Search code examples
javalibgdxgame-physics

Calculating collisions, taking into account velocity


I'm making a platformer game. The jumping and movement are working, and now I want to program the collisions. I have a sort of idea as to how this will work:

I wasn't sure whether this question should be here or in the game dev site.

  1. I have two Vector2's - velo and momentum (velo is the velocity). Both are (0, 0). The momentum is what's added to the velocity each frame.

  2. Each frame, I first get the input. Momentum is increased and/or increased based on the keys pressed (e.g: if (Gdx.input.isKeyPressed(Keys.A)) { momentum.x -= speed; })

  3. I then multiply the momentum by 0.15. This is so that it slows down.

  4. After this, I multiply the velocity by 0.8.

  5. Then, I add the momentum to the velocity, to increase the velocity, as this is what actually moves the player.

  6. I then add the velocity to the position of the player.

  7. To apply the gravity, I add a gravity vector (0, -10) to the position of the player.

So I need to find a way to move the player, but not allowing it to overlap any part of the world. The world is made up of lots of Rectangle instances. The player's body is also an instance of Rectangle. Would it be easier to rewrite the collisions using Box2D? What I've tried is checking if the player overlaps any rectangles when it's moved, and if it will, not moving it.
But this doesn't seem to take everything into account - sometimes it works, but other times, it stops before touching the world.

TL;DR: I want to make collisions of my player with a world which is stored as a grid of rectangles. How would I do this, as my player is also a Rectangle. Would it be easier to use Box2D?


Solution

  • This answer gives a good overview about the details of collision detection: https://gamedev.stackexchange.com/a/26506

    However, that might be a bit overwhelming if you just want to get a simple game going. Does your game loop happen in fixed interval or is it dependent on the framerate? Maybe you could solve a part of your issue by simply dividing the collision detection into more steps. Instead of moving the full way during one update, you could make 10 little updates that each move you only a 10th of the distance. Then you do a collision check after each step, so it's less likely that you stop too early or move through thin objects.

    That would of course be more taxing on the performance, but it's a naive and easy to implement approach to a solution.

    EDIT: Just wrap the position update in a for loop. I don't know how your code for collision checking and updating, but the general structure would be something like

    for (int i = 0; i < 10; i++) {
        newPosX += deltaX * 0.1; // 1/10th of the usual update
        newPosY += deltaY * 0.1; // 1/10th of the usual update
        if (checkCollision(newPosX, newPosY))
        {
            posX = newPosX;
            posY = newPosY;
        }
        else
        {
            break; // We hit something, no more mini-updates necessary.
        }
    }