首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#俄罗斯方块游戏运行缓慢

C#俄罗斯方块游戏运行缓慢
EN

Stack Overflow用户
提问于 2013-05-14 19:22:50
回答 3查看 1.2K关注 0票数 2

我正在为我的C#学校项目编写俄罗斯方块的克隆程序。我正在使用Microsoft Visual Studio 2012。游戏本身被实现为一个二维块数组(块列表列表),每个块都有自己的纹理(bmp图像)。我将整个数组绘制到一个PictureBox控件上,问题就是从这里开始的。当更新PictureBox上的图像(移动/旋转活动形状)时,游戏会稍微滞后。我试着在Panel控件上绘图,但结果是一样的。我大概知道是什么原因造成了延迟,但我不知道如何消除它。

这是“grid”游戏的绘图方法:

代码语言:javascript
复制
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的draw方法:

代码语言:javascript
复制
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);
}

然后游戏本身同时使用这两个参数(双缓冲尝试):

代码语言:javascript
复制
public void GameDraw(PictureBox p)
{
    Graphics g = Graphics.FromImage(gb);
    gameGrid.Draw(g);
    PlayingShape.Draw(g);
    p.Image = gb;
    p.Refresh();
}

其中"gb"是一个私有Bitmap变量,我在类构造函数中只创建了一次(以减少(不成功地)延迟)。

每当游戏状态改变时(例如,移动/旋转活动的tetromino和每个“重力”刻度),GameDraw方法就会被调用。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-05-14 20:47:20

不需要图片框,添加您自己的控件:

代码语言:javascript
复制
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);
        }
    }
}

然后在每次刻度或移动时,不要调用画图,只需使控件无效:

代码语言:javascript
复制
tetris.Invalidate();
票数 0
EN

Stack Overflow用户

发布于 2013-05-14 19:32:03

您需要双缓冲,但您没有设置。引用MSDN

双缓冲使用内存缓冲区来解决与多个绘制操作相关的闪烁问题。启用双缓冲时,所有绘制操作将首先呈现到内存缓冲区,而不是屏幕上的绘图图面

您可以使用Control.DoubleBuffered属性来启用它

票数 4
EN

Stack Overflow用户

发布于 2013-05-14 19:41:30

另外,跳出框框去思考……你可以让每个形状成为链表的一部分,然后根据它们在网格中的位置重新绘制它们,而不是进行完整的网格扫描。直到你的网格完全填满,你才会做更少的扫描。

或者,考虑只重画你需要重画的部分,例如,一个块落在顶部附近,不需要完全重画整个网格。

优化是我们与动物的不同之处。除了鸭嘴兽,它是最理想的生物。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16541905

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档