我正在开发一个自上而下的2D瓷砖帆布游戏。我有一个雪碧单张,上面有我所有的瓷砖,然后是一个JSON瓷砖地图数组,显示它们放在哪里。
以前,我会将所有的瓷砖层渲染成一个画布元素一次,然后重新渲染每一帧。这将给我300+ FPS,因为它只是一个单独的抽签调用,每个帧重新绘制这个画布。
然而,问题是,这是地图不只是一个“平面”图像。有时候瓷砖需要被销毁,或者有时候玩家需要站在某些瓷砖的后面(比如当玩家在上面),如果地图只是一个静态的图像,这似乎是不可能的。
因此,我相信我需要重新渲染所有的瓷砖每一帧。然而,即使我只重呈现用户可以看到的瓷砖,FPS也会大幅下降。只有两个瓷砖层和100x100地图,FPS下降到20。
我会假设,尽管每帧有100 * 100 *2个canvas.context.drawImage
调用,但它仍然很好,因为它正在利用GPU,而且我使用的是单个sprite表,因此不应该进行纹理交换。显然不是这样的。
我正在寻找一种可能加快速度的方法,但这些建议似乎是极其沉重和固执己见的库,如three.js和pixi.js。这些库会很棒,只是它们做的太多了。在PIXI和Three.js中,您需要将对象添加到场景中,并且它们会自动重新绘制每一帧。这不是我所需要的,因为我目前的ECS架构需要一个即时模式渲染器,而且我已经有了自己的场景图,所以我不能(也不想)使用他们的。
这里有解决办法吗?我唯一真正需要做的就是快速地从一个spritesheet中提取图像。这能用即时模式渲染完成吗?还是注定要有20个FPS?
发布于 2021-02-24 05:27:56
即使地图是“小”的100x100有两层,这仍然是20,000绘制每帧调用。
一种优化是只绘制可见的瓷砖,例如限制相机的可视区域和缩放级别,这样您就不能一次看到超过几百块瓷砖。但是,您必须实现这样的功能,即可以查询是否可以在摄像机中看到一个瓷砖。
第二个优化(在上述实现之后)是将可见的瓷砖分组为一个大的抽签调用。
发布于 2021-02-24 12:08:16
你认为如何呈现游戏世界的2-3个状态?比如,一个是“玩家下面的东西”,另一个是“玩家上面的东西”,更适合你的需要。然后简单地按照各自的顺序stuff below player -> player -> stuff above player
呈现这些
然后,与其每次修改游戏世界时重新收集图像数据,也许还有另一种解决方案,您可以使用数学手动编辑图像的imageData
对象,从而几乎立即找到需要更新的确切像素?这个部分有点模糊,但也许你能让它发挥作用?(结果是每次对渲染器进行2-3次调用,每次执行改变世界的操作时,都会对图像数据进行一次一次的大范围编辑)
https://gamedev.stackexchange.com/questions/189394
复制相似问题