diff --git a/src/main/java/se/urmo/game/entities/Ghost.java b/src/main/java/se/urmo/game/entities/Ghost.java index 4e62ca1..3edee17 100644 --- a/src/main/java/se/urmo/game/entities/Ghost.java +++ b/src/main/java/se/urmo/game/entities/Ghost.java @@ -3,6 +3,8 @@ package se.urmo.game.entities; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import se.urmo.game.collision.GhostCollisionChecker; +import se.urmo.game.graphics.SpriteLocation; +import se.urmo.game.graphics.SpriteSheetManager; import se.urmo.game.main.Game; import se.urmo.game.map.GameMap; import se.urmo.game.state.GhostManager; @@ -52,12 +54,13 @@ public class Ghost { - public Ghost(GhostCollisionChecker collisionChecker, GhostStrategy strategy, GhostStrategy scaterStrategy, BufferedImage[] animation, BufferedImage[] fearAnimation) { + public Ghost(GhostCollisionChecker collisionChecker, GhostStrategy strategy, GhostStrategy scaterStrategy, int animation) { this.collisionChecker = collisionChecker; this.chaseStrategy = strategy; this.scaterStrategy = scaterStrategy; - this.baseAnimation = animation; - this.fearAnimation = fearAnimation; + this.baseAnimation = SpriteSheetManager.get(SpriteLocation.GHOST).getAnimation(animation);; + this.fearAnimation = SpriteSheetManager.get(SpriteLocation.GHOST).getAnimation(8);; + position = new Point( 13 * GameMap.MAP_TILESIZE + GameMap.OFFSET_X + (GameMap.MAP_TILESIZE / 2), 4 * GameMap.MAP_TILESIZE + GameMap.OFFSET_Y + (GameMap.MAP_TILESIZE / 2) ); diff --git a/src/main/java/se/urmo/game/map/SpriteLocation.java b/src/main/java/se/urmo/game/graphics/SpriteLocation.java similarity index 54% rename from src/main/java/se/urmo/game/map/SpriteLocation.java rename to src/main/java/se/urmo/game/graphics/SpriteLocation.java index a59eae3..ee8213f 100644 --- a/src/main/java/se/urmo/game/map/SpriteLocation.java +++ b/src/main/java/se/urmo/game/graphics/SpriteLocation.java @@ -1,15 +1,18 @@ -package se.urmo.game.map; +package se.urmo.game.graphics; import lombok.Getter; +import se.urmo.game.entities.Ghost; +import se.urmo.game.map.GameMap; import se.urmo.game.util.LoadSave; import java.awt.image.BufferedImage; @Getter public enum SpriteLocation { - MAP("sprites/PacMan-custom-spritemap-0-3.png", 5, 11), - ITEM("sprites/PacManAssets-Items.png", 2, 8), - NONE("", 0, 0) { // Special case for tiles without sprites + MAP("sprites/PacMan-custom-spritemap-0-3.png", 5, 11, GameMap.MAP_TILESIZE), + ITEM("sprites/PacManAssets-Items.png", 2, 8, GameMap.MAP_TILESIZE), + GHOST("sprites/PacManAssets-Ghosts.png", 11, 4, Ghost.GHOST_SIZE), + NONE("", 0, 0, 0) { // Special case for tiles without sprites @Override public BufferedImage[][] loadSprites(int tileSize) { return new BufferedImage[][] {{ null }}; // Single null sprite @@ -19,11 +22,13 @@ public enum SpriteLocation { private final String path; private final int rows; private final int cols; + private final int size; - SpriteLocation(String path, int rows, int cols) { + SpriteLocation(String path, int rows, int cols, int size) { this.path = path; this.rows = rows; this.cols = cols; + this.size = size; } public BufferedImage[][] loadSprites(int tileSize) { diff --git a/src/main/java/se/urmo/game/map/SpriteSheet.java b/src/main/java/se/urmo/game/graphics/SpriteSheet.java similarity index 56% rename from src/main/java/se/urmo/game/map/SpriteSheet.java rename to src/main/java/se/urmo/game/graphics/SpriteSheet.java index 3d1c71a..a7df5ed 100644 --- a/src/main/java/se/urmo/game/map/SpriteSheet.java +++ b/src/main/java/se/urmo/game/graphics/SpriteSheet.java @@ -1,6 +1,7 @@ -package se.urmo.game.map; +package se.urmo.game.graphics; import lombok.Getter; + import java.awt.image.BufferedImage; @@ -11,15 +12,7 @@ public class SpriteSheet { public SpriteSheet(SpriteLocation location) { this.location = location; - this.spriteSheet = location.loadSprites(GameMap.MAP_TILESIZE); - } - - public BufferedImage getSprite(TileType tileType) { - if (tileType.getSpriteSheet() != location) { - throw new IllegalArgumentException("Tile type belongs to different sprite sheet"); - } - // NONE will always return null without additional checks - return getSprite(tileType.getRow(), tileType.getCol()); + this.spriteSheet = location.loadSprites(location.getSize()); } public BufferedImage getSprite(int row, int col) { @@ -31,4 +24,12 @@ public class SpriteSheet { } return spriteSheet[row][col]; } + + public BufferedImage[] getAnimation(int row) { + if(location == SpriteLocation.NONE) return null; + + if(row>= spriteSheet.length) return null; + + return spriteSheet[row]; + } } \ No newline at end of file diff --git a/src/main/java/se/urmo/game/map/SpriteSheetManager.java b/src/main/java/se/urmo/game/graphics/SpriteSheetManager.java similarity index 75% rename from src/main/java/se/urmo/game/map/SpriteSheetManager.java rename to src/main/java/se/urmo/game/graphics/SpriteSheetManager.java index 3586214..e482ac0 100644 --- a/src/main/java/se/urmo/game/map/SpriteSheetManager.java +++ b/src/main/java/se/urmo/game/graphics/SpriteSheetManager.java @@ -1,4 +1,6 @@ -package se.urmo.game.map; +package se.urmo.game.graphics; + +import se.urmo.game.map.GameMap; import java.util.EnumMap; import java.util.Map; @@ -6,7 +8,7 @@ import java.util.Map; public class SpriteSheetManager { private static final Map spriteSheets = new EnumMap<>(SpriteLocation.class); - public static SpriteSheet get(SpriteLocation location) { + public static SpriteSheet get(SpriteLocation location) { return spriteSheets.computeIfAbsent(location, SpriteSheet::new); } diff --git a/src/main/java/se/urmo/game/map/GameMap.java b/src/main/java/se/urmo/game/map/GameMap.java index cd5810d..e5da8f1 100644 --- a/src/main/java/se/urmo/game/map/GameMap.java +++ b/src/main/java/se/urmo/game/map/GameMap.java @@ -1,6 +1,7 @@ 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.*; @@ -31,28 +32,26 @@ public class GameMap { BufferedReader br = new BufferedReader(new InputStreamReader(Objects.requireNonNull(is)))) { String line; - int rowIndex = 0; - while ((line = br.readLine()) != null && rowIndex < mapRowSize) { + int row = 0; + while ((line = br.readLine()) != null && row < mapRowSize) { String[] tokens = line.split(","); if (tokens.length != mapColSize) { throw new IllegalStateException( - "Invalid map format: row " + rowIndex + " has " + tokens.length + + "Invalid map format: row " + row + " has " + tokens.length + " columns, expected " + mapColSize ); } for (int col = 0; col < mapColSize; col++) { int value = Integer.parseInt(tokens[col].trim()); - TileType type = TileType.fromValue(value); - BufferedImage sprite = SpriteSheetManager.get(type.getSpriteSheet()).getSprite(type); - data[rowIndex][col] = new MapTile(sprite, type); + data[row][col] = MapTile.byType(TileType.fromValue(value)); } - rowIndex++; + row++; } - if (rowIndex != mapRowSize) { + if (row != mapRowSize) { throw new IllegalStateException( - "Invalid map format: found " + rowIndex + " rows, expected " + mapRowSize + "Invalid map format: found " + row + " rows, expected " + mapRowSize ); } @@ -78,10 +77,10 @@ public class GameMap { } } - private BufferedImage getSprite(int value) { - TileType type = TileType.fromValue(value); - return SpriteSheetManager.get(type.getSpriteSheet()).getSprite(type); - } +// private BufferedImage getSprite(int value) { +// TileType type = TileType.fromValue(value); +// return SpriteSheetManager.get(type.getSpriteSheet()).getSprite(type); +// } public boolean isPassable(List list){ return list.stream().allMatch(p -> isPassable(p.x, p.y)); diff --git a/src/main/java/se/urmo/game/map/MapTile.java b/src/main/java/se/urmo/game/map/MapTile.java index 3ccfb55..272b3c3 100644 --- a/src/main/java/se/urmo/game/map/MapTile.java +++ b/src/main/java/se/urmo/game/map/MapTile.java @@ -2,6 +2,7 @@ package se.urmo.game.map; import lombok.Getter; import lombok.Setter; +import se.urmo.game.graphics.SpriteSheetManager; import java.awt.image.BufferedImage; @@ -12,12 +13,19 @@ public class MapTile { private BufferedImage image; private final boolean[][] collisionMask; - public MapTile(BufferedImage image, TileType tileType) { - this.tileType = tileType; + public MapTile(BufferedImage image, TileType type) { + this.tileType = type; this.image = image; this.collisionMask = tileType.isSolid() ? createCollisionMask(image) : null; } + public static MapTile byType(TileType type) { + BufferedImage img = SpriteSheetManager + .get(type.getSpriteSheet()) + .getSprite(type.getRow(), type.getCol()); // row and col in sprite - not in map! + return new MapTile(img, type) ; + } + private boolean[][] createCollisionMask(BufferedImage img) { if(img == null) return null; int w = img.getWidth(); diff --git a/src/main/java/se/urmo/game/map/TileType.java b/src/main/java/se/urmo/game/map/TileType.java index c485b90..96aaa09 100644 --- a/src/main/java/se/urmo/game/map/TileType.java +++ b/src/main/java/se/urmo/game/map/TileType.java @@ -1,6 +1,7 @@ package se.urmo.game.map; import lombok.Getter; +import se.urmo.game.graphics.SpriteLocation; @Getter public enum TileType { diff --git a/src/main/java/se/urmo/game/state/GhostManager.java b/src/main/java/se/urmo/game/state/GhostManager.java index 600dfdf..9ed30bf 100644 --- a/src/main/java/se/urmo/game/state/GhostManager.java +++ b/src/main/java/se/urmo/game/state/GhostManager.java @@ -26,10 +26,12 @@ import java.util.List; public class GhostManager { public static final int SPRITE_SHEET_ROWS = 10; public static final int MAX_SPRITE_FRAMES = 4; + public static final int BLINKY_ANIMATION = 0; + public static final int PINKY_ANIMATION = 2; + public static final int INKY_ANIMATION = 1; + public static final int CLYDE_ANIMATION = 3; @Getter private final List ghosts = new ArrayList<>(); - private BufferedImage[][] image; - private GhostMode globalMode; private long lastModeSwitchTime; private int phaseIndex = 0; @@ -43,31 +45,17 @@ public class GhostManager { }; public GhostManager(GhostCollisionChecker ghostCollisionChecker) { - loadAnimation(); - // Create ghosts with their strategies - Ghost blinky = new Ghost(ghostCollisionChecker, new BlinkyStrategy(), new ScatterToTopRight(), image[0], image[9]); + Ghost blinky = new Ghost(ghostCollisionChecker, new BlinkyStrategy(), new ScatterToTopRight(), BLINKY_ANIMATION); ghosts.add(blinky); - //ghosts.add(new Ghost(ghostCollisionChecker, new PinkyStrategy(),new ScatterToTopLeft(), image[2], image[9])); - //ghosts.add(new Ghost(ghostCollisionChecker,new InkyStrategy(blinky), new ScatterToBottomRight(), image[1], image[9])); - //ghosts.add(new Ghost(ghostCollisionChecker, new ClydeStrategy(), new ScatterToBottomLeft(), image[3], image[8])); + ghosts.add(new Ghost(ghostCollisionChecker, new PinkyStrategy(), new ScatterToTopLeft(), PINKY_ANIMATION)); + ghosts.add(new Ghost(ghostCollisionChecker,new InkyStrategy(blinky), new ScatterToBottomRight(), INKY_ANIMATION)); + ghosts.add(new Ghost(ghostCollisionChecker, new ClydeStrategy(), new ScatterToBottomLeft(), CLYDE_ANIMATION)); setMode(GhostMode.CHASE); } - private void loadAnimation() { - image = new BufferedImage[SPRITE_SHEET_ROWS][MAX_SPRITE_FRAMES]; - - BufferedImage img = LoadSave.GetSpriteAtlas("sprites/PacManAssets-Ghosts.png"); - for (int row = 0; row < SPRITE_SHEET_ROWS; row++) { - for (int col = 0; col < MAX_SPRITE_FRAMES; col++) { - image[row][col] = img.getSubimage(Ghost.GHOST_SIZE * col, Ghost.GHOST_SIZE * row, Ghost.GHOST_SIZE, Ghost.GHOST_SIZE); - } - } - } - public void setMode(GhostMode mode) { - this.globalMode = mode; - log.debug("Mode changed to {}", globalMode); + log.debug("Mode changed to {}", mode); for (Ghost g : ghosts) { g.setMode(mode); }