1

我正在尝试用纯 HTML5 和 JavaScript 制作一个小平台游戏。没有框架。

所以为了让我的角色跳到敌人和地板/墙壁等上面,它需要一些适当的碰撞检测算法。

因为我通常不喜欢这样做。我真的不知道如何解决这个问题。

我是否应该在每一帧(以 30 FPS 运行)重新检查 Canvas 中的所有障碍物,看看它是否与我的播放器发生碰撞,还是有更好更快的方法来做到这一点?

我什至想过制作动态地图。因此障碍物的宽度、高度、x 和 y 坐标存储在一个对象中。这样可以更快地检查它是否与玩家发生碰撞吗?

4

2 回答 2

6

1. 我应该重新检查每一帧(它以 30 FPS 运行)吗?

谁说它以 30 FPS 运行?我在HTML5 规范中没有发现这样的东西。最接近您的关于帧率的说法就是以编程方式调用setInterval或新的、更受欢迎的requestAnimationFrame函数。

然而,回到故事。您应该始终尽可能多地寻找碰撞。通常,在其他平台上编写游戏,其中一个人有更大的测量 CPU 负载的能力,如果 CPU 很难效仿,这可能是你可能会发现有利于缩减一些的事情之一。但是,在 JavaScript 中,尝试实现像这样的高级解决方案是不走运的。

我认为这里没有捷径。如果您不自己进行计算,计算机就无法知道发生了什么碰撞、如何碰撞、何时以及在何处发生碰撞。是的,这通常是在绘制每个新框架之前完成的,即使不是一直如此。

2.动态地图?

如果“映射”是指将坐标映射到对象的类数组对象或多维数组,那么简短的回答必须是no。但请务必拥有场景中所有对象的数组。对象的宽度、高度和坐标应存储在对象中的变量中。泄露这些东西很快就会成为负担;使代码复杂并引入错误(请参阅关注点分离内聚)。

请注意,我刚刚说的是“场景中所有对象的数组” =) 这句话中有一个微妙但最重要的一点:

每当您穿过物体以确定它们的位置以及它们是否与某人发生碰撞时。还要查看您的视口边界并确定对象是否仍然“在场景中”。例如,如果您有某种航天器模拟器,而一颗星星刚刚从屏幕的一侧穿过玩家的视口,然后又穿过屏幕,而这颗星星无法返回并再次可见,那么没有理由再将恒星留在系统中。他应该被删除和删除。他绝对不应该被存储在一个数组中,成为未来与玩家头像碰撞检测的一部分!这样的事情可能会大大减慢您的游戏速度。

奖励:碰撞快速提示

  1. 将屏幕分成几部分。如果其中一个在屏幕左侧,另一个在右侧,则您没有理由寻找两个对象之间的碰撞。您也可以将屏幕拆分为更多的逻辑单元,而不仅仅是左右。

  2. 始终努力首先进行廉价的计算。我们在上一个技巧中已经这样做了。但是,即使您现在知道两个对象可能会相互碰撞,也请在对象周围画两个逻辑方块。例如,假设您有两架 2D 飞机,那么您没有理由首先查看它们机翼的某些部分是否发生碰撞。在每架飞机周围画一个正方形,有效地捕捉它们的最大宽度和最大高度。如果这两个正方形不重叠,那么就像上一个提示一样,您知道它们不会相互碰撞。但是,如果您的第一阶段廉价计算暗示它们可能会发生碰撞,请将这两架飞机传递给另一个更昂贵的计算,以便真正深入研究这个问题。

于 2013-08-04T08:23:36.033 回答
-2

我还在做一些我想做很多 div 并让它们作用于物理的东西。我将分享一些起初对我来说并不明显的东西。

  1. 首先检测数据中的冲突。我正在阅读屏幕上的 x 和 y 框,然后检查其他 div。一周后,我意识到这是多么愚蠢。我的意思是首先我会为 div 分配一个新值,然后从 div 中读取它。访问 div 很昂贵。将 dom 视为渲染阶段。
  2. 如果可能容易使用网络工作者。
  3. 尽可能使用画布。
  4. 如果可能的话,让元素携带一个元素列表,它们应该被检查碰撞。(这仅在某些情况下有用)。

我了解到交互式碰撞的成本要高得多。因为您必须在正常交互时检查环境的变化,所以您模拟未来将要发生的事情,因此您的动画将更加流畅且可用的 CPU 更多。

我很早就做了一些东西只是为了好玩:http ://www.lastnoob.com/

于 2013-08-04T08:50:10.737 回答