diff --git a/src/main/java/se/urmo/game/map/GameMap.java b/src/main/java/se/urmo/game/map/GameMap.java index bcce658..e83fb67 100644 --- a/src/main/java/se/urmo/game/map/GameMap.java +++ b/src/main/java/se/urmo/game/map/GameMap.java @@ -1,12 +1,12 @@ package se.urmo.game.map; import lombok.extern.slf4j.Slf4j; -import se.urmo.game.graphics.SpriteSheetManager; import se.urmo.game.util.Direction; import java.awt.*; import java.awt.image.BufferedImage; import java.io.*; +import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.stream.Stream; @@ -18,15 +18,36 @@ public class GameMap { public static final int MAP_ROW_SIZE = 30; public static final int OFFSET_Y = 7 * MAP_TILESIZE; // 160px from top public static final int OFFSET_X = MAP_TILESIZE; // 16px from left - private final MapTile[][] mapData; + private MapTile[][] mapData; + private final int[][] csvData; + private long numberOfDots; public GameMap(String mapFilePath) { - this.mapData = loadMap(mapFilePath, MAP_ROW_SIZE, MAP_COL_SIZE); + this.csvData = readCSV(mapFilePath, MAP_ROW_SIZE, MAP_COL_SIZE); + + this.mapData = createMap(csvData); + + this.numberOfDots = Arrays.stream(mapData) + .flatMap(Arrays::stream) + .filter(tile -> tile != null && + (tile.getTileType() == TileType.SMALL_PELLET || + tile.getTileType() == TileType.LARGE_PELLET)) + .count(); + } - private MapTile[][] loadMap(String path, int mapRowSize, int mapColSize) { + private static MapTile[][] createMap(int[][] data2) { + return Arrays.stream(data2) + .map(a -> Arrays.stream(a) + .mapToObj(i -> MapTile.byType(TileType.fromValue(i))) + .toArray(MapTile[]::new)) + .toArray(MapTile[][]::new); + } + + private int[][] readCSV(String path, int mapRowSize, int mapColSize) { MapTile[][] data = new MapTile[mapRowSize][mapColSize]; + int[][] data2 = new int[mapRowSize][mapColSize]; try (InputStream is = getClass().getClassLoader().getResourceAsStream(path); BufferedReader br = new BufferedReader(new InputStreamReader(Objects.requireNonNull(is)))) { @@ -42,11 +63,15 @@ public class GameMap { ); } - for (int col = 0; col < mapColSize; col++) { - int value = Integer.parseInt(tokens[col].trim()); - data[row][col] = MapTile.byType(TileType.fromValue(value)); - } - row++; + data2[row++] = Arrays.stream(tokens) + .map(String::trim) + .mapToInt(Integer::parseInt) + .toArray(); + +// for (int col = 0; col < mapColSize; col++) { +// int value = Integer.parseInt(tokens[col].trim()); +// data[row][col] = MapTile.byType(TileType.fromValue(value)); +// } } if (row != mapRowSize) { @@ -57,10 +82,10 @@ public class GameMap { } catch (NullPointerException e) { log.error("Failed to open inputstream: {}", e.getMessage(), e); - } catch (IOException e){ + } catch (IOException e) { log.error("Failed to read resource: {}", e.getMessage(), e); } - return data; + return data2; } public void draw(Graphics g) { @@ -77,10 +102,6 @@ public class GameMap { } } - public boolean isPassable(List list){ - return list.stream().allMatch(p -> isPassable(p.x, p.y)); - } - public boolean isPassable(int screenX, int screenY) { int row = screenToRow(screenY); int col = screenToCol(screenX); @@ -90,7 +111,7 @@ public class GameMap { boolean[][] mask = mapData[row][col].getCollisionMask(); boolean b = mask == null || !mask[tileY][tileX]; - log.trace(b?" - passable":" - not passable"); + log.trace(b ? " - passable" : " - not passable"); return b; } @@ -100,8 +121,8 @@ public class GameMap { public boolean isSolid(int row, int col) { - if (col >= columns() || col < 0 ) return true; - if(row >= rows() || row < 0) return true; + if (col >= columns() || col < 0) return true; + if (row >= rows() || row < 0) return true; MapTile mapTile = mapData[row][col]; boolean solid = mapTile.isSolid(); log.debug("[{}][{}] {}", row, col, mapTile.getTileType()); @@ -143,35 +164,36 @@ public class GameMap { public int columns() { return MAP_COL_SIZE; } + public int rows() { return MAP_ROW_SIZE; } - public int colToWorldX(int col){ + public int colToWorldX(int col) { return col * GameMap.MAP_TILESIZE + GameMap.OFFSET_X; } - public int rowToWorldY(int row){ + public int rowToWorldY(int row) { return row * GameMap.MAP_TILESIZE + GameMap.OFFSET_Y; } - public int worldXtoCol(int x){ + public int worldXtoCol(int x) { return x / GameMap.MAP_TILESIZE; } - public int worldYtoRow(int y){ + public int worldYtoRow(int y) { return y / GameMap.MAP_TILESIZE; } - public Point coordToWorld(int row, int col){ + public Point coordToWorld(int row, int col) { return new Point(colToWorldX(col), rowToWorldY(row)); } - public Point worldToScreen(Point world){ + public Point worldToScreen(Point world) { return new Point(world.x + OFFSET_X, world.y + OFFSET_Y); } - public Point screenToWorld(Point screen){ + public Point screenToWorld(Point screen) { return new Point(screen.x - OFFSET_X, screen.y - OFFSET_Y); } @@ -186,6 +208,7 @@ public class GameMap { public static int colToScreen(int col) { return col * MAP_TILESIZE + OFFSET_X; } + public static int rowToScreen(int row) { return row * MAP_TILESIZE + OFFSET_Y; } @@ -202,7 +225,8 @@ public class GameMap { int row = (screenY - GameMap.OFFSET_Y) / GameMap.MAP_TILESIZE; int col = (screenX - GameMap.OFFSET_X) / GameMap.MAP_TILESIZE; - record DirectionCheck(int rowOffset, int colOffset, Direction direction) {} + record DirectionCheck(int rowOffset, int colOffset, Direction direction) { + } log.debug("At [{}][{}]", row, col); return Stream.of( new DirectionCheck(0, 1, Direction.RIGHT), @@ -226,4 +250,13 @@ public class GameMap { int col = pos.y % GameMap.MAP_TILESIZE; return row == GameMap.MAP_TILESIZE / 2 && col == GameMap.MAP_TILESIZE / 2; } + + public long numberOfDots() { + //return this.numberOfDots; + return 10; + } + + public void reset() { + mapData = createMap(csvData); + } } diff --git a/src/main/java/se/urmo/game/state/FruitManager.java b/src/main/java/se/urmo/game/state/FruitManager.java index f6120da..e376ccb 100644 --- a/src/main/java/se/urmo/game/state/FruitManager.java +++ b/src/main/java/se/urmo/game/state/FruitManager.java @@ -10,13 +10,12 @@ import java.awt.Graphics; public class FruitManager { private final LevelManager levelManager; private Fruit activeFruit; - private int dotsEaten = 0; public FruitManager(LevelManager levelManager) { this.levelManager = levelManager; } - public void dotEaten() { + public void dotEaten(int dotsEaten) { dotsEaten++; if (dotsEaten == 10 || dotsEaten == 170) { spawnFruit(levelManager.getCurrentLevel().getLevel()); @@ -48,4 +47,8 @@ public class FruitManager { activeFruit.draw(g); } } + + public void reset() { + activeFruit = null; + } } diff --git a/src/main/java/se/urmo/game/state/FruitType.java b/src/main/java/se/urmo/game/state/FruitType.java index b600b98..3efac3f 100644 --- a/src/main/java/se/urmo/game/state/FruitType.java +++ b/src/main/java/se/urmo/game/state/FruitType.java @@ -9,7 +9,9 @@ import java.util.Arrays; @Getter public enum FruitType { - CHERRY(1, SpriteSheetManager.get(SpriteLocation.ITEM).getSprite(0,0), 100); + CHERRY(1, SpriteSheetManager.get(SpriteLocation.ITEM).getSprite(0,0), 100), + CHERRY2(2, SpriteSheetManager.get(SpriteLocation.ITEM).getSprite(0,0), 100), + CHERRY3(3, SpriteSheetManager.get(SpriteLocation.ITEM).getSprite(0,0), 100); private final int level; private final BufferedImage sprite; diff --git a/src/main/java/se/urmo/game/state/GhostManager.java b/src/main/java/se/urmo/game/state/GhostManager.java index c221eaa..976d1dd 100644 --- a/src/main/java/se/urmo/game/state/GhostManager.java +++ b/src/main/java/se/urmo/game/state/GhostManager.java @@ -92,4 +92,8 @@ public class GhostManager { public void setFrightMode() { this.setMode(GhostMode.FRIGHTENED); } + + public void reset() { + ghosts.forEach(Ghost::resetPosition); + } } diff --git a/src/main/java/se/urmo/game/state/LevelManager.java b/src/main/java/se/urmo/game/state/LevelManager.java index bf9497b..c8cd902 100644 --- a/src/main/java/se/urmo/game/state/LevelManager.java +++ b/src/main/java/se/urmo/game/state/LevelManager.java @@ -4,9 +4,31 @@ import lombok.Getter; public class LevelManager { + public void nextLevel() { + currentLevel = Level.forLevel(currentLevel.getLevel() + 1); + } + @Getter public enum Level { - LEVEL1(1,6000, 0.75, 0.85, FruitType.CHERRY); + LEVEL1(1,6000, 0.75, 0.8, FruitType.CHERRY), + LEVEL2(2,3000, 0.85, 0.85, FruitType.CHERRY), + LEVEL3(3,1000, 0.95, 0.9, FruitType.CHERRY), + LEVEL4(4,6000, 0.75, 0.85, FruitType.CHERRY), + LEVEL5(5,6000, 0.75, 0.85, FruitType.CHERRY), + LEVEL6(6,6000, 0.75, 0.85, FruitType.CHERRY), + LEVEL7(7,6000, 0.75, 0.85, FruitType.CHERRY), + LEVEL8(8,6000, 0.75, 0.85, FruitType.CHERRY), + LEVEL9(9,6000, 0.75, 0.85, FruitType.CHERRY), + LEVEL10(10,6000, 0.75, 0.85, FruitType.CHERRY), + LEVEL11(11,6000, 0.75, 0.85, FruitType.CHERRY), + LEVEL12(12,6000, 0.75, 0.85, FruitType.CHERRY), + LEVEL13(13,6000, 0.75, 0.85, FruitType.CHERRY), + LEVEL14(14,6000, 0.75, 0.85, FruitType.CHERRY), + LEVEL15(15,6000, 0.75, 0.85, FruitType.CHERRY), + LEVEL16(16,6000, 0.75, 0.85, FruitType.CHERRY), + LEVEL17(17,6000, 0.75, 0.85, FruitType.CHERRY), + LEVEL18(18,6000, 0.75, 0.85, FruitType.CHERRY), + LEVEL19(19,6000, 0.75, 0.85, FruitType.CHERRY); private final int frightendedDuration; private final double ghostSpeed; diff --git a/src/main/java/se/urmo/game/state/PlayingState.java b/src/main/java/se/urmo/game/state/PlayingState.java index a38fd5e..920b677 100644 --- a/src/main/java/se/urmo/game/state/PlayingState.java +++ b/src/main/java/se/urmo/game/state/PlayingState.java @@ -31,6 +31,7 @@ public class PlayingState implements GameState { private GameMap map; private int score; private int lives = 3; + private int dotsEaten = 0; public PlayingState(Game game, GameStateManager gameStateManager) { this.game = game; @@ -63,8 +64,17 @@ public class PlayingState implements GameState { ghostManager.setFrightMode(); } if(wasRemoved){ - fruitManager.dotEaten(); + dotsEaten++; + fruitManager.dotEaten(dotsEaten); score+=tile.getTileType().getScore(); + if(dotsEaten == map.numberOfDots()){ + levelManager.nextLevel(); + map.reset(); + ghostManager.reset(); + fruitManager.reset(); + pacman.resetPosition(); + dotsEaten = 0; + } } }