如何在游戏循环中只检测一次碰撞而不是连续检测碰撞?

Posted

技术标签:

【中文标题】如何在游戏循环中只检测一次碰撞而不是连续检测碰撞?【英文标题】:How to detect collision only once in Game-loop instead of continuously? 【发布时间】:2019-01-02 14:13:07 【问题描述】:

我正在用 javascript 编写一个小空间游戏,如何检测碰撞?

我正在使用 requestAnimationFrame() 循环游戏,我的问题是: 如何检测两个物体之间的碰撞,因为计数(死亡)变量只增加一次而不是连续增加?

// --- Collision ---
asteroids.forEach(asteroid => 
  //if (collisionOccured)  return;  I thought might work...
  if (distance(spaceship.x + spaceship.width, spaceship.y + spaceship.width, asteroid.x, asteroid.y) < asteroid.radius + spaceship.width) 
     console.log('Collision');
     collisionOccured = true;
     deaths++;
  
);

我想我明白问题出在哪里,两个物体正在碰撞,所以它们之间的距离在 n 帧中小于条件,所以死亡变量更多地计算它们碰撞的帧而不是数量碰撞。 但是我该如何做对呢?任何的想法?

如果有帮助,这里是距离函数:

function distance(x1, y1, x2, y2) 
  return Math.sqrt(Math.pow(Math.abs(x1 -  x2), 2) + Math.pow(Math.abs(y1 - y2), 2));

【问题讨论】:

【参考方案1】:

如果之前没有检测到碰撞,您只能增加死亡人数。

if (distance(spaceship.x + spaceship.width, spaceship.y + spaceship.width, asteroid.x, asteroid.y) < asteroid.radius + spaceship.width)          
    if (!collisionOccured) 
      console.log('Collision');
      collisionOccured = true;
      deaths++;
    

如果这不起作用,那是因为 collisionOccured 在每一帧开始时被设置为 false,您应该尝试找到一种方法来保持变量在前一帧中的值。

【讨论】:

感谢您的快速回复!但如果我这样做,它会检测到与另一颗小行星的下一次碰撞吗?也许碰撞发生变量必须在 Asteroid 类中? 是的,你可以在小行星类中有一个布尔值“碰撞”。但在那种情况下,如果有许多小行星相撞,你仍然应该只将死亡人数增加 1 对吧? 是的,但这不是绝对必要的。顺便说一句,非常感谢您的帮助!!

以上是关于如何在游戏循环中只检测一次碰撞而不是连续检测碰撞?的主要内容,如果未能解决你的问题,请参考以下文章

CollisionOnEnter 如何检测物体是不是发生碰撞?

碰撞检测经典解决方案

俄罗斯方块游戏开发系列教程4:形状碰撞检测(上)

Monogame碰撞检测无法正常工作

pygame.mask原理及使用pygame.mask实现精准碰撞检测

pygame.mask原理及使用pygame.mask实现精准碰撞检测