Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Rectangular Collision

This simple example demonstrates collisions detection between two rectangular objects. Note that this method will only work when both rectangles are axis-aligned, and only with rectangles!

However, it's possible to use this approach with invisible bounding boxes around more complex shapes. In many cases, as in old arcade games, the user may not even notice the collisions are based purely on rectangles.

Code Block
languagejavajs
intvar rctl1X; // rectangle One x position
intvar rctl1Y; // rectangle One y position
intvar rctl1W = 40; // rectangle One Width
intvar rctl1H = 70; // rectangle One Height
//
intvar rctl2X; // rectangle One x position
intvar rctl2Y; // rectangle One y position
intvar rctl2W = 100; // rectangle 2Two Width
intvar rctl2H = 100; // rectangle 2Two Height

voidfunction setup() {
  sizecreateCanvas(800, 600);
  noStroke();
  rectMode(CENTER);
  rctl2X = width/2;
  rctl2Y = height/2;
}

voidfunction draw() {
  background(255);
  rctl1X = mouseX; 
  rctl1Y = mouseY; 
  booleanvar collision = checkCollision(rctl1X, rctl1Y, rctl1W, rctl1H, rctl2X, rctl2Y, rctl2W, rctl2H);
  if (collision) {
    fill(70255, 0, 0);
  } else {
    fill(2550, 0255, 0);
  }
  rect(rctl1X, rctl1Y, rctl1W, rctl1H);
  rect(rctl2X, rctl2Y, rctl2W, rctl2H);
}

// this method uses the center of the rectangles
booleanfunction checkCollision(int r1x, int r1y, int r1w, int r1h, int r2x, int r2y, int r2w, int r2h) {
  // store the locations of each rectangles outer borders 
  intvar top1 = r1y-r1h/2;
  intvar bottom1 = r1y+r1h/2;
  intvar right1 = r1x+r1w/2;
  intvar left1 = r1x-r1w/2;
  intvar top2 = r2y-r2h/2;
  intvar bottom2 = r2y+r2h/2;
  intvar right2 = r2x+r2w/2;
  intvar left2 = r2x-r2w/2;

  if (top1>bottom2 || bottom1<top2 || right1<left2 || left1>right2) {
    return false;
  } else {
    return true;
  }
}


Rectangular Collision

This method uses the top left original of the rectangle and width and height to calculate the collision.

Code Block
languagejava
booleanfunction checkRectangle(
  floatvar r1x, floatvar r1y, floatvar r1w, floatvar r1h, 
  floatvar r2x, floatvar r2y, floatvar r2w, floatvar r2h) {

  return (r1x < r2x + r2w &&
    r1x + r1w > r2x &&
    r1y < r2y + r2h &&
    r1y + r1h > r2y);
}


Circular Collision

The following example demonstrates a simple method for checking collisions between round objects. As in the above example, it can be used to create invisible bounding boxes for more complex shapes. 

ArrayList<Ball>
Code Block
languagejs
let ballList = new[] ArrayList<Ball>();
Balllet mouseBall;
voidlet centerBall;

function setup()
{
  sizecreateCanvas(600, 800);
  
 ballList.add( for (var j = 0; j< 10; j++) {
     centerBall = new Ball(width/2+j, height/2+j, 40);
     ballList.push(centerBall);

   }  
  mouseBall = new Ball(mouseX, mouseY, 20);
 
}

voidfunction draw()
{
  background(255);
  mouseBall.update(mouseX, mouseY);

  for (intvar i = 0; i<ballList.size()i< ballList.length; i++) {
    ballList.get([i)].drawBall();
    mouseBall.checkCollision(ballList.get(i)._position, ballList.get(i)._radius);
  }
    mouseBall.drawBall();
}

class Ball {
  PVector
_position = newconstructor PVector();
  int _radius;
  int colour = 250;
  public Ball(int x, int y, int r) {
    this._position.set = createVector(x, y, 0);
    this._radius = r;
    this.colour = 250;
  }
  void
  update(int x, int y) {
    this._position.setadd(x, y, 0);
  }

  void drawBall() {
    pushMatrix();
    fill(this.colour, 0, 0);
    noStroke();
    translate(this._position.x, this._position.y);
    ellipse(0, 0, this._radius* 2, this._radius*2);
    popMatrix();
  }

  void checkCollision(PVector position, int radius) {
    floatvar distance = PVectorp5.Vector.dist(this._position, position);
    if (this.distance <= radius +this._radius) {
      println("hit");
      this.colour = 60;
    } else {
      this.colour = 255;
    }
  }
}


Point and Polygon

Sometimes it is only necessary to check if one specific points is inside a very complex shape. This complex shape can even be convex, which means that the edges of the polygon do not only point to the outside, but maybe also to the inside.Image Removed

...

But there is a simple solution to check, if a point is located inside or outside this complex shape. W. Randolph Franklin created this method to check, if a point is located inside an Array of points. This is an adapted version for processing.

boolean pnpoly(PVector[] vertices, float testx, float testy) { int i, j; boolean c = false
Code Block
languagejava
firstline1
titlePNPoly
js
const polyPoints = [{
    x: 445,
    y: 240
  },
  {
    x: 350,
    y: 410
  },
  {
    x: 150,
    y: 410
  },
  {
    x: 45,
    y: 240
  },
  {
    x: 150,
    y: 60
  },
  {
    x: 240,
    y: 225
  }
];

function setup() {
  createCanvas(500, 500);
}

function draw() {
  background('#f8f8f8');

  drawCustomShape();
  drawCollidingShape();

  (hit()) ? fill('#131721'): noFill();
}

//is colliding shape in custom shape
function hit() {
  return polyPoint(polyPoints, mouseX, mouseY);
}

//shape being collided with
function drawCustomShape() {
  beginShape();
  strokeJoin(ROUND);
  strokeWeight(10)
  for (let i = 0; i < Object.keys(polyPoints).length; i++) {
    vertex(polyPoints[i].x, polyPoints[i].y);
  }
  endShape(CLOSE);
}

//colliding shape
function drawCollidingShape() {
  push();
  fill('#f8f8f8');
  ellipse(mouseX, mouseY, 10, 10);
  pop();
}



// POLYGON/POINT
function polyPoint(vertices, px, py) {
  let collision = false;

  // go through each of the vertices, plus
  // the next vertex in the list
  let next = 0;
  for (ilet current = 0,; jcurrent =< vertices.length-1; i < vertices.length; j = i++) {
    if ( ((vertices[i].y>testy) != (vertices[j].y>testy)) 
      && (testx < (vertices[j].x-vertices[i]; current++) {

    // get next vertex in list
    // if we've hit the end, wrap around to 0
    next = current + 1;
    if (next == vertices.length) next = 0;

    // get the Vectors at our current position
    // this makes our if statement a little cleaner
    let vc = vertices[current]; // c for "current"
    let vn = vertices[next]; // n for "next"

    // compare position, flip 'collision' variable
    // back and forth
    if (((vc.y >= py && vn.y < py) || (vc.y < py && vn.y >= py)) &&
      (px < (vn.x - vc.x) * (testy-vertices[i]py - vc.y) / (vertices[j]vn.y-vertices[i] - vc.y) + vertices[i]vc.x)) ){
      ccollision = !ccollision;
    }
  }
  return ccollision;
}


Bitmap Collision

For complex shapes, it's possible to create a reference bitmap to indicate hit areas. This reference can be black and white images, which correlates exactly to an image or shape that will be displayed on the screen. This method works well for game maps, and in situations where you are testing a simple shape against a complex one. 

Out background image:Image Removed

...

Our collision reference: Image Removed

...

Download Source Code

...