Search code examples
javaprocessingcollision

Collision Problems in Processing


So I'm trying to make a platformer game and I'm just starting to work on collision. Right now the collisions very glitchy and only works if its on the side of a rectangle and not the top (this makes more sense if you run the code). I'm wondering how I can get the collision to be cleaner and overall less glitchy.

float x = 100;
float y = 100;

float vy = 0;
float vx = 0;

boolean rightCollision = false;
boolean leftCollision = false;

void setup(){
    size(700, 500);
    
}

void draw(){
  background(0);
  fill(255);
  rect(x, y, 50, 50);
  y += vy;
  vy += .3;
    
  x += vx;
  vx -= vx * 0.07;
    
    
  if(y > 400){
      vy = 0;
      y = 400;
  }
    
  if(left){
      x -= 1;
      vx -= .5;
  }
    
  if(right){
      x += 1;
      vx += .5;
  }
  
  if(touching(x, y, 50, 50, 400, 325, 100, 500) && keyCode == RIGHT){
      rightCollision = true;
  }
  else{
      rightCollision = false;
  }
  
  if(rightCollision){
      vx -= 2;
  }
  
  if(touching(x, y, 50, 50, 400, 325, 100, 500) && keyCode == LEFT){
      leftCollision = true;
  }
  else{
      leftCollision = false;
  }
  
  if(leftCollision){
      vx += 2;
  }
  
  fill(167);
  noStroke();
  rect(0, 450, 1000, 50);
  rect(400, 325, 100, 500);
}

boolean left = false;
boolean right = false;

void keyPressed(){
  if(keyCode == RIGHT || key == 'd'){
      right = true;
  }
    
  if(keyCode == LEFT || key == 'a'){  
    left = true;
  }
    
  if(keyCode == UP || key == 'w'){
    if(y == 400){
      vy -= 10;
    }
    
  }
  
}

void keyReleased(){
  if(keyCode == RIGHT || key == 'd'){
    right = false;
  }
  if(keyCode == LEFT || key == 'a'){
    left = false;
   }
}


boolean touching(float x1, float y1, float w1, float h1, float x2, float y2, float w2, float h2){
    return x1 + w1 >= x2 && x2 + w2 >= x1 && y1 + h1 >= y2 && y2 + h2 >= y1;
}


Solution

  • You need to detect the collision when the player is moving (vx != 0, vy != 0), not just when the key is pressed.
    Set the movement to 0 and limit the player's position when a collision is detected:

    int pw = 50, ph = 50;
    int ox = 400, oy = 325, ow = 100, oh = 400;
    
    topCollision = touching(x, y, pw, ph, ox, oy, ow, oh) && vy > 0.0 && y < oy;
    if (topCollision){
        vy = 0;
        y = oy-ph;
    }  
      
    rightCollision = touching(x, y, pw, ph, ox, oy, ow, oh) && vx < 0.0;
    if (rightCollision){
        vx = 0;
        x = ox+ow;
    }
      
    leftCollision = touching(x, y, pw, ph, ox, oy, ow, oh) && vx > 0.0;
    if (leftCollision) {
        vx = 0;
        x = ox-pw;
    }
    

    Use > instread of >= for the collision detection:

    boolean touching(float x1, float y1, float w1, float h1, float x2, float y2, float w2, float h2){
        return x1 + w1 > x2 && x2 + w2 > x1 && y1 + h1 > y2 && y2 + h2 > y1;
    }