Significant amount of refactoring:

- Removed several mode timer variables and implemented a GameMode enum w/
associated timer.
- Removed individual chase/scatter timer, replace with single timer
- Hopefully made level/round initializing methods more coherent
This commit is contained in:
Matt Low 2020-01-05 02:34:30 +04:00
parent ecaf86a57a
commit 389533d394
2 changed files with 230 additions and 204 deletions

View File

@ -117,10 +117,11 @@ public class Ghost extends MovableEntity {
return; return;
} }
if (!(currentBehaviour instanceof FrightenedBehaviour || currentBehaviour instanceof ReturnToBase)) { if (currentBehaviour == chaseBehaviour && state.scatter) {
if ((currentBehaviour == chaseBehaviour && !state.chase) || (currentBehaviour == scatterBehaviour && state.chase)) { setNextDirection(currDirection.getOpposite());
updateBehaviour();
} else if (currentBehaviour == scatterBehaviour && !state.scatter) {
setNextDirection(currDirection.getOpposite()); setNextDirection(currDirection.getOpposite());
}
updateBehaviour(); updateBehaviour();
} }
@ -198,7 +199,7 @@ public class Ghost extends MovableEntity {
if (state.frightTimer > 0 && !caught) { if (state.frightTimer > 0 && !caught) {
currentBehaviour = frightBehaviour; currentBehaviour = frightBehaviour;
} else { } else {
currentBehaviour = state.chase ? chaseBehaviour : scatterBehaviour; currentBehaviour = state.scatter ? scatterBehaviour : chaseBehaviour;
} }
} }

View File

@ -35,16 +35,15 @@ public class PlayState extends LevelState {
}; };
private Texture levelBackground, winBackground; private Texture levelBackground, winBackground;
private BitmapFont font;
private TextureRegion lifeSprite; private TextureRegion lifeSprite;
private BitmapFont font;
public Random random; public Random random;
private long sirenId; private long sirenId;
private int pelletCount; private int pelletCount;
private int pelletEatenCount; private int pelletsEaten;
public int pelletsEatenSinceDeath; public int pelletsEatenSinceDeath;
public boolean pelletsEatenSinceDeathCounterEnabled; public boolean pelletsEatenSinceDeathCounterEnabled;
@ -54,24 +53,17 @@ public class PlayState extends LevelState {
private int round; private int round;
private boolean paused = false; private boolean paused = false;
private float readyTimer; private float modeTimer;
private float gameOverTimer; private GameState mode;
private float newGameTimer;
private float deathTimer;
private float pointsTimer;
private float roundClearedTimer;
public float frightTimer;
public float secondsSinceLastDot; public float secondsSinceLastDot;
private float chaseTimer; public boolean scatter;
private float scatterTimer;
private int scatterCount; private int scatterCount;
private float scatterChaseTimer;
public boolean chase; public float frightTimer; // remaining fright time
private int ghostsCaught; // number of ghosts caught since last power pellet
private boolean pacmanCaught;
private int ghostsCaught;
private Ghost lastGhostCaptured; private Ghost lastGhostCaptured;
public Pacman pacman; public Pacman pacman;
@ -89,7 +81,8 @@ public class PlayState extends LevelState {
lifeSprite = game.assets.pacman[2][1]; lifeSprite = game.assets.pacman[2][1];
Gdx.input.setInputProcessor(new Controller()); Gdx.input.setInputProcessor(new Controller());
newGame(); preNewGame();
setGameState(GameState.PRE_NEW_GAME);
} }
@Override @Override
@ -102,42 +95,52 @@ public class PlayState extends LevelState {
game.batch.draw(lifeSprite, i * 16, 0); game.batch.draw(lifeSprite, i * 16, 0);
} }
if (pointsTimer > 0) { if (mode == GameState.GHOST_CAUGHT_POINTS_WAIT) {
game.batch.draw(game.assets.points[0][ghostsCaught-1], (lastGhostCaptured.pos.x * 8) - 8, (lastGhostCaptured.pos.y * 8) + 8); game.batch.draw(game.assets.points[0][ghostsCaught-1], (lastGhostCaptured.pos.x * 8) - 8, (lastGhostCaptured.pos.y * 8) + 8);
} else { } else {
pacman.render(game.batch, 0, 16); pacman.render(game.batch, 0, 16);
} }
if (roundClearedTimer > 0 && roundClearedTimer <= 2) { if (mode == GameState.ROUND_WON) {
// draw flashing level background // draw flashing level background
game.batch.draw((int) (roundClearedTimer * 4) % 2 == 0? levelBackground : winBackground, 0, 16); game.batch.draw((int) (modeTimer * 4) % 2 == 0? levelBackground : winBackground, 0, 16);
return; return;
} else { } else {
game.batch.draw(levelBackground, 0, 16); game.batch.draw(levelBackground, 0, 16);
} }
if (pacman.alive && newGameTimer <= 0) { switch (mode) {
case PRE_NEW_GAME:
case PACMAN_CAUGHT:
case ROUND_WON:
case GAME_OVER:
break;
default:
for (Ghost ghost : ghosts) { for (Ghost ghost : ghosts) {
if (pointsTimer > 0 && ghost == lastGhostCaptured) { if (mode == GameState.GHOST_CAUGHT_POINTS_WAIT && ghost == lastGhostCaptured) {
continue; game.batch.draw(game.assets.points[0][ghostsCaught - 1], (ghost.pos.x * 8) - 8, (ghost.pos.y * 8) + 8);
} } else {
ghost.render(game.batch, 0, 16); ghost.render(game.batch, 0, 16);
} }
} }
if (readyTimer > 0) {
game.assets.getFont().setColor(Color.YELLOW);
game.assets.getFont().draw(game.batch, "ready!", 92, 127);
}
if (gameOverTimer > 0) {
game.assets.getFont().setColor(Color.RED);
game.assets.getFont().draw(game.batch, "game over", 78, 127);
} }
if (paused) { if (paused) {
game.assets.getFont().setColor(Color.YELLOW); game.assets.getFont().setColor(Color.YELLOW);
game.assets.getFont().draw(game.batch, "paused", 90, 151); game.assets.getFont().draw(game.batch, "paused", 90, 151);
} else {
switch (mode) {
case PRE_NEW_GAME:
case NEW_ROUND_WAIT:
case START_ROUND_WAIT:
game.assets.getFont().setColor(Color.YELLOW);
game.assets.getFont().draw(game.batch, "ready!", 92, 127);
break;
case GAME_OVER:
game.assets.getFont().setColor(Color.RED);
game.assets.getFont().draw(game.batch, "game over", 78, 127);
break;
}
} }
} }
@ -152,45 +155,20 @@ public class PlayState extends LevelState {
dt = 1/60f; dt = 1/60f;
} }
pointsTimer -= dt; switch (mode) {
if (pointsTimer > 0) { case PLAYING:
return; if (frightTimer <= 0) {
} if (scatter || scatterCount < 4) {
scatterChaseTimer -= dt;
if (roundClearedTimer > 0) { if (scatterChaseTimer <= 0) {
roundClearedTimer -= dt; scatter = !scatter;
if (roundClearedTimer <= 0) { scatterChaseTimer = scatter ? 7f : 20f;
newRound(); if (scatter) {
} scatterCount++;
return;
}
if (gameOverTimer > 0) {
gameOverTimer -= dt;
if (gameOverTimer <= 0) {
newGame();
}
return;
}
if (readyTimer > 0) {
readyTimer -= dt;
if (readyTimer <= 0) {
startGame();
} else if (newGameTimer <= 0) {
return;
} }
} }
if (newGameTimer > 0) {
newGameTimer -= dt;
if (newGameTimer <= 0) {
setupGame();
} }
return; } else {
}
if (frightTimer > 0) {
frightTimer -= dt; frightTimer -= dt;
if (frightTimer <= 0) { if (frightTimer <= 0) {
for (Ghost ghost : ghosts) { for (Ghost ghost : ghosts) {
@ -199,24 +177,6 @@ public class PlayState extends LevelState {
ghost.currentBehaviour = ghost.chaseBehaviour; ghost.currentBehaviour = ghost.chaseBehaviour;
} }
} }
} else {
// pause chase/scatter timer when frightened
if (scatterTimer > 0) {
scatterTimer -= dt;
if (scatterTimer <= 0) {
chase = true;
if (scatterCount < 4) {
chaseTimer = 20f;
}
}
} else if (chaseTimer > 0) {
chaseTimer -= dt;
if (chaseTimer <= 0) {
chase = false;
scatterTimer = 7f;
scatterCount++;
}
}
} }
secondsSinceLastDot += dt; secondsSinceLastDot += dt;
@ -233,100 +193,137 @@ public class PlayState extends LevelState {
} }
} }
if (!pacmanCaught) { pacman.update(dt);
for (Ghost ghost : ghosts) { for (Ghost ghost : ghosts) {
ghost.update(dt); ghost.update(dt);
if (ghost.onSameTile(pacman)) { if (ghost.onSameTile(pacman)) {
if (frightTimer > 0 && !ghost.caught) { if (frightTimer > 0 && !ghost.caught) {
ghostCaught(ghost); ghostCaught(ghost);
} else if (frightTimer <= 0 || !(ghost.currentBehaviour instanceof ReturnToBase)) { continue;
}
if (!(ghost.currentBehaviour instanceof ReturnToBase)) {
pacmanCaught(); pacmanCaught();
return; return;
} }
} }
} }
} else if (deathTimer <= 0) { break;
if (pacman.alive) { case PACMAN_CAUGHT:
game.assets.deathSound.play(1f); pacman.update(dt);
}
pacman.alive = false;
if (pacman.deathFrame == 13) { if (pacman.deathFrame == 13) {
if (lives > 0) { if (lives > 0) {
setupGame(); resetField();
readyTimer = 2f; setGameState(GameState.START_ROUND_WAIT);
} else { } else {
gameOverTimer = 2f; setGameState(GameState.GAME_OVER);
} }
} }
} else { break;
deathTimer -= dt; default:
modeTimer -= dt;
if (modeTimer <= 0) {
modeTransition();
}
break;
}
} }
pacman.update(dt); public void modeTransition() {
switch (mode) {
// The mode we're transitioning /from/
case PRE_NEW_GAME:
newGame();
setGameState(GameState.START_ROUND_WAIT);
break;
case START_ROUND_WAIT:
case NEW_ROUND_WAIT:
startGame();
setGameState(GameState.PLAYING);
break;
case ROUND_WON_WAIT:
setGameState(GameState.ROUND_WON);
break;
case ROUND_WON:
newRound();
setGameState(GameState.NEW_ROUND_WAIT);
break;
case GAME_OVER:
preNewGame();
setGameState(GameState.PRE_NEW_GAME);
break;
case GHOST_CAUGHT_POINTS_WAIT:
setGameState(GameState.PLAYING);
break;
case PACMAN_CAUGHT_WAIT:
game.assets.deathSound.play(1f);
pacman.alive = false;
setGameState(GameState.PACMAN_CAUGHT);
break;
}
} }
public void initializeField() { public void initializeLevel() {
level = new Level(game,"level");
pelletCount = level.getTileCount(LevelTile.PELLET) + level.getTileCount(LevelTile.POWER_PELLET);
pacman = new Pacman(this, false);
}
public void initializeRound() {
scatter = true;
scatterCount = 1;
pelletsEaten = 0;
pelletsEatenSinceDeath = 0;
pelletsEatenSinceDeathCounterEnabled = false;
spawnGhosts();
}
public void resetField() {
lives--;
frightTimer = 0f; frightTimer = 0f;
deathTimer = 0f;
pacmanCaught = false;
ghostsCaught = 0; ghostsCaught = 0;
lastGhostCaptured = null; lastGhostCaptured = null;
secondsSinceLastDot = 0; secondsSinceLastDot = 0;
if (chase) { scatterChaseTimer = scatter? 7f : 20f;
chaseTimer = 20f;
} else {
scatterTimer = 7f;
}
random = new Random(897198256012865L); random = new Random(897198256012865L);
pacman = new Pacman(this, false); pacman = new Pacman(this, false);
resetGhosts();
}
public void preNewGame() {
score = 0;
lives = 3;
round = 1;
initializeLevel();
game.assets.beginning.play(1.0f);
} }
public void newGame() { public void newGame() {
pelletCount = 0; initializeRound();
pelletEatenCount = 0; resetField();
score = 0;
lives = 3;
round = 0;
newGameTimer = 2.3f;
newRound();
} }
public void newRound() { public void newRound() {
initializeLevel();
initializeRound();
resetField();
round++; round++;
level = new Level(game,"level");
pelletCount = level.getTileCount(LevelTile.PELLET);
pelletCount += level.getTileCount(LevelTile.POWER_PELLET);
pelletsEatenSinceDeath = 0;
pelletsEatenSinceDeathCounterEnabled = false;
initializeField();
spawnGhosts();
chase = false;
scatterCount = 1;
game.assets.siren.stop(sirenId); game.assets.siren.stop(sirenId);
if (round == 1) {
readyTimer = 4.2f;
game.assets.beginning_alt.play(1.0f); game.assets.beginning_alt.play(1.0f);
} else {
readyTimer = 4.3f;
game.assets.beginning.play(1.0f);
}
} }
public void setupGame() { public void startGame() {
lives--; sirenId = game.assets.siren.loop(1.0f);
initializeField(); pacman.moving = true;
resetGhosts();
} }
private void spawnGhosts() { private void spawnGhosts() {
@ -337,30 +334,26 @@ public class PlayState extends LevelState {
ghosts[3] = new Clyde(this, new Vector2(GHOST_SPAWN_POINTS[3]), GHOST_SPAWN_DIRS[3]); ghosts[3] = new Clyde(this, new Vector2(GHOST_SPAWN_POINTS[3]), GHOST_SPAWN_DIRS[3]);
} }
public void startGame() {
pacman.moving = true;
sirenId = game.assets.siren.loop(1.0f);
}
public void resetGhosts() { public void resetGhosts() {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
if (ghosts[i] == null) continue; if (ghosts[i] == null) continue;
ghosts[i].pos = new Vector2(GHOST_SPAWN_POINTS[i]); ghosts[i].pos = new Vector2(GHOST_SPAWN_POINTS[i]);
ghosts[i].currDirection = GHOST_SPAWN_DIRS[i]; ghosts[i].currDirection = GHOST_SPAWN_DIRS[i];
ghosts[i].currentBehaviour = chase? ghosts[i].chaseBehaviour : ghosts[i].scatterBehaviour;
ghosts[i].currentPath = null; ghosts[i].currentPath = null;
ghosts[i].caught = false;
ghosts[i].inHouse = i > 0; ghosts[i].inHouse = i > 0;
ghosts[i].updateBehaviour();
} }
} }
private void pelletEaten(float x, float y) { private void pelletEaten(float x, float y) {
level.setTile(x, y, LevelTile.EMPTY); level.setTile(x, y, LevelTile.EMPTY);
if (pelletEatenCount % 2 == 0) { if (pelletsEaten % 2 == 0) {
game.assets.chomp_1.play(1.0f); game.assets.chomp_1.play(1.0f);
} else { } else {
game.assets.chomp_2.play(1.0f); game.assets.chomp_2.play(1.0f);
} }
pelletEatenCount++; pelletsEaten++;
pelletCount--; pelletCount--;
if (pelletsEatenSinceDeathCounterEnabled) { if (pelletsEatenSinceDeathCounterEnabled) {
@ -381,7 +374,7 @@ public class PlayState extends LevelState {
secondsSinceLastDot = 0; secondsSinceLastDot = 0;
if (pelletCount == 0) { if (pelletCount == 0) {
roundClearedTimer = 3f; setGameState(GameState.ROUND_WON_WAIT);
} }
} }
@ -405,11 +398,11 @@ public class PlayState extends LevelState {
private void pacmanCaught() { private void pacmanCaught() {
game.assets.siren.stop(sirenId); game.assets.siren.stop(sirenId);
deathTimer = 1f;
pacmanCaught = true;
pacman.moving = false; pacman.moving = false;
pelletsEatenSinceDeath = 0; pelletsEatenSinceDeath = 0;
pelletsEatenSinceDeathCounterEnabled = true; pelletsEatenSinceDeathCounterEnabled = true;
setGameState(GameState.PACMAN_CAUGHT_WAIT);
} }
private void ghostCaught(Ghost ghost) { private void ghostCaught(Ghost ghost) {
@ -419,7 +412,8 @@ public class PlayState extends LevelState {
lastGhostCaptured = ghost; lastGhostCaptured = ghost;
ghostsCaught++; ghostsCaught++;
score += ghostsCaught * 200; score += ghostsCaught * 200;
pointsTimer = 1f;
setGameState(GameState.GHOST_CAUGHT_POINTS_WAIT);
} }
@Override @Override
@ -453,7 +447,7 @@ public class PlayState extends LevelState {
paused = !paused; paused = !paused;
break; break;
case Input.Keys.N: case Input.Keys.N:
newGame(); preNewGame();
break; break;
} }
return super.keyDown(keycode); return super.keyDown(keycode);
@ -461,4 +455,35 @@ public class PlayState extends LevelState {
} }
public enum GameState {
PRE_NEW_GAME(2.3f),
NEW_ROUND_WAIT(4.2f),
START_ROUND_WAIT(2f),
ROUND_WON_WAIT(1f),
ROUND_WON(2f),
PACMAN_CAUGHT,
PACMAN_CAUGHT_WAIT(1f),
GHOST_CAUGHT_POINTS_WAIT(1f),
GAME_OVER(2f),
PLAYING,
;
final float timer;
GameState(float timer) {
this.timer = timer;
}
GameState() {
this(0f);
}
}
public void setGameState(GameState mode) {
this.mode = mode;
this.modeTimer = mode.timer;
}
} }