Simple collision detection - Griffith-ICT/1701ICT-Creative-Coding GitHub Wiki
A common technique in game programming is collision detection, i.e. detecting if two objects have collided. Collision detection could be used to collect objects, prevent a car from driving off a road or through houses, or to cause an explosion.
Collision detection can be tricky when done well. We are going to use a simple technique based on the distance from the object.
We are going to presume that if two objects are within 20 pixels of each other then there is a collision.
We need to check each axis:
if (dx < 20 && dy < 20) {
// Collision
}
&& - AND
In the above if statement we combined two conditions using the && operator. && simply means and. It means that we require both expressions to be true for the entire if statement to be true.
dx, dy
We want the distance between the x positions and y positions to be less than a threshold. First we need to work out the distances.
Let's assume we are comparing the robot position with a target position. The difference in positions is simply the subtraction:
var dx = robotX - targetX;
var dy = robotY - targetY;
Can you see a problem here?
The problem is we may end up with a negative dx and/or dy which would always be less then 20.
We need to ensure that any negative values are always positive. In maths we call it the absolute value, and JavaScript provides a function for us to make the conversion: Math.abs().
We can rewrite our calculations as:
var dx = Math.abs(robotX - targetX);
var dy = Math.abs(robotY - targetY);
Note that it is also possible to perform an absolute calculation manually using the logic that if a negative value is encountered then make it positive, e.g.:
if (dx < 0) {
dx = -dx;
}
But generally Math.abs() is used because it is shorter.
Game with collision
Here is a simple example of a game where when the robot overlaps the ellipse the ellipse moves. Note that the robot and ellipse always start in the same positions, and the ellipse only moves once to a new position.
var img; // Robot image
var robotX; // Robot x and y co-ordinates (centre of the robot image)
var robotY;
var targetX = 100; // Ellipse x and y co-ordinates
var targetY = 20;
function setup() {
createCanvas(400, 400);
img = loadImage("robot.png"); // Load the image
robotX = width / 2;
robotY = height / 2;
}
function draw() {
background('white');
// Displays the image at point (0, height/2) at half size
image(img, robotX - img.width / 2, robotY - img.height / 2);
// Draw the target as an ellipse
ellipse(targetX, targetY, 40, 40);
// Some debugging
text("x: " + robotX, 5, 15);
text("y: " + robotY, 5, 30);
}
function keyPressed() {
if (keyCode === LEFT_ARROW) {
robotX -= 5;
}
if (keyCode === RIGHT_ARROW) {
robotX += 5;
}
if (keyCode === UP_ARROW) {
robotY -= 5;
}
if (keyCode === DOWN_ARROW) {
robotY += 5;
}
// How far is the robot from the target?
var dx = Math.abs(robotX - targetX);
var dy = Math.abs(robotY - targetY);
// If less than 20 pixels on both axes then move the target
if (dx < 20 && dy < 20) {
targetX = 300;
targetY = 300;
}
}