2011-09-07 23 views
6

Tôi hiện đang tạo trò chơi phòng thủ tháp bằng C# & XNA. Các trò chơi chạy tốt và trơn tru trong một thời gian nhưng sau khi chơi cho một số lượng tốt thời gian (sau khi đủ kẻ thù/tháp/viên đạn đã sinh ra) các trò chơi có vẻ chậm theo cấp số nhân. Ngay cả khi tất cả các trường hợp được xóa, độ trễ vẫn tồn tại. Lúc đầu, tôi nghĩ rằng điều này có thể liên quan đến việc thu gom rác (và có lẽ nó) nhưng để kiểm tra nó, tôi đã viết destructors để in khi một đối tượng được thu thập và mọi thứ đều ổn (tất cả các đối tượng được thu thập). Vì vậy, tôi tò mò nếu có ai có bất kỳ kinh nghiệm với lag trong XNA và nguyên nhân có thể của nó?Xác định XNA Game Lag

CHỈNH SỬA: Đây là dành cho PC

+0

Gợi ý: Câu hỏi (tổng thể) tốt hơn có thể là -> Tôi có thể làm gì để xác định nơi xảy ra sự cố? Có vẻ như điều này có thể do nhiều thứ khác nhau gây ra, chúng tôi sẽ phải xem rất nhiều mã của bạn để xác định gốc của vấn đề lag – jadarnel27

+0

Có quá nhiều mã để chỉ xem qua. Tôi đang yêu cầu nhiều hơn cho các giải pháp lý thuyết hoặc nguyên nhân có thể làm chậm trễ. Hiện tại không có liên quan đến mạng nên không phải là vấn đề. – Johannes

+1

Một điều tôi sẽ đề nghị là in (để một tập tin đăng nhập gỡ lỗi hoặc một cái gì đó) một dấu thời gian khi bạn nhập và thoát khỏi chương trình con lớn hơn của bạn/khu vực nghi ngờ. Bằng cách này bạn có thể thấy nơi bạn đang mất thời gian đó, và làm việc hướng tới vấn đề – jadarnel27

Trả lời

0

Thời gian vòng trò chơi có tăng không? Thêm đồng hồ bấm giờ vào đầu và đến cuối vòng lặp Update và vòng lặp Draw. Nếu nó đang tăng lên, hãy cố gắng loại trừ (di chuyển stopwatch.Start() và/hoặc stopwatch.Stop()) cho đến khi bạn tìm thấy nguyên nhân làm chậm tốc độ. Nếu nó không tăng, nó gây ra bởi cái gì khác.

Cố gắng thêm dòng này vào mã:

SpriteBatch.DrawInt64(Font, GC.GetTotalMemory(false)/1000 /* in kilobytes */, 
POSITION, Color.White, 0f); 

(DrawInt64/32 là phần mở rộng thực sự hữu ích để spritebatch mà cho phép bạn vẽ số mà không tạo rác, có sẵn ở đây:. http://pastebin.com/pVw66mGy Ngoài ra chỉ cần sử dụng Drawstring và .ToString()).

Mỗi khi số hiển thị giảm, thu thập rác sẽ được chạy.

+0

Một cách tốt hơn để xác định xem các bộ sưu tập rác có xảy ra hay không là sử dụng GC.CollectionCount(). Điều này sẽ cho phép bạn xem khi nào từng thế hệ được thu thập. Bộ sưu tập thế hệ 0 có lẽ không phải là một vấn đề lớn; bộ sưu tập thế hệ 1 và 2 có nhiều mối quan tâm hơn khi nói đến hiệu suất. –

1

Nếu bạn lo lắng rằng các bộ sưu tập rác đang ảnh hưởng đến hiệu suất, một trong những công cụ tốt nhất bạn có thể học cách sử dụng là CLR Profiler. Tiện ích này cho phép bạn cấu hình phân bổ heap được thực hiện bởi chương trình của bạn, để bạn có thể xác định chính xác phương thức nào đang tạo ra rác. Hãy nhớ rằng rất nhiều thứ không rõ ràng có thể phân bổ trên heap: chuỗi nối, lập chỉ mục từ điển với các phím liệt kê, đóng cửa, đại biểu, v.v. Ngay cả một ít rác, được tạo một lần trên mỗi khung ở 60 khung hình/giây, có thể nhanh chóng thêm trong hoàn cảnh thích hợp.

Điều đó nói rằng, những gì bạn mô tả không giống như vấn đề với việc thu gom rác thải đối với tôi. GC nói chung là đủ nhanh, ngay cả trong một bộ sưu tập hoàn chỉnh, để chỉ gây ra một vài khung hình được giảm - nói cách khác, bạn sẽ nhận thấy một nhỏ, gây phiền nhiễu jerk thường xuyên như vậy, nhưng không phải là một sự suy giảm liên tục.

(Nên biết trước: này chỉ áp dụng trên máy tính, trong đó có một GC rất phức tạp so với các nền tảng XNA khác.)

Bạn nên cố gắng gắn một hồ sơ để mã của bạn để xác định phương pháp đang dùng lâu nhất để hoàn thành ; nếu vấn đề của bạn không liên quan đến GC, điều này có thể mang tính thông tin. Trước đây, tôi đã sử dụng EQATEC, mặc dù tôi đã gặp sự cố với một số phiên bản mới hơn của họ. Bạn có thể thử điều đó hoặc bạn có thể xem xét trên Google để thay thế.

0

Bạn không quên hủy các sự kiện là bạn? trong ví dụ dưới đây tôi thêm 4 sprites vào một danh sách, mỗi sprite móc một sự kiện từ game. Tôi sau đó loại bỏ một sprite và nâng cao sự kiện.

Trong trường hợp này tất cả 4 sprites vẫn hoạt động và nhận được sự kiện của họ được nêu ra vì vẫn còn một tham chiếu đến chúng trong trò chơi.

chỉ là một ý nghĩ, nếu bạn đang sử dụng sự kiện cho các đối tượng trò chơi của mình, bạn có thể để tất cả chúng vẫn chạy.

class Game 
{ 
    public event EventHandler SomeEvent; 
    List<Sprite> sprites; 

    public Game() 
    { 
    sprites = new List<Sprite>(); 
    sprites.Add(new Sprite(this)); 
    sprites.Add(new Sprite(this)); 
    sprites.Add(new Sprite(this)); 
    sprites.Add(new Sprite(this)); 

    sprites.RemoveAt(0); 

    EventHandler temp = SomeEvent; 
    if (temp != null) 
    { 
     temp(this, EventArgs.Empty); 
    } 
    } 

    static void Main(string[] args) 
    { 
     Game newProgram = new Game(); 
    } 



    class Sprite 
    { 
     public Sprite(Game gameReference) 
     { 
      gameReference.SomeEvent += new EventHandler(gameReference_SomeEvent); 
     } 

     void gameReference_SomeEvent(object sender, EventArgs e) 
     { 
      Debug.WriteLine("Event"); 
     }  
    }