From 3df30a2b778f24ab6b3dbd4d8327e96a013dd45d Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 27 Dec 2014 04:15:03 +1100 Subject: [PATCH] Fixed formatting issues --- collision-logic.md | 79 +++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/collision-logic.md b/collision-logic.md index 9569907..62270b1 100644 --- a/collision-logic.md +++ b/collision-logic.md @@ -1,4 +1,4 @@ -Abstract: +## Abstract The goal of this pseudocode is to create a collision system that brings several colliding bodies to a near-contact state (no space between the bodies, but not @@ -6,7 +6,7 @@ overlapping), while preserving the motion of said bodies. For simplicity, I've decided to use a square box (BoundingBox, or BBox for short) for the collidable bodies. -Example: +## Goal My current game has a tiled-map, where the tiles are arranged on a 2D grid. The tiles each have a flag indicating if they are solid (i.e. collidable) or not. I @@ -22,19 +22,21 @@ Obviously, there are many in depth issues that I will need to take into account when writing this logic, that have been glossed over or omitted in this article. -------------------------- +## Design + +### Basic Example ``` - velocity = motion + speed - if (collision(position + velocity)) then - if (collision(position + {velocity.x, 0})) then - velocity.x = 0 - end - if (collision(position + {0, velocity.y})) then - velocity.y = 0 - end +velocity = motion + speed +if (collision(position + velocity)) then + if (collision(position + {velocity.x, 0})) then + velocity.x = 0 end - position = position + velocity + if (collision(position + {0, velocity.y})) then + velocity.y = 0 + end +end +position = position + velocity ``` This code is a basic outline for a collision system that preserves the object's @@ -42,15 +44,15 @@ motion, but it still leaves several pixels of space between the bounding boxes. Notably, it also treats "collision" as an abstract concept, rather than as an event that could happen multiple times per frame. -------------------------- +### Better Example ``` - velocity = motion + speed - if (collisionSimple(BOXSET, position + velocity)) then - velocity.x = collisionX(BOXSET, velocity.x) - velocity.y = collisionY(BOXSET, velocity.y) - end - position = position + velocity +velocity = motion + speed +if (collisionSimple(BOXSET, position + velocity)) then + velocity.x = collisionX(BOXSET, velocity.x) + velocity.y = collisionY(BOXSET, velocity.y) +end +position = position + velocity ``` Here, collisions are still abstract, but "BOXSET" is defined externally @@ -62,17 +64,17 @@ If there are any collisions between the player object and the given box set, then collisionX() and collisionY() are called to calculate the new distance that the character will move. -------------------------- +### Simple Collision Check ``` - bool collisionSimple(BOXSET, newPos): - for_each box in BOXSET do - if (box.overlap(PLAYER.box + newPos)) then - return true - end +bool collisionSimple(BOXSET, newPos): + for_each box in BOXSET do + if (box.overlap(PLAYER.box + newPos)) then + return true end - return false end + return false +end ``` collisionSimple() first runs through the BOXSET, checking if any of the given @@ -90,24 +92,23 @@ would not have been checked against the removed elements. Just something to note. -------------------------- +### Velocity Correction ``` - var collisionX(BOXSET, velocityX): - var ret = velocityX +var collisionX(BOXSET, velocityX): + var ret = velocityX - for_each box in BOXSET do - if (box.overlap(PLAYER.box + PLAYER.position + {velocityX,0})) then - if (velocityX > 0) then - ret = min(ret, box.west - PLAYER.position.x) - else - ret = max(ret, box.east - PLAYER.position.x) - end + for_each box in BOXSET do + if (box.overlap(PLAYER.box + PLAYER.position + {velocityX, 0})) then + if (velocityX > 0) then + ret = min(ret, box.west - PLAYER.position.x) + else + ret = max(ret, box.east - PLAYER.position.x) end end - - return ret end + return ret +end ``` Two things: 1. collisionX() and collisionY() should be identical except for the @@ -122,4 +123,4 @@ right (or up or down). An unfortunate bug I can already see is that this logic doesn't check corners; it might be possible to get stuck on a corner of a wall, but if this becomes an issue in my implementation I will update this article with that information, -and you can promptly ignore it. \ No newline at end of file +and you can promptly ignore it.