Performance Graphics.DrawImage 2dtilemap性能问题

Performance Graphics.DrawImage 2dtilemap性能问题,performance,graphics,drawimage,redraw,Performance,Graphics,Drawimage,Redraw,我目前正在忙着为我的游戏创建一个2d tilemap。为了做到这一点,我做了一个二维阵列填充瓷砖。这些平铺是具有存储在其中的图像的类 每次我在地图上移动精灵时,地图必须每1ms重新绘制一次(我有理由这样做)。但是它太慢了。。。它现在以每秒30帧的速度运行,我真的不知道该怎么办。我尝试了很多东西,但结果都是一样的 在这一点上我真的需要帮助,因为我无法让它工作:/ 这是我制作地图的方式: public void makeBoard() { for (int i = 0; i

我目前正在忙着为我的游戏创建一个2d tilemap。为了做到这一点,我做了一个二维阵列填充瓷砖。这些平铺是具有存储在其中的图像的类

每次我在地图上移动精灵时,地图必须每1ms重新绘制一次(我有理由这样做)。但是它太慢了。。。它现在以每秒30帧的速度运行,我真的不知道该怎么办。我尝试了很多东西,但结果都是一样的

在这一点上我真的需要帮助,因为我无法让它工作:/

这是我制作地图的方式:

        public void makeBoard()
{
    for (int i = 0; i < tileArray.GetLength(0); i++)
    {
        for (int j = 0; j < tileArray.GetLength(1); j++)
        {
            tileArray[i, j] = new Tile() { xPos = j * 50, yPos = i * 50 };
        }
    }
}
      private void Wereld_Paint_1(object sender, PaintEventArgs e)
{
    //label1.Text = k++.ToString();
    using (Graphics grap = Graphics.FromImage(bmp))
    {
        for (int i = 0; i < tileArray.GetLength(0); i++)
        {
            for (int j = 0; j < tileArray.GetLength(1); j++)
            {
                grap.DrawImage(tileArray[i, j].tileImage, j * 50, i * 50, 50, 50);
            }
        }
        grap.DrawImage(player.movingObjectImage, player.xPos, player.yPos, 50, 50);
        grap.DrawImage(enemyGoblin.movingObjectImage, enemyGoblin.xPos, enemyGoblin.yPos, 50, 50);

        groundPictureBox.Image = bmp;
       // grap.Dispose();

    }
}
        private void UpdateTimer_Tick(object sender, EventArgs e)
{
    if(player.Update()==true) // true keydown event is fired
    {
        this.Invalidate();
    }
    label1.Text = lastFrameRate.ToString(); // for fps rate show
    CalculateFrameRate(); // for fps rate show
}
关于我的评论:

private void Wereld_Paint_1(object sender, PaintEventArgs e)
{
    if(backgroundRedrawRequired)
    {
        Bitmap newBackground = new Bitmap(this.backGroundBitmap.Width, this.backGroundBitmap.Height, PixelFormat.Format32bppARGB);
        using (Graphics grap2 = Graphics.FromImage(newBackground))
        {
            // Draw the old background to the new image moved by the offset in X/Y 
            // MoveByNumberOfTilesX/Y can be negative depending on the direction you move the background.
            grap2.DrawImage(this.BackgroundImage, this.moveByNumberOfTilesX * 50, this.moveByNumberOfTilesY, this.BackgroundImage.Width, this.BackgroundImage.Height);

            // ToDo: Set the start i/j or the upper Bound of both for loops, so that only the tiles of the "white" area in the new background drawing get drawn.
            for (int i = 0; i < tileArray.GetLength(0); i++)
            {
                for (int j = 0; j < tileArray.GetLength(1); j++)
                {
                    grap2.DrawImage(tileArray[i, j].tileImage, j * 50, i * 50, 50, 50);
                }
            }
        }
        this.BackgroundImage = newBackground;
    }

    using (Graphics grap = Graphics.FromImage(bmp))
    {
        // Reuse the background as long as it doesn't change!
        grap.DrawImage(this.backGroundBitmap,0,0, groundPictureBox.Width, groundPictureBox.Height);
        grap.DrawImage(player.movingObjectImage, player.xPos, player.yPos, 50, 50);
        grap.DrawImage(enemyGoblin.movingObjectImage, enemyGoblin.xPos, enemyGoblin.yPos, 50, 50);
    }

    groundPictureBox.Image =bmp;
}
private void Wereld_Paint_1(对象发送方,PaintEventArgs e)
{
如果需要(背景重新绘制)
{
Bitmap newBackground=新位图(this.backGroundBitmap.Width、this.backGroundBitmap.Height、PixelFormat.Format32bppARGB);
使用(Graphics grap2=Graphics.FromImage(新背景))
{
//将旧背景绘制到按X/Y偏移移动的新图像
//MoveByNumberOfTileX/Y可以是负数,具体取决于移动背景的方向。
图2.DrawImage(this.BackgroundImage,this.movebynumberoftilex*50,this.movebynumberoftilexy,this.BackgroundImage.Width,this.BackgroundImage.Height);
//ToDo:设置循环的起始i/j或两者的上限,以便仅绘制新背景图形中“白色”区域的平铺。
for(int i=0;i
关于我的评论:

private void Wereld_Paint_1(object sender, PaintEventArgs e)
{
    if(backgroundRedrawRequired)
    {
        Bitmap newBackground = new Bitmap(this.backGroundBitmap.Width, this.backGroundBitmap.Height, PixelFormat.Format32bppARGB);
        using (Graphics grap2 = Graphics.FromImage(newBackground))
        {
            // Draw the old background to the new image moved by the offset in X/Y 
            // MoveByNumberOfTilesX/Y can be negative depending on the direction you move the background.
            grap2.DrawImage(this.BackgroundImage, this.moveByNumberOfTilesX * 50, this.moveByNumberOfTilesY, this.BackgroundImage.Width, this.BackgroundImage.Height);

            // ToDo: Set the start i/j or the upper Bound of both for loops, so that only the tiles of the "white" area in the new background drawing get drawn.
            for (int i = 0; i < tileArray.GetLength(0); i++)
            {
                for (int j = 0; j < tileArray.GetLength(1); j++)
                {
                    grap2.DrawImage(tileArray[i, j].tileImage, j * 50, i * 50, 50, 50);
                }
            }
        }
        this.BackgroundImage = newBackground;
    }

    using (Graphics grap = Graphics.FromImage(bmp))
    {
        // Reuse the background as long as it doesn't change!
        grap.DrawImage(this.backGroundBitmap,0,0, groundPictureBox.Width, groundPictureBox.Height);
        grap.DrawImage(player.movingObjectImage, player.xPos, player.yPos, 50, 50);
        grap.DrawImage(enemyGoblin.movingObjectImage, enemyGoblin.xPos, enemyGoblin.yPos, 50, 50);
    }

    groundPictureBox.Image =bmp;
}
private void Wereld_Paint_1(对象发送方,PaintEventArgs e)
{
如果需要(背景重新绘制)
{
Bitmap newBackground=新位图(this.backGroundBitmap.Width、this.backGroundBitmap.Height、PixelFormat.Format32bppARGB);
使用(Graphics grap2=Graphics.FromImage(新背景))
{
//将旧背景绘制到按X/Y偏移移动的新图像
//MoveByNumberOfTileX/Y可以是负数,具体取决于移动背景的方向。
图2.DrawImage(this.BackgroundImage,this.movebynumberoftilex*50,this.movebynumberoftilexy,this.BackgroundImage.Width,this.BackgroundImage.Height);
//ToDo:设置循环的起始i/j或两者的上限,以便仅绘制新背景图形中“白色”区域的平铺。
for(int i=0;i
您可以尝试一些优化:1。检查您的图像像素格式。它的格式应为32bppargb,以避免在绘图时进行图片转换。2.调整图形上下文设置。查找关键字sourceOver、SourceCopy、最近邻、抗锯齿3。使用“绘制未缩放图像”。这比drawimage快。但我担心使用gdi无法实现1ms刷新。@Thomas Voß好的,谢谢。但我已经尝试过所有这些了,没有标度对我来说更糟。所以我想我对windows窗体的这个问题无能为力?你可以尝试的是:将一帧中的所有分片绘制成位图,最后显示该位图。在下一帧,将旧位图绘制为新位图,但按移动偏移量移动。然后,您只需绘制剩余的平铺并再次显示图像。这样,您可以节省大量的抽签调用。对于您拥有的任何图形,只需在背景上绘制它们即可。但是,只有当你有很多瓷砖,并且每一帧都重复使用其中的一些瓷砖时,这才有帮助。最后,我认为你不会看到1000 fps。对我来说,甚至100个听起来都很不错。你可以尝试所有这些设置:以防万一你错过了一些。你可以尝试一些优化:1。检查您的图像像素格式。它的格式应为32bppargb,以避免在绘图时进行图片转换。2.调整图形上下文设置。查找关键字sourceOver、SourceCopy、最近邻、抗锯齿3。使用“绘制未缩放图像”。这比drawimage快。但我担心使用gdi无法实现1ms刷新。@Thomas Voß好的,谢谢。但我已经尝试过所有这些了,没有标度对我来说更糟。所以我想我对windows窗体的这个问题无能为力?你可以尝试的是:将一帧中的所有分片绘制成位图,最后显示该位图。在下一帧,将旧位图绘制为新位图,但按移动偏移量移动。然后,您只需绘制剩余的平铺并再次显示图像。这样,您可以节省大量的抽签调用。对于您拥有的任何图形,只需在背景上绘制它们即可。