Implement FrightBehaviour
This took way too long.
This commit is contained in:
parent
75d0c41bb5
commit
afad1017a5
@ -8,6 +8,8 @@ import com.me.pacman.entity.ai.Target;
|
||||
import com.me.pacman.level.LevelTile;
|
||||
import com.me.pacman.state.PlayState;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Ghost extends MovableEntity {
|
||||
|
||||
public static final Direction[] GHOST_ORDER = { Direction.UP, Direction.LEFT, Direction.DOWN, Direction.RIGHT };
|
||||
@ -17,8 +19,8 @@ public class Ghost extends MovableEntity {
|
||||
public Behaviour currentBehaviour;
|
||||
|
||||
public Behaviour chaseBehaviour;
|
||||
public Behaviour freightBehaviour;
|
||||
public Behaviour scatterBehaviour;
|
||||
public Behaviour frightBehaviour;
|
||||
|
||||
public TextureRegion[][] sprite;
|
||||
|
||||
@ -26,13 +28,13 @@ public class Ghost extends MovableEntity {
|
||||
private int counter = 0;
|
||||
|
||||
public Ghost(PlayState state, float x, float y, Direction direction, int spriteIndex,
|
||||
Behaviour chaseBehaviour, Behaviour freightBehaviour, Behaviour scatterBehaviour) {
|
||||
Behaviour chaseBehaviour, Behaviour scatterBehaviour) {
|
||||
super(state, x, y, 7.03f, true, direction, 0.1f);
|
||||
this.state = state;
|
||||
this.spriteIndex = spriteIndex;
|
||||
this.chaseBehaviour = chaseBehaviour;
|
||||
this.freightBehaviour = freightBehaviour;
|
||||
this.scatterBehaviour = scatterBehaviour;
|
||||
this.frightBehaviour = new FrightenedBehaviour(state);
|
||||
sprite = state.getGame().assets.ghosts;
|
||||
}
|
||||
|
||||
@ -53,7 +55,7 @@ public class Ghost extends MovableEntity {
|
||||
public void update(float dt) {
|
||||
super.update(dt);
|
||||
|
||||
if (!state.paused && age % 20 == 0) {
|
||||
if (age % 20 == 0) {
|
||||
counter++;
|
||||
}
|
||||
|
||||
@ -66,16 +68,19 @@ public class Ghost extends MovableEntity {
|
||||
}
|
||||
|
||||
Target target = currentBehaviour.getTarget();
|
||||
Vector2 ahead = new Vector2((int) pos.x, (int) pos.y).add(currDirection.getVector());
|
||||
if (target == null) {
|
||||
// no target, carry on current course
|
||||
return;
|
||||
}
|
||||
|
||||
Direction bestDirection = null;
|
||||
Vector2 ahead = new Vector2((int) pos.x, (int) pos.y).add(currDirection.getVector());
|
||||
float shortest = Float.MAX_VALUE;
|
||||
Direction nextDirection = null;
|
||||
|
||||
for (Direction dir : GHOST_ORDER) {
|
||||
if (dir.isOpposite(currDirection)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Vector2 adjacent = dir.getVector().add(ahead);
|
||||
LevelTile nextTile = state.level.getTile(adjacent);
|
||||
if (nextTile != null && nextTile.isPassable()) {
|
||||
@ -83,14 +88,12 @@ public class Ghost extends MovableEntity {
|
||||
float d = target.distance_sqr(adjacent);
|
||||
if (d < shortest) {
|
||||
shortest = d;
|
||||
bestDirection = dir;
|
||||
nextDirection = dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bestDirection != null) {
|
||||
setNextDirection(bestDirection);
|
||||
}
|
||||
setNextDirection(nextDirection);
|
||||
}
|
||||
|
||||
private class ReturnToBase extends Behaviour {
|
||||
@ -108,4 +111,56 @@ public class Ghost extends MovableEntity {
|
||||
|
||||
}
|
||||
|
||||
private class FrightenedBehaviour extends Behaviour {
|
||||
|
||||
private Target target;
|
||||
|
||||
public FrightenedBehaviour(PlayState state) {
|
||||
super(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Target getTarget() {
|
||||
if (target != null && !target.targetReached(pos)) {
|
||||
return target;
|
||||
}
|
||||
|
||||
ArrayList<Vector2> adjacentTiles = new ArrayList<>(3);
|
||||
ArrayList<Direction> possibleTurns = new ArrayList<>(3);
|
||||
Vector2 ahead = new Vector2((int) pos.x, (int) pos.y).add(currDirection.getVector());
|
||||
|
||||
for (Direction dir : GHOST_ORDER) {
|
||||
if (dir.isOpposite(currDirection)) {
|
||||
// Don't consider going backwards
|
||||
continue;
|
||||
}
|
||||
Vector2 adjacent = dir.getVector().add(ahead);
|
||||
LevelTile nextTile = state.level.getTile(adjacent);
|
||||
if (nextTile != null && nextTile.isPassable()) {
|
||||
adjacentTiles.add(adjacent);
|
||||
possibleTurns.add(dir);
|
||||
}
|
||||
}
|
||||
|
||||
if (possibleTurns.size() == 0) {
|
||||
// No possible turns means no valid tiles ahead, which would be the tunnel.
|
||||
target = null;
|
||||
} else if (possibleTurns.size() == 1) {
|
||||
if (possibleTurns.get(0) == currDirection) {
|
||||
// can only go straight, so no target
|
||||
target = null;
|
||||
} else {
|
||||
// turn the only possible direction
|
||||
target = new Target(adjacentTiles.get(0));
|
||||
}
|
||||
} else {
|
||||
// n-way intersection, pick random direction
|
||||
int rand = state.random.nextInt(adjacentTiles.size());
|
||||
target = new Target(adjacentTiles.get(rand));
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -46,11 +46,11 @@ public class Pacman extends MovableEntity {
|
||||
|
||||
super.update(dt);
|
||||
|
||||
if (!state.paused && canMove && age % 4 == 0) {
|
||||
if (canMove && age % 4 == 0) {
|
||||
counter += 1;
|
||||
}
|
||||
|
||||
if (age % 8 == 0 && !alive) {
|
||||
if (!alive && age % 8 == 0) {
|
||||
deathFrame++;
|
||||
}
|
||||
|
||||
|
@ -32,4 +32,8 @@ public class Target {
|
||||
return this.x == (int) x && this.y == (int) y;
|
||||
}
|
||||
|
||||
public boolean targetReached(Vector2 vec) {
|
||||
return targetReached(vec.x, vec.y);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,17 +15,21 @@ import com.me.pacman.entity.ai.BlinkyChaseBehaviour;
|
||||
import com.me.pacman.level.Level;
|
||||
import com.me.pacman.level.LevelTile;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class PlayState extends LevelState {
|
||||
|
||||
private Texture levelBackground;
|
||||
private BitmapFont font;
|
||||
|
||||
private TextureRegion lifeSprite;
|
||||
|
||||
private int pelletCount;
|
||||
private int pelletEatenCount;
|
||||
private int score;
|
||||
private int lives;
|
||||
private int round;
|
||||
public boolean paused = false;
|
||||
private boolean paused = false;
|
||||
|
||||
private long sirenId;
|
||||
|
||||
@ -36,7 +40,7 @@ public class PlayState extends LevelState {
|
||||
|
||||
private boolean pacmanCaught;
|
||||
|
||||
private TextureRegion lifeSprite;
|
||||
public Random random;
|
||||
|
||||
public Pacman pacman;
|
||||
public Ghost[] ghosts;
|
||||
@ -90,7 +94,6 @@ public class PlayState extends LevelState {
|
||||
if (paused) {
|
||||
game.assets.getFont().setColor(Color.YELLOW);
|
||||
game.assets.getFont().draw(game.batch, "paused", 90, 151);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,6 +130,8 @@ public class PlayState extends LevelState {
|
||||
}
|
||||
}
|
||||
|
||||
dt = 1/60f;
|
||||
|
||||
if (!pacmanCaught) {
|
||||
for (Ghost ghost : ghosts) {
|
||||
if (ghost == null) {
|
||||
@ -184,7 +189,7 @@ public class PlayState extends LevelState {
|
||||
level = new Level(game,"level");
|
||||
|
||||
pacman = new Pacman(this, false);
|
||||
ghosts[0] = new Ghost(this, 14, 19.5f, Direction.LEFT, 0, new BlinkyChaseBehaviour(this), null, null);
|
||||
ghosts[0] = new Ghost(this, 14, 19.5f, Direction.LEFT, 0, new BlinkyChaseBehaviour(this), null);
|
||||
ghosts[0].currentBehaviour = ghosts[0].chaseBehaviour;
|
||||
|
||||
game.assets.siren.stop(sirenId);
|
||||
@ -205,8 +210,10 @@ public class PlayState extends LevelState {
|
||||
lives--;
|
||||
pacmanCaught = false;
|
||||
|
||||
random = new Random(897198256012865L);
|
||||
|
||||
pacman = new Pacman(this, false);
|
||||
ghosts[0] = new Ghost(this, 14, 19.5f, Direction.LEFT, 0, new BlinkyChaseBehaviour(this), null, null);
|
||||
ghosts[0] = new Ghost(this, 14, 19.5f, Direction.LEFT, 0, new BlinkyChaseBehaviour(this), null);
|
||||
ghosts[0].currentBehaviour = ghosts[0].chaseBehaviour;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user