Implemented level-change

This commit is contained in:
Urban Modig
2025-09-01 15:29:25 +02:00
parent 3a4a0a1824
commit be3c4deb3c
6 changed files with 105 additions and 31 deletions

View File

@ -1,12 +1,12 @@
package se.urmo.game.map; package se.urmo.game.map;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import se.urmo.game.graphics.SpriteSheetManager;
import se.urmo.game.util.Direction; import se.urmo.game.util.Direction;
import java.awt.*; import java.awt.*;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.*; import java.io.*;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -18,15 +18,36 @@ public class GameMap {
public static final int MAP_ROW_SIZE = 30; 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_Y = 7 * MAP_TILESIZE; // 160px from top
public static final int OFFSET_X = MAP_TILESIZE; // 16px from left 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) { 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]; MapTile[][] data = new MapTile[mapRowSize][mapColSize];
int[][] data2 = new int[mapRowSize][mapColSize];
try (InputStream is = getClass().getClassLoader().getResourceAsStream(path); try (InputStream is = getClass().getClassLoader().getResourceAsStream(path);
BufferedReader br = new BufferedReader(new InputStreamReader(Objects.requireNonNull(is)))) { BufferedReader br = new BufferedReader(new InputStreamReader(Objects.requireNonNull(is)))) {
@ -42,11 +63,15 @@ public class GameMap {
); );
} }
for (int col = 0; col < mapColSize; col++) { data2[row++] = Arrays.stream(tokens)
int value = Integer.parseInt(tokens[col].trim()); .map(String::trim)
data[row][col] = MapTile.byType(TileType.fromValue(value)); .mapToInt(Integer::parseInt)
} .toArray();
row++;
// 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) { if (row != mapRowSize) {
@ -60,7 +85,7 @@ public class GameMap {
} catch (IOException e) { } catch (IOException e) {
log.error("Failed to read resource: {}", e.getMessage(), e); log.error("Failed to read resource: {}", e.getMessage(), e);
} }
return data; return data2;
} }
public void draw(Graphics g) { public void draw(Graphics g) {
@ -77,10 +102,6 @@ public class GameMap {
} }
} }
public boolean isPassable(List<Point> list){
return list.stream().allMatch(p -> isPassable(p.x, p.y));
}
public boolean isPassable(int screenX, int screenY) { public boolean isPassable(int screenX, int screenY) {
int row = screenToRow(screenY); int row = screenToRow(screenY);
int col = screenToCol(screenX); int col = screenToCol(screenX);
@ -143,6 +164,7 @@ public class GameMap {
public int columns() { public int columns() {
return MAP_COL_SIZE; return MAP_COL_SIZE;
} }
public int rows() { public int rows() {
return MAP_ROW_SIZE; return MAP_ROW_SIZE;
} }
@ -186,6 +208,7 @@ public class GameMap {
public static int colToScreen(int col) { public static int colToScreen(int col) {
return col * MAP_TILESIZE + OFFSET_X; return col * MAP_TILESIZE + OFFSET_X;
} }
public static int rowToScreen(int row) { public static int rowToScreen(int row) {
return row * MAP_TILESIZE + OFFSET_Y; return row * MAP_TILESIZE + OFFSET_Y;
} }
@ -202,7 +225,8 @@ public class GameMap {
int row = (screenY - GameMap.OFFSET_Y) / GameMap.MAP_TILESIZE; int row = (screenY - GameMap.OFFSET_Y) / GameMap.MAP_TILESIZE;
int col = (screenX - GameMap.OFFSET_X) / 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); log.debug("At [{}][{}]", row, col);
return Stream.of( return Stream.of(
new DirectionCheck(0, 1, Direction.RIGHT), new DirectionCheck(0, 1, Direction.RIGHT),
@ -226,4 +250,13 @@ public class GameMap {
int col = pos.y % GameMap.MAP_TILESIZE; int col = pos.y % GameMap.MAP_TILESIZE;
return row == GameMap.MAP_TILESIZE / 2 && col == GameMap.MAP_TILESIZE / 2; 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);
}
} }

View File

@ -10,13 +10,12 @@ import java.awt.Graphics;
public class FruitManager { public class FruitManager {
private final LevelManager levelManager; private final LevelManager levelManager;
private Fruit activeFruit; private Fruit activeFruit;
private int dotsEaten = 0;
public FruitManager(LevelManager levelManager) { public FruitManager(LevelManager levelManager) {
this.levelManager = levelManager; this.levelManager = levelManager;
} }
public void dotEaten() { public void dotEaten(int dotsEaten) {
dotsEaten++; dotsEaten++;
if (dotsEaten == 10 || dotsEaten == 170) { if (dotsEaten == 10 || dotsEaten == 170) {
spawnFruit(levelManager.getCurrentLevel().getLevel()); spawnFruit(levelManager.getCurrentLevel().getLevel());
@ -48,4 +47,8 @@ public class FruitManager {
activeFruit.draw(g); activeFruit.draw(g);
} }
} }
public void reset() {
activeFruit = null;
}
} }

View File

@ -9,7 +9,9 @@ import java.util.Arrays;
@Getter @Getter
public enum FruitType { 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 int level;
private final BufferedImage sprite; private final BufferedImage sprite;

View File

@ -92,4 +92,8 @@ public class GhostManager {
public void setFrightMode() { public void setFrightMode() {
this.setMode(GhostMode.FRIGHTENED); this.setMode(GhostMode.FRIGHTENED);
} }
public void reset() {
ghosts.forEach(Ghost::resetPosition);
}
} }

View File

@ -4,9 +4,31 @@ import lombok.Getter;
public class LevelManager { public class LevelManager {
public void nextLevel() {
currentLevel = Level.forLevel(currentLevel.getLevel() + 1);
}
@Getter @Getter
public enum Level { 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 int frightendedDuration;
private final double ghostSpeed; private final double ghostSpeed;

View File

@ -31,6 +31,7 @@ public class PlayingState implements GameState {
private GameMap map; private GameMap map;
private int score; private int score;
private int lives = 3; private int lives = 3;
private int dotsEaten = 0;
public PlayingState(Game game, GameStateManager gameStateManager) { public PlayingState(Game game, GameStateManager gameStateManager) {
this.game = game; this.game = game;
@ -63,8 +64,17 @@ public class PlayingState implements GameState {
ghostManager.setFrightMode(); ghostManager.setFrightMode();
} }
if(wasRemoved){ if(wasRemoved){
fruitManager.dotEaten(); dotsEaten++;
fruitManager.dotEaten(dotsEaten);
score+=tile.getTileType().getScore(); score+=tile.getTileType().getScore();
if(dotsEaten == map.numberOfDots()){
levelManager.nextLevel();
map.reset();
ghostManager.reset();
fruitManager.reset();
pacman.resetPosition();
dotsEaten = 0;
}
} }
} }