Jump to content
  • Advertisement
Juan Kang

Help with Collision Detection on endless platform runner

This topic is 375 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi everyone, 
I've made a small java game recently, just for education purpose. So this game is a endless scrolling 2D plaformer. all you can do is jumping, with the impulse force to it. So the basic is to keep the player standing(and jumping) and move the background/platform from right to left. And with the forced jump, increase the force everytime the player press the button(e.g spacebar) and jump with the increased force when the button is released.
Then,  I use Collision/Physics detection, with the platform in the air, or standing like a wall. So I want, when the player is hit against the wall, he will be dragged by it, as it move from right to left. And now I have 2 problems:

- Sometime when the player is stand against a wall, and being dragged, he can't jump. Actually, just for a small distance and then stuck into a wall against him.

image.thumb.png.0dfee44bcbd307b7157370d0bb3b1655.png
- Some other times,  when I press/hold the button, he is going through the wall, and not even jump when I released the button.

image.thumb.png.7314e19105acc0dd5d5dae892a7aa1a2.png

- The second problem is, when he falling, if he hit the platform, he got stuck to it, unable to jump anymore.

image.thumb.png.832dae12e96598f09b2fe21f5020259d.png

I tried checking online for this, I believe I am probably Googling the wrong things to find tutorials for this, most tutorials seem to be for platformers like Rockman, or Flappy Bird,...But nothing seemed to solve my problems. 
These are some of my code:

Player.java

package smithitsmiths;

import bases.GameObject;
import bases.Vector2D;
import bases.inputs.InputManager;
import bases.physics.BoxCollider;
import bases.physics.Physics;
import bases.renderers.ImageRenderer;
import jdk.internal.util.xml.impl.Input;

public class Player extends GameObject {
    private Vector2D velocity;
    private final float GRAVITY = 1f;
    private final float JUMPSPEED = 10;
    protected float force = 0;
    private BoxCollider boxCollider;
    final static int maxForce = 2;
    public static float currentForce;

    public GaugeBar gaugeBar;


    public Player() {
        super();
        this.renderer = ImageRenderer.create("assets/images/players/player_walk1.png");

        velocity = new Vector2D();
        boxCollider = new BoxCollider(36, 45);
        this.children.add(boxCollider);

        gaugeBar = new GaugeBar();
        GameObject.add(gaugeBar);
    }

    @Override
    public float run(Vector2D parentPosition) {
        super.run(parentPosition);

        //GRAVITY impact velocity && Inputs
        this.velocity.y += GRAVITY;

        if (InputManager.instance.spacePressed) {

            if (force <= maxForce) {
                gaugeBar.setValue(force);
                force += 0.1f;
                return currentForce = force;
            }

        }

        if (InputManager.instance.spaceReleased) {
            //when player is at platform(not in the air), enable jump, vice versa
            BoxCollider boxColliderAtBottom = this.boxCollider.shift(0, 1);

            if (Physics.collideWith(boxColliderAtBottom, Platform.class) != null) {
                velocity.y = -JUMPSPEED * force;
            }
            force = 0;
            gaugeBar.reset();
        }

        //Platform physics
        moveVertical();
        moveHorizontal();


        //gaugebar update:
        gaugeBar.setPosition(this.position.x - 40, this.position.y - 40);

        return 0;
    }

    private void moveVertical() {

        //calculate future position(box collider) & predict collision
        BoxCollider nextBoxCollider = this.boxCollider.shift(0, velocity.y);

        Platform platform = Physics.collideWith(nextBoxCollider, Platform.class);
        if (platform != null) {

            //move player continously towards platform
            boolean moveContinue = true;
            float shiftDistance = Math.signum(velocity.y);
            while (moveContinue) {
                if (Physics.collideWith(this.boxCollider.shift(0, shiftDistance), Platform.class) != null) {
                    moveContinue = false;
                } else {
                    shiftDistance += Math.signum(velocity.y);
                    this.position.addUp(0, Math.signum(velocity.y));
                }
            }

            //update velocity ()
            velocity.y = 0;
        }

        //velocity impact position
        this.position.addUp(0, velocity.y);
        this.screenPosition.addUp(0, velocity.y);

    }

    private void moveHorizontal() {


        //calculate future position(box collider) & predict collision
        BoxCollider nextBoxCollider = this.boxCollider.shift(velocity.x, 0);

        Platform platform = Physics.collideWith(nextBoxCollider, Platform.class);
        if (platform != null) {
            //move player continously towards platform
            boolean moveContinue = true;
            float shiftDistance = Math.signum(velocity.x);
            while (moveContinue) {
                if (Physics.collideWith(this.boxCollider.shift(shiftDistance, 0), Platform.class) != null) {
                    moveContinue = false;
                    this.position.subtractBy(platform.getSpeed(),0);
                } else {
                    shiftDistance += Math.signum(velocity.x);
                    this.position.addUp(Math.signum(velocity.x), 0);
                }
            }
            //end move player continously towards platform


            //update velocity ()
            velocity.x = 0;
        }

        //velocity impact position
        this.position.addUp(velocity.x,0);
        this.screenPosition.addUp(velocity.x,0);

    }
}
Platform.java:
package smithitsmiths;

import bases.GameObject;
import bases.Vector2D;
import bases.physics.BoxCollider;
import bases.physics.PhysicsBody;
import bases.renderers.ImageRenderer;

public class Platform extends GameObject implements PhysicsBody{
    private BoxCollider boxCollider;
    private final float SPEED = 2;
    Vector2D velocity;

    public Platform() {
        super();
        this.renderer = ImageRenderer.create("assets/images/platform/yellow_square.jpg");
        boxCollider = new BoxCollider(30,30);
        this.children.add(boxCollider);
        velocity = new Vector2D();
    }

    @Override
    public float run(Vector2D parentPosition) {
        super.run(parentPosition);

        velocity.x = -SPEED;
        position.addUp(velocity);
        return 0;
    }

    @Override
    public BoxCollider getBoxCollider() {
        return boxCollider;
    }

    public float getSpeed() {
        return SPEED;
    }
}

 

BoxCollider.java:

package bases.physics;

import bases.GameObject;

public class BoxCollider extends GameObject {
    private float width;
    private float height;

    public BoxCollider(float x, float y, float width, float height) {
        super();
        this.position.set(x, y);
        this.screenPosition.set(x, y);
        this.width = width;
        this.height = height;
    }

    public BoxCollider(float width, float height) {
        this(0, 0, width, height);
    }

    public BoxCollider shift(float dx, float dy){
        BoxCollider shiftedBoxCollider = new BoxCollider(this.width, this.height);
        shiftedBoxCollider.position.set(this.position.add(dx,dy)); //new position of newBC = current position + (dx,dy)
        shiftedBoxCollider.screenPosition.set(this.screenPosition.add(dx,dy));
        return shiftedBoxCollider;
    }

    public float left() {
        return this.screenPosition.x - this.width / 2;
    }

    public float right() {
        return this.screenPosition.x + this.width / 2;
    }

    public float top() {
        return this.screenPosition.y - this.height / 2;
    }

    public float bottom() {
        return this.screenPosition.y + this.height / 2;
    }

    public float getWidth() {
        return width;
    }

    public float getHeight() {
        return height;
    }

    public boolean intersects(BoxCollider other) {
        return this.bottom() >= other.top() &&
                this.top() <= other.bottom() &&
                this.right() >= other.left() &&
                this.left() <= other.right();
    }

    @Override
    public String toString() {
        return "BoxCollider{" +
                "width=" + width +
                ", height=" + height +
                ", screenPosition=" + screenPosition +
                '}';
    }
}

 

So the ground is a total of many square platforms, with the BoxCollider of each. I really confuse where the bug is, and how to fix it. So I post it here hopefully you guys can tell me what to do. 
I really appreciate it.

Thanks for reading my post.

Edited by Juan Kang

Share this post


Link to post
Share on other sites
Advertisement

Hey there,

hard to tell what the problem might be, but imho you should check few things that might solve problems:

1. Try to change box colliders size for both player (bigger than actual player's size) and platform (smaller than actual box size). Both of your problems sounds like the collision detects the intersection in wrong places. 

2. Try to separate the collision for horizontal and vertical movement. So the player can only jump if it's not in the air (and y position is set to the current box he collides (but remember about the Box size, so it doesn't collides with neighbours or the player will be moved up or down :P).

 

Anyway your collision detection system looks bit weird and if you could share the code I might try to solve it, but no promises ;]

Good luck!

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!