Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect collisions between fast moving objects

Generally to detect collisions in canvas games I use something like:

function collides(a, b) {
   return a.x < b.x + b.width &&
     a.x + a.width > b.x &&
     a.y < b.y + b.height &&
     a.y + a.height > b.y;
}

But this only detects collisions if the objects are touching at the time the frame is processed. If I have a sprite whose speed (in pixels/frame) is greater than the width of an obstacle in its path, it will pass through the obstacle without the collision being detected.

How would I go about checking what's in between the sprite and its destination?

like image 247
Sam Avatar asked May 09 '13 12:05

Sam


People also ask

How do you detect collisions?

If both the horizontal and vertical edges overlap we have a collision. We check if the right side of the first object is greater than the left side of the second object and if the second object's right side is greater than the first object's left side; similarly for the vertical axis.

What is the fastest collision algorithm?

As with 2D collision detection, axis-aligned bounding boxes (AABB) are the quickest algorithm to determine whether the two game entities are overlapping or not.

Which method is used to collision detection between two rectangles?

Axis-Aligned Bounding Box One of the simpler forms of collision detection is between two rectangles that are axis aligned — meaning no rotation. The algorithm works by ensuring there is no gap between any of the 4 sides of the rectangles. Any gap means a collision does not exist.

How can you determine of there is a collision between two circles?

Determining whether or not two circles intersect or overlap is the most basic way of determining whether or not two circles have collided. This is done by comparing the distance squared between the two circles to the radius squared between the two circles.


1 Answers

That's a generally a hard problem and for high-quality solution something like Box 2D library will be useful.

A quick and dirty solution (that gives false positives on diagonally moving objects) — check collision between bounding boxes that cover position of object in current and previous frame.

Instead of a.x use min(a.x, a.x - a.velocity_x), instead of a.x + a.width use max(a.x + a.width, a.x + a.width - a.velocity_x), etc.

If the object that is moving fast is small (a bullet), then test collision between line (from its origin to origin + velocity) and boxes of other objects.

like image 88
Kornel Avatar answered Nov 16 '22 04:11

Kornel