Image 我是否需要在2d瓷砖世界中移动瓷砖或播放器?

Image 我是否需要在2d瓷砖世界中移动瓷砖或播放器?,image,performance,graphics,invalidation,redraw,Image,Performance,Graphics,Invalidation,Redraw,我目前正在创建一个2d瓷砖游戏,我想知道瓷砖是要移动还是要移动角色 我问这个问题是因为我已经创建了“2d瓷砖贴图”,但是它运行得太慢了,我无法修复它。我现在尝试了所有的方法,结果是我获得了30 fps 它运行太慢的原因是,每1ms使用一个计时器,瓷砖就会被重新绘制。但我不知道如何解决这个问题 如果有人能帮助我,我将非常感激 这是我制作地图的方式: public void makeBoard() { for (int i = 0; i < tileAr

我目前正在创建一个2d瓷砖游戏,我想知道瓷砖是要移动还是要移动角色

我问这个问题是因为我已经创建了“2d瓷砖贴图”,但是它运行得太慢了,我无法修复它。我现在尝试了所有的方法,结果是我获得了30 fps

它运行太慢的原因是,每1ms使用一个计时器,瓷砖就会被重新绘制。但我不知道如何解决这个问题

如果有人能帮助我,我将非常感激

这是我制作地图的方式:

        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
    }

正如评论中提到的,你的概念是错误的。下面是如何完成这项任务的简单总结:

  • 平铺贴图是静态的

    从功能的角度来看,无论玩家移动或地图,但从性能的角度来看,瓷砖的数量远远大于玩家的数量,因此移动玩家的速度更快

    要实现以玩家为中心或跟随视图,还必须移动相机

  • 渲染

    每1ms重新绘制一次是疯狂的,如果场景的复杂度达到中等水平,在当今的计算机上很可能是不可能的。人类视觉无论如何都无法检测到它,因此没有必要重新绘制超过
    25-40
    fps的图像。需要更高fps的唯一原因是与监视器刷新同步,以避免扫描线瑕疵(是的,甚至LCD使用扫描线刷新)。要获得更多的fps,显示器的刷新率是毫无意义的(许多fps玩家会反对,但我们的看法是,不管他们说什么…)

    无论如何,如果渲染时间超过1ms(这很可能),那么计时器就坏了,因为它应该在第一个处理程序停止之前触发几次。由于同步问题,这通常会导致大量的速度减慢,因此生成的fps通常比渲染引擎所能提供的还要小。那么如何补救呢

  • 计时器
    间隔设置为
    20ms
    或更高
  • 添加
    bool\u redraw=false
    并且仅当您需要重新绘制屏幕时才使用它来重新绘制。因此,对于任何动作,如玩家移动、相机移动或转弯,动画更改将其设置为
    true
  • 内部计时器事件处理程序仅在
    \u redraw==true
    时调用重绘,然后将其设置为false
  • 这将大大提高性能。即使重新绘制所需的时间超过了计时器的时间间隔,也会比当前方法快得多

    要避免闪烁,请使用后缓冲

  • 摄像机和剪辑

    您的地图很可能比屏幕大得多,因此没有必要重新绘制所有瓷砖。您可以通过查看相机来选择地图的正确部分。如果您的游戏不使用旋转,那么您只需要
    位置
    ,并且可以
    缩放
    。如果你想要旋转,那么2D 3x3同质矩阵就是最好的选择

    假设只有位置(无缩放或旋转),则可以使用以下变换:

    screen_x=world_x-camera_x
    screen_y=world_y-camera_y
    
    world_x=screen_x+camera_x
    world_y=screen_y+camera_y
    
    因此,
    camera
    是您的相机视图位置,
    world
    是您在地图网格中的平铺位置,
    screen
    是屏幕上的位置。如果您在地图中获得了磁贴的
    索引
    ,则只需将它们乘以以像素为单位的磁贴大小即可获得
    世界
    坐标

    若要仅选择可见分幅,您需要获得屏幕的角位置,将其转换为世界坐标,然后转换为地图中的索引,最后仅渲染这些点在地图中形成的矩形内的分幅+一些误差范围(例如,在所有方向渲染1个分幅放大的矩形)。这样,渲染将独立于贴图大小。此过程称为剪裁

  • 我强烈建议查看这些相关的QAs:

    • 。。。阅读那里的评论

    链接QA中的演示仅使用GDI和win32 form app中位图的直接像素访问,因此您可以将性能与代码进行比较(它们应该类似),并调整代码,直到其表现正常。

    如注释中所述,您的概念是错误的。下面是如何完成这项任务的简单总结:

  • 平铺贴图是静态的

    从功能的角度来看,无论玩家移动或地图,但从性能的角度来看,瓷砖的数量远远大于玩家的数量,因此移动玩家的速度更快

    要实现以玩家为中心或跟随视图,还必须移动相机

  • 渲染

    每1ms重新绘制一次是疯狂的,如果场景的复杂度达到中等水平,在当今的计算机上很可能是不可能的。人类视觉无论如何都无法检测到它,因此没有必要重新绘制超过
    25-40
    fps的图像。需要更高fps的唯一原因是与监视器刷新同步,以避免扫描线瑕疵(是的,甚至LCD使用扫描线刷新)。要获得更多的fps,显示器的刷新率是毫无意义的(许多fps玩家会反对,但我们的看法是,不管他们说什么…)

    无论如何,如果渲染时间超过1ms(这很可能),那么计时器就坏了,因为它应该在第一个处理程序停止之前触发几次。由于同步问题,这通常会导致大量的速度减慢,因此生成的fps通常比渲染引擎所能提供的还要小。那么如何补救呢

  • 计时器
    间隔设置为
    20ms
    或更高
  • 添加
    bool\u redraw=false
    并且仅当您需要重新绘制屏幕时才使用它来重新绘制。因此,对于任何动作,如玩家移动、相机移动或转弯,动画更改都将其设置为
    true