-
Notifications
You must be signed in to change notification settings - Fork 0
Collision detection
Let (x, y)
, (v_x, v_y)
and (w, h)
denote the position, velocity and dimensions (width and height),
respectively, of the player,
and (X, Y)
and (W, H)
the corresponding attributes of an obstacle. Compute the overlaps
a_L = x + w - X,
a_R = X + W - x,
a_T = y + h - Y,
a_B = Y + H - y,
called, respectively, the left, right, top and bottom overlaps. Player and obstacle collide if all the above overlaps are positive numbers.
The collision is a left collision if a_L < w < a_R
, a right collision if a_R < w < a_L
,
a top collision if a_T < h < a_B
and a bottom collision if a_B < h < a_T
. Combining
these conditions we see that there are a total of eight possible collision scenarios:
- Top-left (i.e. a collision which is both a top collision and a left collision)
- Direct top (a collision which is a top collision but neither a left nor a right collision)
- Top-right
- Direct right
- Bottom-right
- Direct bottom
- Bottom-left
- Direct left
Note that collisions where the player would be entirely inside an obstacle or vice versa are not taken into account here. We assume that the game physics object sizes are parametrized in such a way that the maximum distance spanned over one frame is less than the player size and minimum obstacle size.
The direct collisions 2, 4, 6 and 8 are handled in a straight-forward way by pushing the player away from the obstacle along the cardinal direction in question and zeroing the appropriate component of velocity. For example, for a direct top collision:
y -= a_T
v_y = 0
Note that we are using image coordinates where the y
axis points down, and, by definition of a collision,
a_T > 0
.
The corner collisions are a bit more subtle. First of all, the appropriate action to take depends on player velocity direction. There are four possible cases, enumerated below for a top-left collision:
-
v_x > 0 and v_y < 0
, i.e. the velocity points top-right. In this case we setv_x = 0
and push the player to the left. -
v_x < 0 and v_y < 0
, i.e. velocity points top-left. This case should not be possible, so we don't take any action here. -
v_x < 0 and v_y > 0
, i.e. velocity points bottom-left. Set vertical speed to zero and push the player up. -
v_x > 0 and v_y < 0
, i.e. velocity points towards the obstacle. This case is further divided into two, based on the overlap values: Ifa_L < a_T
, set horizontal speed to zero and push player left. Ifa_L > a_T
, set vertical speed to zero and push player up.
Other corner collisions are handled similarly, by considering the direction of player velocity relative to the obstacle, and dividing the head-on collision into two based on the relation of the appropriate overlap values.