Collision with platforms

I know i had a post about this last week, but i have since changed my design and am now really in need of some ideas and ways that i can implement collisions between my player and platforms.

This is what my game currently looks like:

I have all platforms loaded into an array list, but i don’t want to check for collisions against every platform as that just would cause the performance to decrease dramatically.
So i’ve been trying to think of ways to decide on which platform/s to check for collisions based on the players position.
Which is what i need help with.

So, if you have any ideas or suggestions please reply.

If you’re going to make Doodle Jump clone, then I sugesst you to only check platform that appear in screen. Should no more than 10 right?

However if it’s clone, as ra4king who has made it successfully :wink:

To check a subsection of the map…

Things you need:

  1. Map (Defined some how that allows you to get position information)
  2. Player (Defined by a position and dimensions)
  3. Information about relative dimensions of platform blocks.

Then:
int startX = Player.position.x / width
int startY = Player.position.y / height
int endX = (Player.position.x + player.width) / width
int endY = (Player.position.y + player.height) / height

boolean isOccupied(int startX, int startY, int endX, int endY) {
for(int i = startX; i <= endX; i++) {
for(int j = startY; j <= endY; j++) {
if(map.isFilled(i,j)){
return true;
}
}
return false;
}

One thing to note is that this only checks current position. Of course, you can use it to check whether or not the result of a movement. If you’re really smart, you can have it return the position of the ‘first’ collision that occurs in the direction of a motion. So you know which way to shift for the stop to happen.

Doesn’t that startx stuff seem unnecessary? Why not just do this:

if (!map.collisionAt(player.getX() + player.getXVel(), player.getY() + player.getYVel()) {
// No collision if you move here, go ahead and move
}

The collisionAt(int x, int y) method in Map simply loops and checks each platform to see if ‘x’ or ‘y’ is between their position and position + size.

No need to complicate it =)

A Rectangle v Rectangle check is very cheap so you should be fine looping through all Platform’s rectangle bounds against the player’s bounds (please have a Rectangle instance in each Platform and in the Player class, instead of creating an instance within the getBounds() method. That’s a GREAT way to waste memory :)). If the velocity of the player is greater than 0, check for collisions :slight_smile:

you mean this? ;D


public Rectangle getBounds(){
    return new Rectangle(x, y, width, height);
}

I really believe OP want make DJ.

Yes.

A rectangle vs rectangle is great too. So, essentially, after initializing all the rectangles (having each rect cover the entire platform) when you create your player/platforms, it’s as simple as:


public boolean collisionAt(Player player) {
              // Loop through all platforms in the map
              for (Platform platform : platformList) {
                          // If the player's rectangle is inside this particular platform's rectangle (intersects() is a method in Rectangle 
                          // that takes another Rectangle as an argument and checks this for you)
                          if (player.getCollisionRect().intersects(platform.getCollisionRect())) {
                                         return true;      // Collision! Return true so player knows
                          }
              }
              return false;         // Nothing returned true, so report false
}

Like ra4king said, this only checks the current position so in your update move player, then check. Move back if there was a collision. So your player’s update method might look like this:


public void update(float elapsedTime) {
             // ....
             // Other updates
             // ....

             // Move player
             x += xVel;
             y += yVel;

             // Check map now that I've moved
             if (map.collisionAt(this)) {
                       // We can't go here now, so 'undo'
                       x -= xVel;
                       y -= yVel;
             }
}

EDIT: Actually, wouldn’t it be more readable to pass an x or y and collisionAt() makes a player rect before the loop? That sounds more readable with negligible overhead. Correct me if I’m wrong.

Think of design here, why would the map care what the player is? The way you have it is fine, however it is best to make checkCollision take an object of type Entity or whatever other superclass all entities extend. Then make it return an Entity instead of boolean (null being false) so you could have specialized behavior :slight_smile:

That’s a good idea. Then Player could use instanceof to have reactions against spikes or an enemy.

That way enemies could utilize it as well to climb walls or have different behavior.

Thanks for your help guys, I’ve got heaps of ideas on collision now, its just i can’t find a good way to move the camera with the player as they climb each platform. I’ve tried changing the velocity of the camera and/or adding to its position, but i can’t get something solid.
PS. My camera class just holds its yPosition and all entities are drawn based on its position.

Is there better design i could be using? Im really not sure.

Your design is the best way to do it. All entities should have some way to access this Camera instance and then just add yOffset to their Y coordinates :slight_smile: