JavaScript画布游戏开发

时间:2015-07-12 12:46:55

标签: javascript android html5 canvas

对于我正在研究的游戏,我一直有一个令人困惑的缓慢问题可能是因为我不确定如何在不使用第三方框架(如Phaser / ImapactJS /)的情况下处理javascript中的图形(最有可能导致速度减慢) EaselJS等)*。 以下是关于我如何接近我的图形的低调。我非常感谢有关如何做到这一点的一些提示或方法。

  • 我的游戏是基于磁贴的 - 使用500x500 px 设计的磁贴,因为我希望它们能够在高清设备上正常显示。
  • 我正在使用spritesheet在主循环运行之前加载我的所有(大部分)磁贴。 此图像大约为4000 x 4000(因为GPU无法处理大于此的纹理大小,因此将其保持在4096以下)。
  • 然后我使用drawImage函数循环并使用存储在tile数组中的信息(w,h,x,y)在画布的一部分上绘制每个tile。我使用drawMap函数在主循环的每个循环中执行此操作。
  • 地图目前是6x6尺寸的瓷砖
  • 在绘制地图后,还会加载角色spritesheet并将其绘制到画布上。角色在主循环的每个循环中显示动画的不同帧。每个包含在同一个spritesheet中的字符都有一组动画。
    • 角色精灵表大约是4000x3500
  • 角色大约为350x250像素
  • 其他对象也使用相同的精灵表。目前只有一个对象。

    可能有用的问题:

  • 我使用过多的精灵表还是太少?

  • 如果它的坐标位于屏幕的边界,我应该只画一些东西吗?
  • 我应该如何进行垃圾收集?在不再使用时,是否需要将图像对象设置为null?

提前感谢您提供意见。我想知道我是否采用正确的方法,并选择你的大脑来加快速度。

*请注意,我计划将JS游戏移植到cocoonJS,它为移动设备上的canvas元素提供图形加速。

**如果有兴趣,请访问我的Patreon page以获得乐趣!

1 个答案:

答案 0 :(得分:1)

你在这里问了很多问题,我将解决我遇到过的问题。 我想非常清楚地说,

使用分析器

了解任何人建议你做的每一件事是否都在改进。除非我们处理您的代码,否则我们只能为您提供有关如何优化代码的理论。

我应该如何进行垃圾收集?在不再使用时,是否需要将图像对象设置为null?

如果您不再使用对象,将其引用设置为null可能意味着它会被垃圾回收。有空值并不一定好,但这不在这个问题的范围内。

对于高性能应用程序,您希望避免过多的分配,从而避免过多的垃圾回收活动。查看您的分析器所说的内容 - chrome Profiler可以告诉您垃圾收集器占用了多少CPU时间。你现在可能还不错。

然后我使用drawImage函数循环并使用存储在tile数组中的信息(w,h,x,y)在画布的一部分上绘制每个tile。我使用drawMap函数在主循环的每个循环中执行此操作。

这非常慢 - 而是考虑将屏幕图块上的当前图形绘制到背景画布,然后仅绘制先前被遮挡的区域。

例如,如果你的玩家走到左边,屏幕左侧会有很多瓷砖进入视野;你需要在屏幕上绘制背景缓冲区,偏移以考虑移动,然后绘制缺失的瓷砖。

我的游戏是基于磁贴的 - 使用500x500像素设计的磁贴,因为我希望它们能够在高清设备上正常显示

如果我解释正确,你的瓷砖直径为500x500px,你在屏幕上绘制了少量这些瓷砖。然后对于没有这么高分辨率的设备,画布渲染器将缩小它们。你真的想在每台设备上以1:1的比例绘制像素。

相反,您是否能够在屏幕上显示更多的较小的图块 - 从而避免在边缘处额外绘制?边缘周围的瓷砖有时可能只会绘制一条边的几个像素,而且图像的其余部分仍然会被裁剪掉,所以为什么不进一步分解呢?

如果它的坐标在屏幕的边界内,我应该只画一些东西吗?

是的,这是一个非常普遍且很好的优化。你会发现它会产生很大的不同。

我使用太多的spritesheets还是太少?

我发现当我有少量的精灵表时,性能最大的是当我经常在它们之间切换时。如果在一个绘制阶段,你从character_sheet.png中绘制所有角色,然后从plant_sheet.png中绘制所有植物,你就可以了。在它们之间切换可能会造成很多麻烦,而且你会看到减速。如果您的探查器告诉您drawImage正占据您框架的很大一部分,您就会知道这种情况正在发生。