5
\$\begingroup\$

With help from my last question, I was able to fix the issue of having a stuttering effect if you keep hitting jump, while jumping.

I believe I have managed to match moving on the X axis and the physics behind jumping, but I have ran into another hurdle. I'm hoping someone might be able to point out what I am missing.

At this point, the jump looks right, but the collision logic allows Megaman to pass through the floor and stop with his head just under the floor.

EX. Before: Before After: After

Any assistance would be greatly appreciated. I'm really exciting to be learning Libgdx. :)

Megaman.java

package com.mygdx.game;

import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer.Cell;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.Input.Keys;


public class Megaman extends Sprite implements InputProcessor
{
/**the movement velocity*/
private Vector2 velocity = new Vector2();

private float speed = 60 * 1.375f;

private float gravity = 0;
private float jumpV = 4.75f;
private static float GRAVITYCONST = -.25f;
private boolean canJump;
private boolean released;
private boolean movingX; 
private int movingLR = 1;
private boolean jumping;

private TiledMapTileLayer collisionLayer;

public Megaman(Sprite sprite, TiledMapTileLayer collisionLayer)
{
    super(sprite);
    this.collisionLayer = collisionLayer;

}

@Override
public void draw(Batch spriteBatch)
{
    update(Gdx.graphics.getDeltaTime());
    super.draw(spriteBatch);
}

public void update(float delta)
{
    // apply gravity
            setY(getY() + gravity);

            // clamp velocity
            if(gravity < -7.0f)
                gravity = -7.0f;

            // save old position
            float oldX = getX(), oldY = getY();
            boolean collisionX = false, collisionY = false;

            // move on x
            if(movingLR == -1) // going left
                collisionX = collidesLeft();
            else if(movingLR == 1) // going right
                collisionX = collidesRight();

            // react to x collision
            if((collisionX == false) && (movingX == true)) {
                if(movingLR == -1)
                {
                    setX(getX() - 1.375f);
                }
                else if(movingLR == 1)
                {
                    setX(getX() + 1.375f);
                }
            }               

            if(jumping == false){ // going down
                canJump = collidesBottom();
                collisionY = collidesBottom();
                released = collidesBottom();
            }else if(jumping == true) // going up
            {
                collisionY = collidesTop();
                setY(getY() + (jumpV += GRAVITYCONST));
            }



            // react to y collision
            if((collisionY == true) && (jumping = true)) {
                setY(oldY);
                jumpV = 4.75f;
            }
}

public Vector2 getVelocity() {
    return velocity;
}

public void setVelocity(Vector2 velocity) {
    this.velocity = velocity;
}

public float getSpeed() {
    return speed;
}

public void setSpeed(float speed) {
    this.speed = speed;
}

public float getGravity() {
    return gravity;
}

public void setGravity(float gravity) {
    this.gravity = gravity;
}

public TiledMapTileLayer getCollisionLayer() {
    return collisionLayer;
}

public void setCollisionLayer(TiledMapTileLayer collisionLayer) {
    this.collisionLayer = collisionLayer;
}

@Override
public boolean keyDown(int keycode) {
    switch (keycode)
    {
    case Keys.W:
        jumping = true;
        if(canJump) {
            canJump = false;
        }
        break;
    case Keys.A:
        //velocity.x = -speed;
        movingX = true;
        movingLR = -1;  //moving left
        break;
    case Keys.D:
        //velocity.x = speed;
        movingX = true;
        movingLR = 1;  //moving right
        break;
    }
    return true;
}

@Override
public boolean keyUp(int keycode) {
    switch (keycode)
    {
    case Keys.W:
        if (released == true)
        {
            //when W is released, set Y velocity to 0
            //velocity.y = 0;
            released = false;
            jumping = true;
        }
        break;
    case Keys.A:
    case Keys.D:
        //velocity.x = 0;
        movingX = false;
        break;
    }
    return true;
}

@Override
public boolean keyTyped(char character) {
    return false;
}

@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {

    return false;
}

@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
    return false;
}

@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
    return false;
}

@Override
public boolean mouseMoved(int screenX, int screenY) {
    return false;
}

@Override
public boolean scrolled(int amount) {
    return false;
}

private boolean isCellBlocked(float x, float y) {
    Cell cell = collisionLayer.getCell((int) (x / collisionLayer.getTileWidth()), (int) (y / collisionLayer.getTileHeight()));
    return cell != null && cell.getTile() != null && cell.getTile().getProperties().containsKey("blocked");
}

public boolean collidesRight() {
    for(float step = 0; step < getHeight(); step += collisionLayer.getTileHeight() / 2)
        if(isCellBlocked(getX() + getWidth(), getY() + step))
            return true;
    return false;
}

public boolean collidesLeft() {
    for(float step = 0; step < getHeight(); step += collisionLayer.getTileHeight() / 2)
        if(isCellBlocked(getX(), getY() + step))
            return true;
    return false;
}

public boolean collidesTop() {
    for(float step = 0; step < getWidth(); step += collisionLayer.getTileWidth() / 2)
        if(isCellBlocked(getX() + step, getY() + getHeight()))
            return true;
    return false;

}

public boolean collidesBottom() {
    for(float step = 0; step < getWidth(); step += collisionLayer.getTileWidth() / 2)
        if(isCellBlocked(getX() + step, getY()))
            return true;
    return false;
}   
}
\$\endgroup\$
3
  • \$\begingroup\$ Don't know libGDX, don't know Java, but tell me one thing, where are you setting jumping = false again? Atfer setting it true? I think thats why your collisionY has always collidesTop(). May be that is the reason. \$\endgroup\$ Feb 17 '16 at 5:33
  • \$\begingroup\$ You're absolutely right. I never set jumping to false so therefore, collidesDown() never triggers. I'm having difficulty figuring out where/how to change the code to fix it. I've tried a handful of changes, I fix the collision detection, but I get other ambiguous behavior.(EX jump motion only happens while jump button is held or once the jump button is pressed, megaman keeps jumping over and over again). \$\endgroup\$
    – John Vanek
    Feb 17 '16 at 17:35
  • \$\begingroup\$ try to add jumping = false; in this if check if((collisionY == true) && (jumping = true)) { setY(oldY); jumpV = 4.75f; } \$\endgroup\$ Feb 17 '16 at 20:19
1
\$\begingroup\$

It seems like your problem is here:

public boolean collidesBottom() {
    for(float step = 0; step < getWidth(); step += collisionLayer.getTileWidth() / 2)
        if(isCellBlocked(getX() + step, getY()))
            return true;
    return false;
}   

You only detect if the player has hit the floor when the cell inside of him is blocked. To fix this, change the code to:

public boolean collidesBottom() {
    for(float step = 0; step < getWidth(); step += collisionLayer.getTileWidth() / 2)
        if(isCellBlocked(getX() + step, getY() + playerHeight))
            return true;
    return false;
}   
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .