2015-01-02 15 views
5

tôi đang làm việc trên một trò chơi, nhưng hiện tại tôi đang chạy điểm chuẩn.Tốc độ vẽ hình ảnh

Nếu có ai có thể giúp tôi về vấn đề này, tôi sẽ đánh giá cao điều đó.

Những gì tôi đang làm, là tôi cháy sự kiện sơn trên một bảng điều khiển khi tôi nhấp vào nút bắt đầu, với mã này:

private void startToolStripMenuItem_Click(object sender, EventArgs e) 
    { 
     try 
     { 
      pnlArea.Invalidate(); 

     } 
     catch (Exception) 
     { 
      throw; 
     } 
    } 

sau đó tôi làm điều này trong trường hợp sơn của tôi:

private void pnlArea_Paint(object sender, PaintEventArgs e) 
    { 
     try 
     { 
      stopwatch = new Stopwatch(); 
      // Begin timing 
      stopwatch.Start(); 

      if (gameStatus == GameStatus.PlaceHead) 
      { 
       e.Graphics.DrawImage(dictHead["HeadRight"], 100, 100, 15, 15); 
      } 

      //e.Graphics.Clear(Color.White); 

      if (gameStatus == GameStatus.GameTest) 
      { 
       int x = 0; 
       int y = 0; 
       for (int i = 0; i < 5000; i++) 
       { 
        x += 15; 
        if (x > 1000) 
        { 
         x = 0; 
         y += 15; 
        } 

        e.Graphics.DrawImage(body.Value, x, y, 15, 15); 

       } 
      } 

      toolTimer.Text = Math.Round((stopwatch.Elapsed.TotalMilliseconds/1000), 2).ToString() + "s"; 

      // Stop timing 
      stopwatch.Stop(); 
     } 
     catch (Exception) 
     { 

      throw; 
     } 
    } 

Đây là phần cơ thể tôi đang vẽ trong đoạn code trên:

enter image description here

Đây là kích thước chính xác -> 15px x 15px

nhưng điều này mất đến 1,2 giây đôi khi !!! có cách nào tôi có thể cải thiện điều này không?

đây là một mẫu của màn hình kết quả cuối cùng: enter image description here

+0

'DoubleBuffered = true;' trong trình tạo biểu mẫu (ngay bên dưới 'InitializeComponent()'). cái đó có giúp ích không? – Sjips

+0

Yeah đã thử nó ... nhưng tôi đã làm nó trong các thuộc tính của biểu mẫu ... đặt Double Buffer thành true. –

+1

WinForms không phải là một môi trường tuyệt vời để chơi game. Điều đó đang được nói, vẽ mỗi hình ảnh 15 x 15 pixel là khá tốn kém. Hãy thử chỉ cần vẽ hình vuông của bạn với một thói quen vẽ thay thế. Nếu hội đồng quản trị không có quá nhiều pháo hoa diễn ra mọi lúc, hãy thử chỉ vẽ vào một bitmap và chỉ vẽ bitmap vào màn hình. Định dạng PixelFormat.Format32bppPArgb là nhanh nhất. Nếu một ô không thay đổi, đừng bận tâm cập nhật nó. – LarsTech

Trả lời

1

Ngoài những thông tin mà mọi người đã cho tôi, tôi đã đi đến sự kết hợp để tăng gấp đôi bộ đệm. Điều này đã khắc phục được sự cố của tôi ->

class DoubleBufferedPanel : Panel { public DoubleBufferedPanel() : base() { DoubleBuffered = true; } } 

Và tôi chỉ sử dụng bảng điều khiển đệm đôi này thay thế.

Điểm chuẩn mới không có nhấp nháy nào cả! : enter image description here

5

Bạn cần phải suy nghĩ về làm thế nào để giảm thiểu số lượng bản vẽ gọi cho bạn thực hiện. Hiện tại bạn vẽ 5000 hộp nhỏ để tạo lưới. Mỗi khi bạn vẽ một hộp, bạn thực hiện một số lệnh và sau đó gọi phương thức đồ họa để hiển thị hình ảnh được chia tỷ lệ. Đây là rất nhiều chi phí cho mỗi ô vuông. Vì vậy, điều đầu tiên bạn có thể xem xét là tìm các cách hiệu quả hơn để vẽ hình ảnh - ví dụ: DrawImageUnscaled có thể hoạt động nhanh hơn DrawImage và đạt được kết quả mong muốn. Nhưng đây là việc tối ưu hóa tối ưu hóa của thuật toán không hiệu quả - những gì bạn cần làm để có được lợi ích hiệu suất thực tế là xem liệu bạn có thể áp dụng thuật toán mới, hiệu quả hơn hay không.

Nếu bạn phải kết xuất bằng bitmap, hãy xem cách mẫu lặp lại - bạn có thể tạo bitmap lớn hơn cung cấp nhóm ô 4x4 hoặc 16x16 và hiển thị không? Hoặc một bitmap đại diện cho toàn bộ một cột hoặc hàng? Sau đó, bạn có thể hiển thị với 50 cuộc gọi thay vì 5000.

Nhưng nếu bạn không cần sử dụng hiển thị bitmap, bạn có thể làm tốt hơn nhiều. Ví dụ: nếu bạn gfx.Clear(backgroundColor) và sau đó vẽ khoảng 140 đường màu đen xuống và ngang, bạn có thể tạo cùng một màn hình chỉ với 141 cuộc gọi. Hoặc nếu bạn vẽ khoảng 70 hình chữ nhật, bạn có thể thực hiện 2 dòng trên mỗi cuộc gọi một cách hiệu quả Giảm số lượng cuộc gọi phương thức bạn phải thực hiện, và cho phép hệ thống đồ họa vẽ nhiều pixel hơn trong một cụm. (trên thực tế, hình chữ nhật có thể hoạt động nhanh hơn đáng kể so với một dòng tổng quát do hệ thống biết rằng các đường thẳng luôn là dọc và ngang).

(Nếu có bit mà không làm theo mô hình này, sau đó bạn vẫn có thể làm cho lưới nền và sau đó rút ra những thay đổi trên đầu trang?)

Tiếp theo, nếu chỉ khu vực nhỏ của sự thay đổi hình ảnh từ một khung hình tiếp theo, sau đó thuật toán của bạn sẽ vẽ 5.000 hộp mặc dù 4999 trong số chúng không thay đổi (hoặc 70 hình chữ nhật khi 1 sẽ đủ). Vì vậy, bạn có thể cải thiện các vấn đề rất nhiều nếu bạn (a) chỉ làm mất hiệu lực phần khung nhìn cần thay đổi và (b) viết thường trình dựng hình của bạn để tìm ra ô lưới nào nằm ngoài giới hạn clip và do đó vô nghĩa để vẽ. Điều này có thể làm giảm các bản cập nhật của bạn để vẽ 1 hình chữ nhật thay vì 5000 mỗi khung hình.(Một cách khác để đạt được điều tương tự sẽ là giữ hình ảnh trong một bitmap offscreen, và chỉ vẽ các thay đổi lên nó. Khi bạn render nó vào màn hình chính, card đồ họa sẽ clip nó cho bạn và đạt được kết quả tương tự - tốc độ vẽ lại nhanh hơn nhiều)

Đó là tất cả về việc đạt được cùng một màn hình bằng cách "lười" và suy nghĩ về sau để làm ít công việc nhất có thể. (Bắt một máy tính để đi nhanh hơn luôn luôn sôi xuống để yêu cầu nó để làm ít hơn)

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