使用JavaScript进行逐像素动画制作

6
我正在一个像素网格上制作精灵动画。我有几个选项,每个选项都有其优缺点。我有相当多的javascript经验(六年),但没有这种类型的经验。问题是我不知道每个选项的成本。
精灵需要快速渲染,并且要足够便宜,以至少同时运行五个并运行碰撞检测。
理想情况下,我想使用包装器内的元素网格,从多维数组向每个元素渲染颜色和alpha通道。 主要好处在于我可以逐像素运行碰撞检测并点击精灵的透明部分。对于任何基于图像的精灵,即使我单击透明像素,onClick事件也会触发(我将不得不做大量工作来通过透明像素传递点击事件,这可能非常昂贵)。
下一个选项是使用css精灵。 css-tricks.com/css-sprites/ 这将非常容易,但如前所述,onClick事件不会通过透明像素传递。我可能可以强制执行,但再次可能很昂贵,并且需要很长时间才能实施。
另一个选择是动画gif,但它们很大,颜色方面受限,并且难以控制动画。我宁愿不要去那里。
然后就有了html5画布元素,我对此并不了解,并且如果可能的话,我想远离它。我甚至不知道我的任何代码如何与画布元素相关,并且我怀疑它在长期内是否会实现我想要的效果。
那么哪个性能最佳?第一个(也是最理想的)是否是可行的选择?还是我错过了什么?
2个回答

3
使用现代浏览器,您可以在桌面电脑上构建由定位像素子元素组成的精灵 (只要它们不太复杂或太大),为了安全起见,我建议您将活动精灵数量限制在大约10个。在移动设备上可能会有点慢和笨重,但考虑到您似乎正在设计需要精确“onclicks”的游戏,我不认为这会是一个问题。
您最灵活的选择是使用HTML5 Canvas,正如您已经发现的那样,但这将涉及相当多的JavaScript编码。但是,该系统将允许您对精灵应用多种效果,并且通过使用getImageData (允许您读取任何像素偏移处的确切像素颜色),将允许您使用像素完美检测。 如果您想避免全屏画布系统的技术问题和挑战(这可能有点棘手),您实际上可以创建许多较小的画布元素并像使用HTML元素一样移动它们,作为您的精灵。然后,您只需要设计绘制动画帧的代码,并使用上述方法告诉鼠标是否已经击中或未击中精灵(以及一个点击处理程序和一些代码来计算用户相对于画布元素位置的点击位置)。显然,最好以通用方式完成此操作,以便您的代码可以应用于所有精灵 :)
要在画布上绘制图像,您可以像在问题中提到的那样使用精灵表,并使用相当灵活的drawImage()方法支持切片模式。这只需要与setInterval或requestAnimationFrame样式的游戏循环相关联即可。


更新 - 想要非常优化的人

如果您想要采取更优化的路线 - 这需要更多的操作 - 您可以执行以下操作。如果您有许多完全相同并且只有几个(20或30)动画帧的精灵,则此方法最有效:

  1. 使用具有背景图像精灵表的普通DIV来为您的精灵供电,并将其背景位置移动。这是您可以实现的最优化,除了将静态图像作为精灵外,因为浏览器会处理所有工作。
  2. 对于每种精灵类型,在一个足够大的隐藏画布元素上绘制您的精灵表。
  3. 当用户单击您的DIV精灵之一时,将背景位置视为坐标,反转它们,然后您应该知道在(通过精灵类型查找)您的画布元素上的像素数据位于何处。
  4. 使用您的隐藏画布上的getPixelData方法来确定用户是否已单击了精灵。
  5. 以上意味着您仅使用一个画布元素 - 每种精灵类型,浏览器为您处理所有图形,并获得与单击完美匹配的像素碰撞。

希望以上内容有意义?


很好的回复。您认为画布方法比像素子元素方法更便宜,因此更快吗?因为最重要的是,我真的需要节省处理能力。 - wjagodfrey
这真的取决于你的精灵的大小/复杂度。如果它们是16x16像素或红色方块带蓝点;)那么我会说不需要...但是任何比那更大或更复杂的,使用单独的精灵画布元素将更加优化。使用全屏画布的主要问题始终是“清除大区域”,因为它相当昂贵。因此,通过使用单独的画布元素,您只需要清除较小的区域,并获得使用CSS定位精灵的灵活性。 - Pebbl
非常感谢,我会照您说的去做。 - wjagodfrey
@WilfredJamesGodfrey 没问题 - 我添加了第三种更优的选择,我实际上还没有使用过这种方法。但是,对于我自己的在线游戏,这是我一直在思考的事情...我看不出为什么它不会更好。 - Pebbl

0
你可以尝试将图像切割成30x30的小块,并仅在小块不透明的部分添加元素,在小块透明的部分留出空白区域,这样点击事件就会穿透到下层。虽然这样做会稍微降低小块可被点击的精度。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接