2013-05-14 4 views
2

Я программирую клон tetris для моего проекта школы C#. Я использую Microsoft Visual Studio 2012. Сама игра реализована как двухмерный массив блоков (список списков блоков), и каждый блок имеет свою собственную текстуру (изображение bmp). Я рисую весь массив на элемент управления PictureBox, и здесь начинается проблема. При обновлении изображения на PictureBox (перемещение/вращение активной фигуры) игра немного отстает. Я попытался использовать панель управления, но результат был таким же. У меня есть общее представление о том, что может вызвать отставание, но я точно не знаю, как избавиться от него.C# Тетрис игра медленная производительность

Это метод Жеребьевка игры «сетки»:

public void Draw(Graphics g) 
{ 
    Brush brush; 
    Font font = new System.Drawing.Font("Arial", 5); 
    for (int i = 0; i < Width; i++) 
    for (int j = 0; j < Height; j++) 
    { 
      brush = new TextureBrush(Blocks[i][j].Texture); 
      if (Blocks[i][j].Occupied==true) 
      g.FillRectangle(brush, i * 20, j * 20, i * 20 + Blocks[i][j].Texture.Width, j * 20 + Blocks[i][j].Texture.Height); 
    } 
} 

Это метод рисования активного Tetromino:

public void Draw(Graphics g) 
{ 
    Brush brush = new TextureBrush(Blocks[0].Texture); 
    foreach (FullBlock b in Blocks) 
     g.FillRectangle(brush, b.x * 20, b.y * 20,b.Texture.Width, b.Texture.Height); 
} 

Сама игра затем использовать оба из них (двойной буферизация попытка):

public void GameDraw(PictureBox p) 
{ 
    Graphics g = Graphics.FromImage(gb); 
    gameGrid.Draw(g); 
    PlayingShape.Draw(g); 
    p.Image = gb; 
    p.Refresh(); 
} 

где "gb" является частным Bitmap v Я могу создать один раз в конструкторе класса (чтобы сократить (неудачно) отставание).

Метод GameDraw вызываются всякий раз, когда состояние игры изменяется (например, перемещение/вращения активного Tetromino и все «сила тяжести» тика)

+3

Вы не делаете нужно использовать иллюстрацию, использовать стандартный GDI + рисунок, и он будет работать * много быстрее. – Tigran

+0

if (Блоки [i] [j] .Occupied == true) <--- Не делайте этого. просто используйте .Occupied, который возвращает логическое значение. –

ответ

0

Нет необходимости в картинной рамки, добавить свой собственный контроль:

using System.Drawing; 
using System.Windows.Forms; 

namespace TetrisGame 
{ 
    public sealed class TetrisControl : Control 
    { 
     private TheBlockType[][] blocks = ...; 

     protected override void OnPaint(PaintEventArgs e) 
     { 
      //draw your stuff here direct to the control, no buffers in the middle 
      //if that causes flickering, turn on double buffering, but don't bother doing it yourself 
      //this is your existing draw method: 
      Draw(e.Graphics); 
     } 
    } 
} 

Тогда на каждом тике или движение, сделать не вызова краски, просто аннулирует контроль:

tetris.Invalidate(); 
+0

Спасибо, я попробую. – Dreamer

+0

После сборки проекта с новым классом он появится в окне инструмента и может быть сброшен в форме, как и другие элементы управления. Удачи! – weston

4

Вам нужна двойная буферизация, что вы не установили. Цитирование MSDN:

Двойная буферизация использует буфер памяти для решения проблем мерцания , связанные с несколькими операциями рисования. При двойном буферизация , все операции краски сначала оказывается в буфере памяти вместо поверхности рисования на экране

Вы можете включить его с помощью Control.DoubleBuffered свойство

+2

Двойная буферизация, инструмент чемпионатов по программированию игр с тех пор, навсегда ... Я помню, как это использовалось на моем Commodore Amiga. –

+1

Изображение не мерцает, хотя я как бы решил, что в методе GameDraw, где сначала я рисую «невидимый» битмап, который затем копирую на pictureBox.Image. Изображение просто обновляется с задержкой. – Dreamer

0

Кроме того, думаю, из коробки ... Вместо того, чтобы выполнять полную проверку сетки, вы можете сделать каждую из ваших фигур частью связанного списка и перерисовать их на основе их положения в сетке ... Пока ваша сетка не заполнится полностью, вы будете делать меньше сканирования ,

Или рассмотрите только перерисовку того, что вам нужно перерисовать, то есть блок падает вверху, нет необходимости полностью перерисовывать полную сетку.

Оптимизация - это то, что отделяет нас от животных. Помимо утконоса, который является оптимальным существом.

+0

Программа OP должна иметь возможность перерисовывать полный экран снова и снова без каких-либо проблем, это то, что большинство игр делают в конце концов. Если они проводят возрасты, оптимизируя ад, чтобы были сделаны только изменения, да, они увидят пользу, но это будет просто скрывать истинную проблему, и для записи и отладки потребуется намного больше времени. – weston

Смежные вопросы