package pathgame.gameplay; import java.util.Iterator; import java.util.LinkedList; import pathgame.tilemap.Tile; import pathgame.tilemap.TileMap; import pathgame.tilemap.Tiles; public class Player { private static final float SPEED = 0.125f; private PlayerAbilities abilities = PlayerAbilities.NORMAL; private float lastX = 0; private float lastY = 0; private float x = 0; private float y = 0; private float velX = 0; private float velY = 0; private boolean isMoving = false; private int currSpeedSlowdown = 1; private int energySupply; private int energyUsed = 0; private int objectivesAmount; private int objectivesVisited = 0; private final LinkedList steps = new LinkedList<>(); private Tile currentTile;// = Tiles.GRASS; public Player() { } public float getLastX() { return lastX; } public float getLastY() { return lastY; } public float getX() { return x; } public float getY() { return y; } private void tickSteps() { Iterator iter = steps.iterator(); while(iter.hasNext()) { MinusStepsValues next = iter.next(); if(next.tick()) { iter.remove(); } } } public void tick(TileMap map) { tickSteps(); int currentTileX = Math.round(x); int currentTileY = Math.round(y); //TODO: Bug beheben: Exception, wenn Spieler sofort an den unteren Levelrand geht (auch am rechten Levelrand) //ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 10 //System.out.println(currentTileY); //currentTile = Tiles.GRASS; currentTile = map.getTile(currentTileX, currentTileY); //System.out.println(currentTile); currSpeedSlowdown = currentTile.getEnergyCost(abilities); lastX = x; lastY = y; if(isOnTile()) { velX = 0.0f; velY = 0.0f; if(isMoving) { currentTile.onEnter(this, map, currentTileX, currentTileY); steps.addLast(new MinusStepsValues(currSpeedSlowdown)); energyUsed += currSpeedSlowdown; } isMoving = false; } if(Keys.LEFT_KEY.isDown() && !isMoving && x > 0 && !map.getTile(currentTileX - 1, currentTileY).isBlockingMovement()) { velX = -SPEED; isMoving = true; currentTile.onLeave(this, map, currentTileX, currentTileY); } else if(Keys.RIGHT_KEY.isDown() && !isMoving && x < map.getWidth() - 1 && !map.getTile(currentTileX + 1, currentTileY).isBlockingMovement()) { velX = SPEED; isMoving = true; currentTile.onLeave(this, map, currentTileX, currentTileY); } else if(Keys.UP_KEY.isDown() && !isMoving && y > 0 && !map.getTile(currentTileX, currentTileY - 1).isBlockingMovement()) { velY = -SPEED; isMoving = true; currentTile.onLeave(this, map, currentTileX, currentTileY); } else if(Keys.DOWN_KEY.isDown() && !isMoving && y < map.getHeight() - 1 && !map.getTile(currentTileX, currentTileY + 1).isBlockingMovement()) { velY = SPEED; isMoving = true; currentTile.onLeave(this, map, currentTileX, currentTileY); } float moveX = Math.abs(velX / currSpeedSlowdown); float moveY = Math.abs(velY / currSpeedSlowdown); if(velX < 0.0f) { float d = x - (float) Math.floor(x); if(d < 0.01f) { d = 1.0f; } moveX = -Math.min(moveX, d); } else if(velX > 0.0f) { float d = (float) Math.ceil(x) - x; if(d < 0.01f) { d = 1.0f; } moveX = Math.min(moveX, d); } else if(velY < 0.0f) { float d = y - (float) Math.floor(y); if(d < 0.01f) { d = 1.0f; } moveY = -Math.min(moveY, d); } else if(velY > 0.0f) { float d = (float) Math.ceil(y) - y; if(d < 0.01f) { d = 1.0f; } moveY = Math.min(moveY, d); } x += moveX; y += moveY; } private boolean isOnTile() { return Math.abs(x - Math.round(x)) < 0.01f && Math.abs(y - Math.round(y)) < 0.01f; } public float getVelX() { return velX; } public float getVelY() { return velY; } public int getEnergySupply() { return energySupply; } public int getEnergyLeft() { return energySupply - energyUsed; } public int getEnergyUsed() { return energyUsed; } public int getObjectivesAmount() { return objectivesAmount; } public void setObjectivesAmount(int objectivesAmount) { this.objectivesAmount = objectivesAmount; } public int getObjectivesVisited() { return objectivesVisited; } public void visitTown() { objectivesVisited++; } public LinkedList getLastSteps() { return steps; } public void setAbilities(PlayerAbilities playerAbilities) { abilities = playerAbilities; } public PlayerAbilities getAbilities() { return abilities; } public void setEnergySupply(int energySupply) { this.energySupply = energySupply; } public boolean hasWon() { return objectivesVisited >= objectivesAmount; } public boolean hasLost() { return energyUsed >= energySupply; } public void reset(int energySupply, int objectivesAmount, PlayerAbilities abilities) { lastX = 0; lastY = 0; x = 0; y = 0; velX = 0; velY = 0; isMoving = false; currSpeedSlowdown = 1; energyUsed = 0; objectivesVisited = 0; steps.clear(); this.energySupply = energySupply; this.objectivesAmount = objectivesAmount; this.abilities = abilities; } public void reset() { reset(1000, 10, PlayerAbilities.NORMAL); } public boolean isMoving() { return isMoving; } public Tile getCurrTile() { return currentTile; } }