0
\$\begingroup\$

The player go's throe walls and stops when theres no wall. Code:

package input;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.math.Vector2;

import dungeon.Dungeon;
import player.PlayerCharacter;
import player.Player_state;

public class PlayerInputProcessor {
private PlayerCharacter player;
private Dungeon dungeon;

private final int NORTH = 0, SOUTH = 1, WEST = 2, EAST = 3;

public PlayerInputProcessor(PlayerCharacter player, Dungeon dungeon) {
    this.player = player;
    this.dungeon = dungeon;
}

public void HandleInput() {
    Vector2 pos = player.getVectorPos();

    if(Gdx.input.isKeyPressed(Keys.UP)) {
        if(canmovethere(new GridPoint2( (int) player.getVectorPosX() / player.getWidth(), (int) (player.getVectorPosY() - 3) / player.getHight()), NORTH)) {
            player.setVectorPosY(player.getVectorPosY() + 3);
        }
    } 
     if(Gdx.input.isKeyPressed(Keys.DOWN)) {
        if(canmovethere(new GridPoint2( (int) player.getVectorPosX() / player.getWidth(), (int) (player.getVectorPosY() - 3) / player.getHight()), SOUTH)) {
            player.setVectorPosY(player.getVectorPosY() - 3);
            player.setState(Player_state.WALKING_FORWORD);
        }
    }
     if(Gdx.input.isKeyPressed(Keys.RIGHT)) {
         if(canmovethere(new GridPoint2( (int) (player.getVectorPosX() + 3) / player.getWidth(), (int) player.getVectorPosY() / player.getHight()), EAST)) {
            player.setVectorPosX(player.getVectorPosX() + 3);
        }
    } 
     if(Gdx.input.isKeyPressed(Keys.LEFT)) {
         if(canmovethere(new GridPoint2( (int) (player.getVectorPosX() - 3) / player.getWidth(), (int) player.getVectorPosY() / player.getHight()), WEST)) {
            player.setVectorPosX(player.getVectorPosX() - 3);
        }
    } 

    if(Gdx.input.isKeyJustPressed(Keys.E)) {
        if(player.hasSword()) {
            player.sword = false;
        }
        else player.sword = true;
    }


     player.setGridPos(new GridPoint2((int) player.getVectorPosX() / player.getWidth(),(int) player.getVectorPosY() / player.getHight()));

}
private Boolean canmovethere(GridPoint2 newpos, int die) {
    GridPoint2 nextpos = new GridPoint2();
    GridPoint2 nextpos2 = new GridPoint2();

    if(die == NORTH) {
        nextpos.x = newpos.x;
        nextpos.y = newpos.y + 1;
        nextpos2.x = newpos.x;
        nextpos2.y = newpos.y + 1;
        if(dungeon.getTile(nextpos).isPassable()) {
            return true;
        }
    }
    if(die == SOUTH) {
        nextpos.x = newpos.x;
        nextpos.y = newpos.y;
        nextpos2.x = newpos.x + 1;
        nextpos2.y = newpos.y;
        if(dungeon.getTile(nextpos).isPassable()) {
            return true;
        }
    }
    if(die == EAST) {
        nextpos.x = newpos.x + 1;
        nextpos.y = newpos.y;
        nextpos2.x = newpos.x;
        nextpos2.y = newpos.y + 1;
        if(dungeon.getTile(nextpos).isPassable() && dungeon.getTile(nextpos2).isPassable()) {
            return true;
        }
    }
    if(die == WEST) {
        nextpos.x = newpos.x;
        nextpos.y = newpos.y;
        nextpos2.x = newpos.x;
        nextpos2.y = newpos.y - 1;
        if(dungeon.getTile(nextpos).isPassable()) {
            return true;
        }
    }
    player.setState(Player_state.STANDING);
    return false;
 }
}
\$\endgroup\$
2
  • \$\begingroup\$ You will probably have better luck if you clearly state your question. \$\endgroup\$
    – Tashus
    Nov 27, 2017 at 23:48
  • \$\begingroup\$ "The player go's throe walls and stops when theres no wall." I need help. I can't fix it myself. \$\endgroup\$ Nov 28, 2017 at 0:11

1 Answer 1

0
\$\begingroup\$

I feel like your player's location should be based on your underlying data structure. The division you are doing to get the next tile location has me a little worried about what cell you are actually looking at for next tile.

If Dungeon is all in integer values for tile locations (which makes sense), you are almost certainly having integer math problems when you are trying to find the next tile. It's hard to tell without the implementation of Dungeon included in your question.

If I were you, I would consider flipping your data around and having your player position be solid integers, so you always know exactly what tile your player is supposed to be at, and doing math to figure out where the player should render on screen.

But my gut feeling is that this all boils down to integer math rounding -- I'd be able to update this answer if you post your Dungeon code so I can get a better idea of how this is all playing together.

Edit:

There are a lot of what look to be copy/paste errors in your canMoveThere function.

1) You are setting nextpos2 in all 4 cases, but only using it in the EAST case. (Are you sure you only want to move east if both nextpos and nextpos2 are passable?)

2) You are incorrectly setting the coordinates on nextpos in most of your situations. - NORTH looks ok - SOUTH is only incrementing the x on newpos2 and not touching nextpos - EAST is modifying both x and y, as well as being the only case that checks isPassable() for both nextpos and nextpos2 - WEST is only incrementing y on newpos2 and not touching nextpos

The problem is certainly in the logic of canmovethere. I believe your function should look more like this:

private Boolean canmovethere(GridPoint2 newpos, int die) {
    GridPoint2 nextpos = new GridPoint2();

    if(die == NORTH) {
        nextpos.x = newpos.x;
        nextpos.y = newpos.y + 1;
        if(dungeon.getTile(nextpos).isPassable()) {
            return true;
        }
    }
    if(die == SOUTH) {
        nextpos.x = newpos.x;
        nextpos.y = newpos.y - 1;
        if(dungeon.getTile(nextpos).isPassable()) {
            return true;
        }
    }
    if(die == EAST) {
        nextpos.x = newpos.x + 1;
        nextpos.y = newpos.y;
        if(dungeon.getTile(nextpos).isPassable()) {
            return true;
        }
    }
    if(die == WEST) {
        nextpos.x = newpos.x - 1;
        nextpos.y = newpos.y;
        if(dungeon.getTile(nextpos).isPassable()) {
            return true;
        }
    }
    player.setState(Player_state.STANDING);
    return false;
}

I removed nextpos2 as it was only used in the EAST case, and seemed unneeded. If you indeed intended for east to behave differently, just add that back in and make sure you are adjusting the correct values.

Edit 2:

There is another copy/paste error in your south logic, it looks like you have a minus where you should have a plus. Note the - 3 in both the UP and DOWN call to canmovethere():

if(Gdx.input.isKeyPressed(Keys.UP)) {
    if(canmovethere(new GridPoint2( (int) player.getVectorPosX() / player.getWidth(), (int) (player.getVectorPosY() - 3) / player.getHight()), NORTH)) {
        player.setVectorPosY(player.getVectorPosY() + 3);
    }
} 
 if(Gdx.input.isKeyPressed(Keys.DOWN)) {
    if(canmovethere(new GridPoint2( (int) player.getVectorPosX() / player.getWidth(), (int) (player.getVectorPosY() - 3) / player.getHight()), SOUTH)) {
        player.setVectorPosY(player.getVectorPosY() - 3);
        player.setState(Player_state.WALKING_FORWORD);
    }
}

I think one piece that is contributing to the confusion after looking at this more and more: You seem to be accounting for the direction the player is trying to move twice. Once in the call to canmovethere():

if(Gdx.input.isKeyPressed(Keys.UP)) {
    if(canmovethere(new GridPoint2( (int) player.getVectorPosX() / player.getWidth(), (int) (player.getVectorPosY() - 3) / player.getHight()), NORTH)) {
        player.setVectorPosY(player.getVectorPosY() + 3);
    }
} 

(Noting the (int) (player.getVectorPosY() - 3) specifically)

and once inside the canmovethere() function:

if(die == NORTH) {
        nextpos.x = newpos.x;
        nextpos.y = newpos.y + 1;
        nextpos2.x = newpos.x;
        nextpos2.y = newpos.y + 1;
        if(dungeon.getTile(nextpos).isPassable()) {
            return true;
        }
    }

(Where you are again adjusting the y position.)

You should certainly simplify this so that you only adjust the position on one side of the call. Since you currently pass a direction into your canmovethere function, you might as well do it there. You can probably reduce your code to look something like this:

if(Gdx.input.isKeyPressed(Keys.UP)) {
    if(canmovethere(new GridPoint2( (int) player.getVectorPosX() / player.getWidth(), (int) player.getVectorPosY() / player.getHight()), NORTH)) {
        player.setVectorPosY(player.getVectorPosY() + 3);
    }
} 
 if(Gdx.input.isKeyPressed(Keys.DOWN)) {
    if(canmovethere(new GridPoint2( (int) player.getVectorPosX() / player.getWidth(), (int) player.getVectorPosY() / player.getHight()), SOUTH)) {
        player.setVectorPosY(player.getVectorPosY() - 3);
        player.setState(Player_state.WALKING_FORWORD);
    }
}
 if(Gdx.input.isKeyPressed(Keys.RIGHT)) {
     if(canmovethere(new GridPoint2( (int) player.getVectorPosX() / player.getWidth(), (int) player.getVectorPosY() / player.getHight()), EAST)) {
        player.setVectorPosX(player.getVectorPosX() + 3);
    }
} 
 if(Gdx.input.isKeyPressed(Keys.LEFT)) {
     if(canmovethere(new GridPoint2( (int) (player.getVectorPosX() / player.getWidth()), (int) (player.getVectorPosY() / player.getHight()), WEST)) {
        player.setVectorPosX(player.getVectorPosX() - 3);
    }
} 

The arguments for canmovethere() should be changed to canmovethere(GridPoint2 currentPos, int direction). You pass in your current position and what direction you are wanting to move, and the function returns true or false if you are able to do that.

Also worth noting is that you are only setting the player state to WALKING_FORWARD in your DOWN case. Not sure if this is intentional or not.

\$\endgroup\$
6
  • \$\begingroup\$ I don't want the player to be tide to a tile for position. btw i'm using GridPoint2 for tile pos. \$\endgroup\$ Nov 28, 2017 at 20:58
  • \$\begingroup\$ @ThePumkinMelon I've updated my answer with a much more thorough analysis of the code you posted. Also, I didn't realize that GridPoint2 was a thing. I will be using that in the future. I had assumed it was a class you wrote. \$\endgroup\$
    – LAMonday
    Nov 29, 2017 at 5:06
  • \$\begingroup\$ Your fix did not work for me. And i was debuging and i got rid of all but EAST's nextpos2 check less code. \$\endgroup\$ Nov 29, 2017 at 22:09
  • \$\begingroup\$ Can you explain what you are seeing with my suggested code? Same exact problem, or are you seeing new incorrect behavior? \$\endgroup\$
    – LAMonday
    Nov 30, 2017 at 5:16
  • \$\begingroup\$ Your fix works for NORTH and EAST but when going WEST or SOUTH the player stops one tile before it is suppoed too. \$\endgroup\$ Nov 30, 2017 at 14:15

You must log in to answer this question.

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