简体   繁体   中英

Java 2D Platformer Gravity

I am currently making a 2D Platformer in Java. I am a beginner so take it easy. I have a problem with the gravity in the game. I am using different variables for falling and jumping. I am using a tiled map. So lets get to the point. My fall method works like this -

if(collisionDown == false) {
    characterY += fall;
    fall ++;
{

fall is equal to 4. and If collisionDown is true it resets back to 4.

My jump method is almost the same:

if(key.E == true && collisionDown == true) {
   characterY -= jump;
   jump --;
}

jump is equal to 16. and If collisonDown is true it resets back to 16.

Now problem is: imagine the character is jumping. its in the air and while going down characterY += fall; lets say characterY = 250 and fall is equal - 15 at that exact moment. The next solid tile below the character starts at Y position 255. character is at 250 and does NOT detect collision so next frame it adds 15 to characterY which is 250 + 15 = 265. At that point the character has "entered" the solid tile which was at positionY 255.

I have "fixed" that so the character gets back ON TOP of the solid tile (and that is visible and annoying.) That is not the perfect solution because it slows the character 1 frame each time it enters a solid tile(which is because it detects left and right collision and the character can't move). The character visibly stutters if I can say it like that.

I need a solution for that problem but can't think of any. So if you make a suggestion I would be happy. Thank you.

The way I usually handle this, is to pre-check movement:

private int moveDown(int fall){
        if (isSolidBlock(characterX, characterY + fall)){
            //Knowing the height of your block, calculate some kind of reduction. If your block height is 40, it's probably something like (characterY + fall)%40
            fall = 4;
            collisionDown = true;
            return maxFallUntilSolidBlockReached();
        }
        fall++;
        return fall;
    }

private boolean isSolidBlock(int x, int y){
        //Implement some kind of check if at (x,y) there's a solid block.
    }

Then just do this for the fall calculation:

if(collisionDown == false) {
            characterY += moveDown(fall);
        }

I would probably use something like the following.

if(collisionDown == false) {
    characterYnext = characterY + fall;          //Get Next Position
    if(NextMovementCollides()){                  //Basically if next position is too far. 
    characterYnext += difference_between(CharacterY,Ground);     //This should move the character to the ground state.
    fall = 0;                                                   //No longer falling so reset the value.
    }
    else{characterY += fall; fall++;}       //Otherwise continue falling like normal.
}

DISCLAIMER: I'm not a java programmer so my syntax might be a bit off.

This should work, just plug in your game logic where it would make sense.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM