2D collision detection - 游戏开发环境 编辑

检测2D游戏中的碰撞算法,依赖于可碰撞物体的形状(例如:矩形与矩形,矩形与圆形,圆形与圆形)。通常情况下,你使用的的简单通用形状,会被称为“hitbox”的实体所覆盖,尽管发生的碰撞并不是像素完美契合的,它看起来也足够好,而且可跨多个实体执行碰撞。本文提供了一系列较为通用的2D游戏中碰撞侦测技术。

Axis-Aligned Bounding Box

碰撞侦测其中一种简单的形式是,在两个轴对齐的矩形之间碰撞 — 这意味着没有旋转。这个算法是确定两个矩形任意4边之间不再有间隔,存在间隔代表没有发生碰撞。

var rect1 = {x: 5, y: 5, width: 50, height: 50}
var rect2 = {x: 20, y: 10, width: 10, height: 10}

if (rect1.x < rect2.x + rect2.width &&
   rect1.x + rect1.width > rect2.x &&
   rect1.y < rect2.y + rect2.height &&
   rect1.height + rect1.y > rect2.y) {
    // collision detected!
}

// filling in the values =>

if (5 < 30 &&
    55 > 20 &&
    5 < 20 &&
    55 > 10) {
    // collision detected!
}

Note: You can see a live example of Axis-Aligned Bounding Box collision detection on jsFiddle, to illustrate how this code would work in practice. Here is another example without Canvas or external libraries.

圆形碰撞

碰撞测试的另一种形状是两个圆形间的碰撞,该算法是通过获取两个圆心点,并确定圆心距离小于两个圆形的半径和实现的。

var circle1 = {radius: 20, x: 5, y: 5};
var circle2 = {radius: 12, x: 10, y: 5};

var dx = circle1.x - circle2.x;
var dy = circle1.y - circle2.y;
var distance = Math.sqrt(dx * dx + dy * dy);

if (distance < circle1.radius + circle2.radius) {
    // collision detected!
}

Note: You can see a live example of Circle collision detection on jsFiddle, to illustrate how this code would work in practice.

Separating Axis Theorem

This is a collision algorithm that can detect a collision between any two *convex* polygons. It's more complicated to implement than the above methods but is more powerful. The complexity of an algorithm like this means we will need to consider performance optimization, covered in the next section.

Implementing SAT is out of scope for this page so see the recommended tutorials below:

  1. Separating Axis Theorem (SAT) explanation
  2. Collision detection and response
  3. Collision detection Using the Separating Axis Theorem
  4. SAT (Separating Axis Theorem)
  5. Separation of Axis Theorem (SAT) for Collision Detection

Collision Performance

While some of these algorithms for collision detection are simple enough to calculate, it can be a waste of cycles to test *every* entity with every other entity. Usually games will split collision into two phases, broad and narrow.

Broad Phase

Broad phase should give you a list of entities that *could* be colliding. This can be implemented with a spacial data structure that will give you a rough idea of where the entity exists and what exist around it. Some examples of spacial data structures are Quad Trees, R-Trees or a Spacial Hashmap.

Narrow Phase

When you have a small list of entities to check you will want to use a narrow phase algorithm (like the ones listed above) to provide a certain answer as to whether there is a collision or not.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

词条统计

浏览:43 次

字数:4801

最后编辑:7年前

编辑次数:0 次

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文