2013-05-15 38 views
14

Tôi đã tạo một trình xem ảnh XNA, nhưng nó luôn vẽ lại cảnh, ngay cả khi nó không thay đổi, và nó làm cho netbook của tôi bị cháy như địa ngục, vì vậy tôi muốn nó tạm dừng vẽ khi không có gì thay đổi.Làm cách nào để tạm dừng vẽ lại trong XNA?

Giảm tốc độ khung hình xuống 1 là một cách để giữ cho nó mát mẻ, nhưng kết quả là sản lượng bị lag.

Làm cách nào để ngăn vẽ lại khi không có đầu vào?


Vấn đề này đã được giải quyết, nhưng một vấn đề khác đã được tìm thấy - trò chơi tiêu thụ rất nhiều CPU khi cửa sổ của nó đang được lấy nét, nhưng khi không, nó chỉ mất khoảng 1% của CPU. Xem câu hỏi này để biết chi tiết về làm thế nào để giải quyết vấn đề này khác:

How to reduce XNA game CPU usage while nothing worth computing is happening?

+0

Đó là một phiếu giảm giá nhanh và một cuộc bỏ phiếu gần gũi. Chăm sóc để giúp cải thiện câu hỏi? – user1306322

+3

Sẽ thật tuyệt nếu mọi người để lại bình luận để giải thích những sự phản đối của họ. Điều này có vẻ như một câu hỏi hoàn toàn hợp pháp với một câu trả lời rõ ràng. –

Trả lời

10

Bạn có thể sử dụng phương pháp Game.SupressDraw cho mục đích này. Từ nhận xét tại liên kết:

Gọi phương thức này trong quá trình Cập nhật để ngăn chặn bất kỳ lệnh gọi nào tới Cập nhật. Phương pháp này có thể được sử dụng trên các thiết bị nhỏ để tiết kiệm pin nếu màn hình không thay đổi do Cập nhật. Ví dụ: nếu màn hình tĩnh không có hoạt ảnh nền, đầu vào của trình phát có thể được kiểm tra trong khi Cập nhật để xác định xem trình phát có đang thực hiện bất kỳ hành động nào không. Nếu không có đầu vào được phát hiện, phương pháp này cho phép các trò chơi để bỏ qua bản vẽ cho đến khi cập nhật tiếp theo.

Ví dụ: mã sau sẽ chỉ gọi hàm Draw một lần. Khi tôi kiểm tra điều này tôi nhận thấy rằng việc sử dụng CPU là cao (70%) mà không cần gọi SuppressDraw. Khi sử dụng SupressDraw, mức sử dụng CPU giảm đáng kể (xuống dưới 15%). Số điện thoại của bạn có thể thay đổi.

public class Game1 : Microsoft.Xna.Framework.Game 
{ 
    ... 
    private bool _drawn = false; 
    protected override void Update(GameTime gameTime) 
    { 
     if (_drawn) 
      SuppressDraw(); 
    } 

    protected override void Draw(GameTime gameTime) 
    { 
     GraphicsDevice.Clear(Color.CornflowerBlue); 
     spriteBatch.Begin(); 
     /* draw stuff here */ 
     spriteBatch.End(); 

     _drawn = true; 
    } 
    ... 
} 

Lưu ý rằng SupressDraw chỉ chặn một cuộc gọi Draw. Để ngăn nhiều cuộc gọi hơn đến Draw, bạn phải liên tục gọi SupressDraw trong Update. Hy vọng rằng có ý nghĩa.

+0

Điều này chắc chắn hoạt động, mặc dù nó không giúp tôi tiết kiệm được nhiều CPU như tôi mong đợi. Phân tích hiệu suất cho biết với mỗi khung vẽ bị chặn, phương thức cập nhật chính sẽ thu hút mọi sự chú ý, nhưng nó vẫn tốn nhiều CPU như trước đây.Tôi đoán câu hỏi được trả lời, nhưng tôi vẫn cần phải biết làm thế nào để giảm chi phí CPU làm hầu như không có gì. – user1306322

+0

@ user1306322 - mà không nhìn thấy mã của bạn, rất khó để cung cấp câu trả lời là tại sao việc sử dụng CPU của bạn không bị giảm. Như bạn có thể thấy với câu trả lời của tôi ở trên, nó ** đã làm giảm thời gian CPU của chương trình mẫu của tôi - từ 70% mức sử dụng xuống khoảng 15%. –

+0

Như bạn đã nói - phần trăm thay đổi. Tôi đoán cuộc gọi Draw không thực sự tiêu tốn bất kỳ lượng tài nguyên đáng kể nào, trong khi toàn bộ ứng dụng đang sử dụng nhiều như nó có thể nhận được (và vẫn vậy). Vì vậy, về cơ bản điều này đã trở thành một vấn đề khác - xác định chính xác những gì tiêu thụ CPU trong khi không có gì đặc biệt thực sự xảy ra ngoài việc chờ đầu vào và vẽ một khung 60 lần mỗi giây. – user1306322

0

Khi câu trả lời được chấp nhận cho biết, bạn có thể sử dụng SuppressDraw để tránh vẽ khung không thay đổi. Phương thức Update của bạn sẽ chạy bất kể, tuy nhiên, đó là lý do tại sao nó vẫn sử dụng nhiều CPU hơn bạn mong đợi. Để tránh sử dụng càng nhiều CPU, bạn cần phải bằng cách nào đó tránh cập nhật những thứ bạn biết đã không thay đổi kể từ khung cuối cùng.

Tôi giả sử bạn sẽ biết điều này giống như bạn biết khi nào để ngăn chặn bốc thăm, vì vậy những gì bạn cần làm là sắp xếp lại Update-phương pháp của bạn như thế này:

private void Update(GameTime gameTime) 
{ 
    var frameHasChanges = DetectChanges(); //This method you need to figure out yourself 
    if (!frameHasChanges) 
    { 
     SuppressDraw(); 
     base.Update(gameTime); 
     return; 
    } 

    //Do the rest of normal Update 

} 

Là một lưu ý cuối cùng; Tôi chưa bao giờ phải sử dụng điều này trong bất kỳ trò chơi nào tôi từng thực hiện. Điều mà tôi cảm thấy cho thấy bạn có thể có một số vấn đề cơ bản khác với hiệu suất. Tuy nhiên, tôi đã sử dụng nhiều kỹ thuật để tránh hiển thị văn bản và cứ như vậy trên mỗi khung hình (gây ra boxing/unboxing). Hỏi về điều này trong bình luận nếu bạn muốn biết thêm.

+0

Trong khi nói chung đây là cách để đi, trong trường hợp cụ thể này, như tôi đã nói trong câu hỏi, phương pháp cập nhật rất đơn giản và nó không thể hog tất cả CPU chỉ để kiểm tra nếu có thay đổi ở trạng thái đầu vào (và nó không, tôi kiểm tra nó bốn lần). Giải pháp được tìm thấy thông qua một câu hỏi khác cho vấn đề xuất hiện sau khi giải quyết vấn đề không vẽ lại trong câu hỏi này. Xem chú thích câu hỏi để biết chi tiết. – user1306322

Các vấn đề liên quan