优化我的国际象棋比赛c#

时间:2012-07-05 14:31:56

标签: c# optimization lag chess

我第一次在这里问一个问题,如果我做错了,请纠正我。

我国际象棋的图片: http://img842.imageshack.us/img842/2695/65744343.png

每次移动一块它都会滞后约1秒钟。每件和瓷砖都有一个图像,正好有96个图像。每当我移动一块时,它都会用黑色清除所有内容,然后更新图形。

在国际象棋的早期阶段,我没有任何图像,而是使用了不同的颜色,只有几件没有明显的滞后,这件作品瞬间移动。

        public void updateGraphics(PaintEventArgs e, Graphics g, Bitmap frame)
    {
        g = Graphics.FromImage(frame);
        g.Clear(Color.Black);


        colorMap(g);

        g.Dispose();
        e.Graphics.DrawImageUnscaled(frame, 0, 0);
    }

函数colorMap(g)如下所示:

        private void colorMap(Graphics g)
    {
        for (int y = 0; y < SomeInts.amount; y++)
        {
            for (int x = 0; x < SomeInts.amount; x++)
            {
                //Tiles
                Bundle.tile[x, y].colorBody(g, x, y);

                //Pieces
                player1.colorAll(g);
                player2.colorAll(g);
            }
        }
    }

colorAll函数执行每个colorBody(g)函数,如下所示:

        public void colorBody(Graphics g)
    {
        //base.colorBody() does the following: body = new Rectangle(x * SomeInts.size + SomeInts.size / 4, y * SomeInts.size + SomeInts.size / 4, size, size);
        base.colorBody();

        if (team == 1)
        {
            //If its a white queen
            image = Image.FromFile("textures/piece/white/queen.png");
        }
        if (team == 2)
        {
            //If its a black queen
            image = Image.FromFile("textures/piece/black/queen.png");
        }
        g.DrawImage(image, body);
    }

最终移动片段的功能:

        public void movePiece(MouseEventArgs e)
    {
        for (int y = 0; y < SomeInts.amount; y++)
        {
            for (int x = 0; x < SomeInts.amount; x++)
            {
                if (Bundle.tile[x, y].body.Contains(e.Location))
                {
                    //Ignore this
                    for (int i = 0; i < queens.Count; i++)
                    {
                        Queen temp = queens.ElementAt<Queen>(i);
                        temp.move(x, y);
                    }
                    //Relevant
                    player1.move(x, y);
                    player2.move(x, y);
                }
            }
        }
    }

感谢您阅读所有这些!如果我的编码示例不够,我可以建立整个程序的链接。

4 个答案:

答案 0 :(得分:7)

您在每次刷新时都会为每个图像调用Image.FromFile - 每次从磁盘上有效地重新加载每个图像文件。

您是否考虑过加载一次的图片,并将生成的Image存储在有用的地方? (比方说,一个数组,Image[2,6]就足够了)

答案 1 :(得分:3)

为什么每次都重新绘制电路板?你不能把电路板留在原处,并在上面显示透明背景的图像吗?这样你就可以将一个图像作为背景(板),再加上64个较小的图像放在网格板上,只需更改每次移动时显示的图像。

这样,你可以让窗户处理绘图...

此外,在应用程序开始时加载碎片的图像。

答案 2 :(得分:1)

除了不在Image.FromFile() 内调用updateGraphics()(这绝对是您最大的问题)之外,您不应该在每次通话时都尝试重新绘制整个电路板到updateGraphics() - 大部分时间,只有一小部分董事会无效。

PaintEventArgs包含一个参数ClipRectangle,它指定了电路板的哪个部分需要重绘。看看你是否无法弄清楚哪些瓷砖与那个矩形相交,只能重绘这些瓷砖:)

提示:编写一个函数Point ScreenToTileCoords(Point),它取一个屏幕坐标并返回哪个电路板块位于该坐标。然后,您需要重绘的唯一图块是

Point upperLeftTileToBeDrawn = ScreenToTileCoords(e.ClipRectangle.Left, e.ClipRectangle.Top);
Point lowerRightTileToBeDrawn = ScreenToTileCoords(e.ClipRectangle.Right - 1, e.ClipRectangle.Bottom- 1);

另外,请确保您的控件是双缓冲的,以避免撕裂。这比上述评论中的@Steve B链接要简单得多;假设这是UserControl,只需设置

即可
this.DoubleBuffered = true;

答案 3 :(得分:0)

那么,这个:

不要清除整个电路板,只清除需要清除的部分。

替代:

更新到WPF - 它将绘图移动到图形卡 - 只需以智能方式移动棋子(即每个棋子都有一个控件/对象)。