I can't get a character to sit on top of a rect without falling through

Here’s my code:

// Adventures of Dingding
// By Dane MacFadden
// 2019/06/03
ArrayList<Platform> platform; // Holds platforms
Dingding dingding; // Character object

void setup() {
  size(600, 400);
  platform = new ArrayList<Platform>();  
  dingding = new Dingding();
}

void draw() {
  background(255);
  PVector gravity = new PVector(0, 0.3); // Adds gravity
  
  dingding.applyForce(gravity); // Applies gravity to character
  dingding.display();
  dingding.update();

  levelOne();

  for (Platform i : platform) { // Enhanced for loop to show all platforms
    i.display();
  }
}

void levelOne() { // Creates first level
  platform.add(new Platform(width/2, height-30, width, 100));
}

void keyPressed()  {// Lets character move
  if (key == 'a') {
    dingding.move(-5);
  } 

  if (key == 'd') {
    dingding.move(5);
  }
}

class Dingding {

  PImage sprite;

  PVector position;
  PVector dimensions;
  PVector vel;
  boolean isColliding;

  Dingding() {
    position = new PVector(width/2, height/2);
    dimensions = new PVector(50, 0);
    vel = new PVector(0, 0);
    sprite = loadImage("dingding.png");
  }

  void display() {
    imageMode(CENTER);
    image(sprite, position.x, position.y, dimensions.x, dimensions.x);
  }

  void move(float steps) { // Lets character move
    position.x += steps;
  }

  void applyForce(PVector force) { // Applies forces when the character is not touching a platform
    if (!isColliding) {
      vel.add(force);
    }
  }

  void update() { // Updates position of character
    position.add(vel);

    for (Platform i : platform) {
      if (i.collide(position)) {
        position.y = i.pos.y;
        isColliding = true;
      }
    }
  }
}


class Platform {
  
  PVector pos;
  PVector dim;
  
  Platform(float x, float y, float pWidth, float pHeight) {
    pos = new PVector(x, y);
    dim = new PVector(pWidth, pHeight);
  }
  
  void display() {
    stroke(0);
    rectMode(CENTER);
    fill(0);
    noStroke();
    rect(pos.x, pos.y, dim.x, dim.y);
  }
  
  boolean collide(PVector position) {
    if (position.x > (pos.x-dim.x) && position.y > pos.y && position.x < (pos.x+dim.x)) {
      return true;
    }
    return false;
  }
}

When I run the code, the character just falls right through the ground. I don’t get why. I’m kind of new to using PVectors and physics and such

1 Like

Hey There!

Always remember to format your code. It saves lives!

Not home but looks like your collision needs a bit of a re-work.

Yeah it was formatted, I think something just went wrong when I copy pasted it. Do you mean the Boolean in my platform class?

  • Dane

By format I mean on the forum. It seems your collision method is wrong.

Cannot run this code, first curly quotes issue then

cannot convert from element type Object to sketch_190604a.Platform

Amend sketch so we can see whats going on.

Normally though you would either create a return statement, or a if statement, which tests the characters position against the objects edges.

ie if(this.x>object.x&& this.x<object.x+object.width&&this.y>= object.y){
   return true;
}

some variation depending on the specifics of your requirements.

1 Like

Hello,

several issues here:

  • don’t call levelOne from draw(), because it copies the same platform over and over again into our poor ArrayList

  • Also, you use rectmode(CENTER). That means that x,y represents the center of the platform, not its upper left corner. Therefore you have to take away half of the height of the platform off the y-position to get the upper border of the platform. Same with x, on both sides.

  • also, don’t use image with 5 parameters, only 3. Using 5 parameters slows things down a lot. Use resize command in setup once and for all and then image with 3 parameters.

Remark

It’s ArrayList<Platform> platforms; // Holds platforms

With <Platform> you tell the ArrayList the type of objects it’s holding.

Remark

I also implemented the key w.

Chrisir



// Adventures of Dingding
// By Dane MacFadden
// 2019/06/03
ArrayList<Platform> platforms; // Holds platforms
Dingding dingding; // Character object

// ----------------------------------------------------------------------------

void setup() {
  size(600, 400);
  platforms = new ArrayList();
  dingding = new Dingding();

  levelOne();
}

void draw() {
  background(255);
  PVector gravity = new PVector(0, 0.3); // Adds gravity

  dingding.applyForce(gravity); // Applies gravity to character
  dingding.display();
  dingding.update();

  for (Platform i : platforms) { // Enhanced for loop to show all platforms
    i.display();
  }
}

// ----------------------------------------------------------------------------

void levelOne() { // Creates first level
  platforms.add(new Platform(width/2, height-30, 
    width-111, 30));
}

void keyPressed() {// Lets character move
  if (key == 'a') {
    dingding.move(-5);
  }

  if (key == 'd') {
    dingding.move(5);
  }

  if (key == 'w') {
    dingding.vel.y=-9;
    dingding.isColliding=false;
  }
}

// ==========================================================================

class Dingding {

  PImage sprite;

  PVector position;
  PVector dimensions;
  PVector vel;
  boolean isColliding=false;

  Dingding() {
    position = new PVector(width/2, height/2);
    dimensions = new PVector(50, 25);
    vel = new PVector(0, 0);
    sprite = loadImage("dingding.png");
  }

  void display() {
    imageMode(CENTER);
    ellipseMode(CENTER);
    //image(sprite, position.x, position.y, dimensions.x, dimensions.x);
    fill(245, 3, 2); 
    ellipse(position.x, position.y, 
      dimensions.x, dimensions.y);
  }

  void move(float steps) { // Lets character move
    position.x += steps;
  }

  void applyForce(PVector force) { // Applies forces when the character is not touching a platform
    if (!isColliding) {
      vel.add(force);
    }
  }

  void update() {  // Updates position of character
    //if (!isColliding) 
    position.add(vel);

    for (Platform i : platforms) {
      if (i.collide(position)) {
        position.y = i.pos.y-dimensions.y;
        dingding.vel.y=0.0; 
        isColliding = true;
      }
    }
  }
}//class

// ========================================================

class Platform {

  PVector pos;
  PVector dim;

  Platform(float x, float y, 
    float pWidth, float pHeight) {
    pos = new PVector(x, y);
    dim = new PVector(pWidth, pHeight);
  }

  void display() {
    stroke(0);
    rectMode(CENTER);
    fill(0);
    noStroke();
    rect(pos.x, pos.y, 
      dim.x, dim.y);
  }

  boolean collide(PVector position) {
    //
    if (position.x > (pos.x-dim.x/2) &&
      position.x < (pos.x+dim.x/2)-1 && 
      position.y >= pos.y-dim.y/2-1 
      ) {
      return true;
    }
    return false;
  }
}//class
//
2 Likes