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;
  }
}