Platform game mechanics

Hi guys,
I’m trying to make a simple platform game but I can’t solve the problem of my Ball having a different y level after a jump. When my yvelocity is high, my Ball just goes through the platform, because it’s not detected by the collision detection. I don’t know if this is related to each other, but I can’t figure it out.
I have already added an ArrayList, because in the end I want multiple platforms.
Hopefuly you can help me!


Ball b;
ArrayList <Platform> platforms;

void setup(){
  size (840,840);
  b = new Ball();
  platforms = new ArrayList<Platform>();
  platforms.add(new Platform(600, 600));
}

void draw(){
  background(0);
  fill(128,128,128);
  rect(0,height-100,width,100);
  b.display();
  b.move();
  for (int i=0; i<platforms.size(); i++){
    Platform p = platforms.get(i);
    p.display();
    p.collision(b);
    println(b.yvelocity);
    if (p.collision(b) == true && key != 'w'){
      b.gravity.y=0;
      b.yvelocity.y = 0;
     PVector platformspeed = b.yvelocity.copy();
     platformspeed.mult(-1);
     b.yvelocity.add(platformspeed);
    }
    
    if (keyPressed == true && p.collision(b) == true && key == 'w' && b.yvelocity.y>=0 && b.location.y <=p.location.y+25){
      b.yvelocity.y += b.upForce.y;
      b.location.add(b.yvelocity);
    }
    
    if (p.collision(b) == true && b.yvelocity.y<0){
      b.yvelocity.mult(-0.3);
    }
    }
  }

class Ball{
  
  PVector location = new PVector (100,height-125);
  PVector xvelocity = new PVector (0,0);
  PVector yvelocity = new PVector(0,0);
  PVector upForce = new PVector (0,-20);
  PVector gravity = new PVector (0,0.7);
  
  Ball(){
  }
  
  void display(){
    fill(255);
    ellipse(location.x,location.y, 25,25);
  }
  void move(){
    location.add(yvelocity);
    yvelocity.add(gravity);
    if (keyPressed){
    if (key == 'd'){
      xvelocity.x =3;
      location.add(xvelocity);
    }}
    if (keyPressed){
    if (key == 'a'){
      xvelocity.x = -3;
      location.add(xvelocity);
    }}
    if (location.y >=height-100){
      gravity.y =0;
      yvelocity.y=0;
    if (keyPressed == true){
    if (key == 'w'){
      yvelocity.y +=upForce.y;
    }
}} else{
gravity.y = 0.7;
}}}

class Platform{
  
  PVector location;
  
  Platform (float x, float y){
    location = new PVector (x,y);
  }
  
  void display(){
    fill(255);
    rect(location.x,location.y, 100,25);
  }
  
  boolean collision(Ball other){
     if ((other.location.x+12.5 >= location.x) && (other.location.x-12.5 <= location.x +100) && (other.location.y+12.5 >= location.y) && (other.location.y <= location.y+25)){
         return true;
     }else {
       return false;
     }
  
  }}

Hi koenterheegde57 .
I tried to run your sketch but it gives me the error
“cannot convert from Object to sketch_180920a.Platform”.
I saw that you tried to place the code in a block with < and /> used above and beneath the code. You need to replace both with this ```
Or you select the whole code text and press the </> button in the edit box.
You can edit your post above by clicking the pencil.
Once in a code block, the code can easily be copied, placing the mouse on top of the vertical scrollbar, where a copy button will appear.
I write this because the error could be a text format error.

if I understand this right, the “steps” a ball makes can be longer than the width of a platform (?).

I think you should not use the “classical” collision form of checking wether a point is within the boundaries of a rectangle…

you could either check if the ball is above the height of your platform an in between its extents to the left and the right and then limit its y position to that of the platform ->

if (location.y >= other.location.y) {
location.y == other.location.y;
}

(which is only a very rough depiction, of course)

it might be even better to use a little vector that shows the upcoming movement (like a line that points away from the ball and check for line intersections with each platform.
if there is an intersection you can reduce the next movement to the intersection point - that’s were the ball will be stopped in its movement.

since it is totally boring to someone like me who’s coding skills are usually limited by my poor math expertise and I do the same things again and again… here is a nice method for you that needs 4 points, one for each line

PVector calculateIntersection (PVector P1, PVector v1, PVector P3, PVector v2) {
  float parallel;
  parallel = v1.x*v2.y-v2.x*v1.y;
  if (parallel == 0) return P3;
  PVector P2 = new PVector(0, 0);
  PVector P4 = new PVector(0, 0);
  PVector S = new PVector(0, 0);
  P2.set(P1);
  P2.add(v1);
  P4.set(P3);
  P4.add(v2);
  //---------------
  S.x = ((P4.x-P3.x)*(P2.x*P1.y-P1.x*P2.y)-(P2.x-P1.x)*(P4.x*P3.y-P3.x*P4.y))/((P4.y-P3.y)*(P2.x-P1.x)-(P2.y-P1.y)*(P4.x-P3.x));
  S.y = ((P1.y-P2.y)*(P4.x*P3.y-P3.x*P4.y)-(P3.y-P4.y)*(P2.x*P1.y-P1.x*P2.y))/((P4.y-P3.y)*(P2.x-P1.x)-(P2.y-P1.y)*(P4.x-P3.x));
  return S;
}

Fixed it!
I already thought this would be wrong but couldn’t fix it. It should run now.

1 Like