diff --git a/core/src/com/me/pacman/entity/Blinky.java b/core/src/com/me/pacman/entity/Blinky.java index 2f02ccd..97c23c3 100644 --- a/core/src/com/me/pacman/entity/Blinky.java +++ b/core/src/com/me/pacman/entity/Blinky.java @@ -5,6 +5,7 @@ import com.me.pacman.PacDude; import com.me.pacman.entity.ai.BlinkyChaseBehaviour; import com.me.pacman.entity.ai.StaticTargetBehaviour; import com.me.pacman.entity.ai.Target; +import com.me.pacman.level.Modifiers; import com.me.pacman.state.PlayState; public class Blinky extends Ghost { @@ -15,6 +16,19 @@ public class Blinky extends Ghost { super(state, pos, direction, 0, new BlinkyChaseBehaviour(state), new StaticTargetBehaviour(state, SCATTER_TARGET), false); } + @Override + protected float getNormalSpeed() { + int round = state.round; + if (!state.hasDied || !state.ghosts[3].inHouse) { + if (state.pelletsRemaining <= Modifiers.getElroy2DotsLeft(round)) { + return Modifiers.getElroy2Speed(round); + } else if (state.pelletsRemaining <= Modifiers.getElroy1DotsLeft(round)) { + return Modifiers.getElroy1Speed(round); + } + } + return super.getNormalSpeed(); + } + @Override public void update(float dt) { if (inHouse) { diff --git a/core/src/com/me/pacman/entity/Ghost.java b/core/src/com/me/pacman/entity/Ghost.java index 21e428b..47b56a1 100644 --- a/core/src/com/me/pacman/entity/Ghost.java +++ b/core/src/com/me/pacman/entity/Ghost.java @@ -9,15 +9,15 @@ import com.me.pacman.entity.ai.Target; import com.me.pacman.entity.path.EnterGhostHousePath; import com.me.pacman.entity.path.ExitGhostHousePath; import com.me.pacman.level.LevelTile; +import com.me.pacman.level.Modifiers; import com.me.pacman.state.PlayState; import java.util.ArrayList; public class Ghost extends MovableEntity { - public static final float GHOST_SPEED = PlayState.FULL_SPEED * 0.75f; - public static final float GHOST_TUNNEL_SPEED = PlayState.FULL_SPEED * 0.4f; public static final float EYES_SPEED = 15f; + public static final float HOUSE_SPEED = PlayState.FULL_SPEED * 0.5f; public static final Direction[] GHOST_ORDER = { Direction.UP, Direction.LEFT, Direction.DOWN, Direction.RIGHT }; @@ -40,7 +40,7 @@ public class Ghost extends MovableEntity { public Ghost(PlayState state, Vector2 pos, Direction direction, int spriteIndex, Behaviour chaseBehaviour, Behaviour scatterBehaviour, boolean inHouse) { - super(state, pos.x, pos.y, GHOST_SPEED, true, direction, 0.1f); + super(state, pos.x, pos.y, Modifiers.getGhostSpeed(0), true, direction, 0.1f); this.state = state; this.spriteIndex = spriteIndex; this.chaseBehaviour = chaseBehaviour; @@ -77,18 +77,24 @@ public class Ghost extends MovableEntity { batch.draw(sprite[1][currDirection.ordinal()], (int) (pos.x * 8) + (offsetX - 8), (pos.y * 8) + (offsetY - 8)); } + protected float getNormalSpeed() { + return Modifiers.getGhostSpeed(state.round); + } + @Override public void update(float dt) { LevelTile currentTile = state.level.getTile(pos); - if (currentBehaviour instanceof FrightenedBehaviour) { - speed = PlayState.FULL_SPEED * 0.5f; + if (currentTile == null || currentTile == LevelTile.TUNNEL) { + speed = Modifiers.getGhostTunnelSpeed(state.round); + } else if (currentBehaviour instanceof FrightenedBehaviour) { + speed = Modifiers.getGhostFrightSpeed(state.round); } else if (currentBehaviour instanceof ReturnToBase) { speed = EYES_SPEED; - } else if (currentTile == LevelTile.TUNNEL || inHouse) { - speed = GHOST_TUNNEL_SPEED; + } else if (inHouse) { + speed = HOUSE_SPEED; } else { - speed = GHOST_SPEED; + speed = getNormalSpeed(); } super.update(dt); diff --git a/core/src/com/me/pacman/entity/Pacman.java b/core/src/com/me/pacman/entity/Pacman.java index d537458..6c06433 100644 --- a/core/src/com/me/pacman/entity/Pacman.java +++ b/core/src/com/me/pacman/entity/Pacman.java @@ -1,11 +1,15 @@ package com.me.pacman.entity; import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.math.Vector2; import com.me.pacman.level.LevelTile; +import com.me.pacman.level.Modifiers; import com.me.pacman.state.PlayState; public class Pacman extends MovableEntity { + public static final Vector2 HOME = new Vector2(14, 7.5f); + private TextureRegion[][] sprite; private TextureRegion[][] death; @@ -18,7 +22,7 @@ public class Pacman extends MovableEntity { public int deathFrame = 0; public Pacman(PlayState state, boolean moving) { - super(state, 14, 7.5f, PlayState.FULL_SPEED * 0.8f, moving, Direction.LEFT, 0.3f); + super(state, HOME.x, HOME.y, PlayState.FULL_SPEED * 0.8f, moving, Direction.LEFT, 0.3f); this.state = state; sprite = state.getGame().assets.pacman; death = state.getGame().assets.deathAnimation; @@ -45,9 +49,9 @@ public class Pacman extends MovableEntity { } if (state.frightTimer > 0) { - speed = PlayState.FULL_SPEED * 0.9f; + speed = Modifiers.getPacmanFrightSpeed(state.round); } else { - speed = PlayState.FULL_SPEED * 0.8f; + speed = Modifiers.getPacmanSpeed(state.round); } super.update(dt); diff --git a/core/src/com/me/pacman/entity/path/ExitGhostHousePath.java b/core/src/com/me/pacman/entity/path/ExitGhostHousePath.java index 2223eb1..f8c01b1 100644 --- a/core/src/com/me/pacman/entity/path/ExitGhostHousePath.java +++ b/core/src/com/me/pacman/entity/path/ExitGhostHousePath.java @@ -13,7 +13,7 @@ public class ExitGhostHousePath extends Path { }}; public ExitGhostHousePath(Vector2 start) { - super(Ghost.GHOST_TUNNEL_SPEED, start); + super(Ghost.HOUSE_SPEED, start); addPoints(points); } diff --git a/core/src/com/me/pacman/level/Modifiers.java b/core/src/com/me/pacman/level/Modifiers.java new file mode 100644 index 0000000..6c287b9 --- /dev/null +++ b/core/src/com/me/pacman/level/Modifiers.java @@ -0,0 +1,273 @@ +package com.me.pacman.level; + +import com.me.pacman.state.PlayState; + +import java.util.Arrays; + +public class Modifiers { + + private static final Modifiers[] ROUND_MODIFIERS; + + private float frightTime; + + private float pacmanSpeed; + private float pacmanFrightSpeed; + + private float ghostSpeed; + private float ghostFrightSpeed; + private float ghostTunnelSpeed; + + private int elroy1DotsLeft; + private float elroy1Speed; + private int elroy2DotsLeft; + private float elroy2Speed; + + private int forceLeaveSeconds; + + private float[] scatterChaseSwitchTimings; + + private static int cap(int round) { + return Math.min(round, 20); + } + + public static float getFrightTime(int round) { + return ROUND_MODIFIERS[cap(round)].frightTime; + } + + public static float getPacmanSpeed(int round) { + return PlayState.FULL_SPEED * ROUND_MODIFIERS[cap(round)].pacmanSpeed; + } + + public static float getPacmanFrightSpeed(int round) { + return PlayState.FULL_SPEED * ROUND_MODIFIERS[cap(round)].pacmanFrightSpeed; + } + + public static float getGhostSpeed(int round) { + return PlayState.FULL_SPEED * ROUND_MODIFIERS[cap(round)].ghostSpeed; + } + + public static float getGhostFrightSpeed(int round) { + return PlayState.FULL_SPEED * ROUND_MODIFIERS[cap(round)].ghostFrightSpeed; + } + + public static float getGhostTunnelSpeed(int round) { + return PlayState.FULL_SPEED * ROUND_MODIFIERS[cap(round)].ghostTunnelSpeed; + } + + public static int getElroy1DotsLeft(int round) { + return ROUND_MODIFIERS[cap(round)].elroy1DotsLeft; + } + + public static float getElroy1Speed(int round) { + return PlayState.FULL_SPEED * ROUND_MODIFIERS[cap(round)].elroy1Speed; + } + + public static int getElroy2DotsLeft(int round) { + return ROUND_MODIFIERS[cap(round)].elroy2DotsLeft; + } + + public static float getElroy2Speed(int round) { + return PlayState.FULL_SPEED * ROUND_MODIFIERS[cap(round)].elroy2Speed; + } + + public static int getForceLeaveSeconds(int round) { + return ROUND_MODIFIERS[cap(round)].forceLeaveSeconds; + } + + public static float getScatterChaseTimer(int round, int scatterChaseTransition) { + return ROUND_MODIFIERS[cap(round)].scatterChaseSwitchTimings[scatterChaseTransition]; + } + + public Modifiers clone() { + Modifiers mod = new Modifiers(); + mod.frightTime = frightTime; + mod.pacmanSpeed = pacmanSpeed; + mod.pacmanFrightSpeed = pacmanFrightSpeed; + + mod.ghostSpeed = ghostSpeed; + mod.ghostFrightSpeed = ghostFrightSpeed; + mod.ghostTunnelSpeed = ghostTunnelSpeed; + + mod.elroy1DotsLeft = elroy1DotsLeft; + mod.elroy1Speed = elroy1Speed; + mod.elroy2DotsLeft = elroy2DotsLeft; + mod.elroy2Speed = elroy2Speed; + + mod.forceLeaveSeconds = forceLeaveSeconds; + + mod.scatterChaseSwitchTimings = Arrays.copyOf(scatterChaseSwitchTimings, scatterChaseSwitchTimings.length); + return mod; + } + + static { + ROUND_MODIFIERS = new Modifiers[21]; + int round = 0; + + // Round 1 + Modifiers mod = new Modifiers(); + mod.frightTime = 6f; + mod.pacmanSpeed = 0.8f; + mod.pacmanFrightSpeed = 0.9f; + + mod.ghostSpeed = 0.75f; + mod.ghostFrightSpeed = 0.5f; + mod.ghostTunnelSpeed = 0.4f; + + mod.elroy1DotsLeft = 20; + mod.elroy1Speed = 0.8f; + mod.elroy2DotsLeft = 10; + mod.elroy2Speed = 0.85f; + + mod.forceLeaveSeconds = 4; + mod.scatterChaseSwitchTimings = new float[] {7f, 20f, 7f, 20f, 5f, 20f, 5f}; + + ROUND_MODIFIERS[round++] = mod; + + // Round 2 + mod = mod.clone(); + mod.frightTime = 5f; + mod.pacmanSpeed = 0.9f; + mod.pacmanFrightSpeed = 0.95f; + + mod.ghostSpeed = 0.85f; + mod.ghostFrightSpeed = 0.55f; + mod.ghostTunnelSpeed = 0.45f; + + mod.elroy1DotsLeft = 30; + mod.elroy1Speed = 0.9f; + mod.elroy2DotsLeft = 14; + mod.elroy2Speed = 0.95f; + + mod.scatterChaseSwitchTimings = new float[] {7f, 20f, 7f, 20f, 5f, 1033f, 1/60f}; + + ROUND_MODIFIERS[round++] = mod; + + // Round 3 + mod = mod.clone(); + mod.frightTime = 4f; + + mod.elroy1DotsLeft = 40; + mod.elroy1Speed = 0.9f; + mod.elroy2DotsLeft = 20; + mod.elroy2Speed = 0.95f; + + ROUND_MODIFIERS[round++] = mod; + + // Round 4 + mod = mod.clone(); + mod.frightTime = 3f; + + ROUND_MODIFIERS[round++] = mod; + + // Round 5 + mod = mod.clone(); + mod.frightTime = 2f; + + mod.pacmanSpeed = 1f; + mod.pacmanFrightSpeed = 1f; + + mod.ghostSpeed = 0.95f; + mod.ghostFrightSpeed = 0.6f; + mod.ghostTunnelSpeed = 0.5f; + + mod.elroy1Speed = 1f; + mod.elroy2Speed = 1.05f; + + mod.forceLeaveSeconds = 3; + mod.scatterChaseSwitchTimings = new float[] {7f, 20f, 7f, 20f, 5f, 1037f, 1/60f}; + + ROUND_MODIFIERS[round++] = mod; + + // Round 6 + mod = mod.clone(); + mod.frightTime = 5f; + + mod.elroy1DotsLeft = 50; + mod.elroy2DotsLeft = 25; + + ROUND_MODIFIERS[round++] = mod; + + // Round 7 & 8 + mod = mod.clone(); + mod.frightTime = 2f; + + ROUND_MODIFIERS[round++] = mod; + ROUND_MODIFIERS[round++] = mod; + + // Round 9 + mod = mod.clone(); + mod.frightTime = 1f; + + mod.elroy1DotsLeft = 60; + mod.elroy2DotsLeft = 30; + + ROUND_MODIFIERS[round++] = mod; + + // Round 10 + mod = mod.clone(); + mod.frightTime = 5f; + + ROUND_MODIFIERS[round++] = mod; + + // Round 11 + mod = mod.clone(); + mod.frightTime = 2f; + + ROUND_MODIFIERS[round++] = mod; + + // Round 12 & 13 + mod = mod.clone(); + mod.frightTime = 1f; + + mod.elroy1DotsLeft = 80; + mod.elroy2DotsLeft = 40; + + ROUND_MODIFIERS[round++] = mod; + ROUND_MODIFIERS[round++] = mod; + + // Round 14 + mod = mod.clone(); + mod.frightTime = 3f; + + ROUND_MODIFIERS[round++] = mod; + + // Round 15 & 16 + mod = mod.clone(); + mod.frightTime = 1f; + + mod.elroy1DotsLeft = 100; + mod.elroy2DotsLeft = 50; + + ROUND_MODIFIERS[round++] = mod; + ROUND_MODIFIERS[round++] = mod; + + // Round 17 + mod = mod.clone(); + mod.frightTime = 0f; + + ROUND_MODIFIERS[round++] = mod; + + // Round 18 + mod = mod.clone(); + mod.frightTime = 1f; + + ROUND_MODIFIERS[round++] = mod; + + // Round 19 & 20 + mod = mod.clone(); + mod.frightTime = 0f; + + mod.elroy1DotsLeft = 120; + mod.elroy2DotsLeft = 60; + + ROUND_MODIFIERS[round++] = mod; + ROUND_MODIFIERS[round++] = mod; + + // Round 21+ + mod = mod.clone(); + mod.pacmanSpeed = 0.9f; + + ROUND_MODIFIERS[round++] = mod; + } + +} diff --git a/core/src/com/me/pacman/state/PlayState.java b/core/src/com/me/pacman/state/PlayState.java index e1da196..0acef02 100644 --- a/core/src/com/me/pacman/state/PlayState.java +++ b/core/src/com/me/pacman/state/PlayState.java @@ -14,6 +14,7 @@ import com.me.pacman.entity.*; import com.me.pacman.entity.ai.ReturnToBase; import com.me.pacman.level.Level; import com.me.pacman.level.LevelTile; +import com.me.pacman.level.Modifiers; import java.util.Random; @@ -43,21 +44,22 @@ public class PlayState extends LevelState { private long sirenId; - private int pelletsRemaining; + public int pelletsRemaining; private int pelletsEaten; public int pelletsEatenSinceDeath; public boolean pelletsEatenSinceDeathCounterEnabled; + public boolean hasDied; private int score; private int lives; - private int round; + public int round; private boolean paused = false; public float secondsSinceLastDot; public boolean scatter; - private int scatterCount; + private int scatterChaseTransition; private float scatterChaseTimer; public float frightTimer; // remaining fright time @@ -131,11 +133,12 @@ public class PlayState extends LevelState { private void initializeRound() { scatter = true; - scatterCount = 1; + scatterChaseTransition = 0; pelletsEaten = 0; pelletsEatenSinceDeath = 0; pelletsEatenSinceDeathCounterEnabled = false; + hasDied = false; spawnGhosts(); } @@ -147,7 +150,7 @@ public class PlayState extends LevelState { lastGhostCaptured = null; secondsSinceLastDot = 0; - scatterChaseTimer = scatter? 7f : 20f; + scatterChaseTimer = Modifiers.getScatterChaseTimer(round, scatterChaseTransition); random = new Random(897198256012865L); @@ -158,7 +161,7 @@ public class PlayState extends LevelState { private void preNewGame() { score = 0; lives = 3; - round = 1; + round = 0; initializeLevel(); @@ -276,7 +279,7 @@ public class PlayState extends LevelState { ghost.currentBehaviour = ghost.frightBehaviour; ghost.currDirection = ghost.currDirection.getOpposite(); } - frightTimer = 6f; + frightTimer = Modifiers.getFrightTime(round); ghostsCaught = 0; score += 50; } @@ -286,6 +289,7 @@ public class PlayState extends LevelState { pacman.moving = false; pelletsEatenSinceDeath = 0; pelletsEatenSinceDeathCounterEnabled = true; + hasDied = true; setGameState(GameState.PACMAN_CAUGHT_WAIT); } @@ -361,15 +365,13 @@ public class PlayState extends LevelState { } private void updateScatterTimer(float dt) { - if (scatter || scatterCount < 4) { + if (scatterChaseTransition < 7) { // only update scatter timer if we're currently in scatter or if we've yet to enter scatter 4 times scatterChaseTimer -= dt; if (scatterChaseTimer <= 0) { scatter = !scatter; - scatterChaseTimer = scatter ? 7f : 20f; - if (scatter) { - scatterCount++; - } + scatterChaseTimer = Modifiers.getScatterChaseTimer(round, scatterChaseTransition); + scatterChaseTransition++; } } } @@ -387,7 +389,7 @@ public class PlayState extends LevelState { private void updateSecondsSinceLastDot(float dt) { secondsSinceLastDot += dt; - if (secondsSinceLastDot >= 4) { + if (secondsSinceLastDot >= Modifiers.getForceLeaveSeconds(round)) { // It's been 4 seconds since pacman last ate a dot, he's tryin' to avoid ghosts coming out! // We'll get him... for (int i = 1; i < 4; i++) {