Fixing minor improvements
This commit is contained in:
@ -19,7 +19,6 @@ import java.util.stream.Collectors;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class Ghost {
|
public class Ghost {
|
||||||
private static final int COLLISION_BOX_SIZE = 16;
|
private static final int COLLISION_BOX_SIZE = 16;
|
||||||
private static final int GHOST_SPEED = 1;
|
|
||||||
private static final int GHOST_MOVEMENT_UPDATE_FREQUENCY = 2;
|
private static final int GHOST_MOVEMENT_UPDATE_FREQUENCY = 2;
|
||||||
public static final int GHOST_SIZE = 32;
|
public static final int GHOST_SIZE = 32;
|
||||||
private static final int ANIMATION_UPDATE_FREQUENCY = 25;
|
private static final int ANIMATION_UPDATE_FREQUENCY = 25;
|
||||||
@ -49,8 +48,8 @@ public class Ghost {
|
|||||||
this.scaterStrategy = scaterStrategy;
|
this.scaterStrategy = scaterStrategy;
|
||||||
this.animation = animation;
|
this.animation = animation;
|
||||||
position = new Point(
|
position = new Point(
|
||||||
13 * GameMap.MAP_TILESIZE + (GameMap.MAP_TILESIZE / 2) + GameMap.OFFSET_X,
|
13 * GameMap.MAP_TILESIZE + GameMap.OFFSET_X + (GameMap.MAP_TILESIZE / 2),
|
||||||
4 * GameMap.MAP_TILESIZE + (GameMap.MAP_TILESIZE / 2) + GameMap.OFFSET_Y);
|
4 * GameMap.MAP_TILESIZE + GameMap.OFFSET_Y + (GameMap.MAP_TILESIZE / 2) );
|
||||||
|
|
||||||
this.currentStrategy = chaseStrategy;
|
this.currentStrategy = chaseStrategy;
|
||||||
}
|
}
|
||||||
@ -86,8 +85,8 @@ public class Ghost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Point newPosition = new Point(
|
Point newPosition = new Point(
|
||||||
position.x + direction.dx * GHOST_SPEED,
|
position.x + direction.dx,
|
||||||
position.y + direction.dy * GHOST_SPEED);
|
position.y + direction.dy);
|
||||||
log.debug("Next position {}", newPosition);
|
log.debug("Next position {}", newPosition);
|
||||||
|
|
||||||
Point destination = collisionChecker.canMoveTo(direction, newPosition);
|
Point destination = collisionChecker.canMoveTo(direction, newPosition);
|
||||||
@ -124,15 +123,15 @@ public class Ghost {
|
|||||||
.orElse(Integer.MAX_VALUE);
|
.orElse(Integer.MAX_VALUE);
|
||||||
|
|
||||||
// Return all directions that have this priority
|
// Return all directions that have this priority
|
||||||
List<Direction> l = options.entrySet().stream()
|
List<Direction> directions = options.entrySet().stream()
|
||||||
.filter(entry -> entry.getValue() == lowestPriority)
|
.filter(entry -> entry.getValue() == lowestPriority)
|
||||||
.map(Map.Entry::getKey)
|
.map(Map.Entry::getKey)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
Direction best = l.getFirst();
|
Direction best = directions.getFirst();
|
||||||
double bestDist = Double.MAX_VALUE;
|
double bestDist = Double.MAX_VALUE;
|
||||||
|
|
||||||
for (Direction d : l) {
|
for (Direction d : directions) {
|
||||||
int nx = position.x + d.dx * GameMap.MAP_TILESIZE;
|
int nx = position.x + d.dx * GameMap.MAP_TILESIZE;
|
||||||
int ny = position.y + d.dy * GameMap.MAP_TILESIZE;
|
int ny = position.y + d.dy * GameMap.MAP_TILESIZE;
|
||||||
double dist = target.distance(nx, ny);
|
double dist = target.distance(nx, ny);
|
||||||
|
|||||||
@ -7,6 +7,8 @@ import java.awt.Point;
|
|||||||
public class ScatterToBottomRight implements GhostStrategy {
|
public class ScatterToBottomRight implements GhostStrategy {
|
||||||
@Override
|
@Override
|
||||||
public Point chooseTarget(Ghost ghost, PacMan pacman, GameMap map) {
|
public Point chooseTarget(Ghost ghost, PacMan pacman, GameMap map) {
|
||||||
return new Point(map.getHeight() - 1, map.getHeight() - 1);
|
return new Point(
|
||||||
|
map.rowToWorldY(map.rows() - 1),
|
||||||
|
map.colToWorldX(map.columns() - 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,53 +1,65 @@
|
|||||||
package se.urmo.game.map;
|
package se.urmo.game.map;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import se.urmo.game.main.GamePanel;
|
|
||||||
import se.urmo.game.util.LoadSave;
|
import se.urmo.game.util.LoadSave;
|
||||||
|
|
||||||
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.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.IntStream;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class GameMap {
|
public class GameMap {
|
||||||
public static final int MAP_TILESIZE = 16;// 16px from left
|
public static final int MAP_TILESIZE = 16;// 16px from left
|
||||||
|
public static final int MAP_COL_SIZE = 28;
|
||||||
|
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 BufferedImage[][] images = new BufferedImage[13][19];
|
private final BufferedImage[][] images = new BufferedImage[13][19];
|
||||||
private MapTile[][] mapData;
|
private final MapTile[][] mapData;
|
||||||
|
|
||||||
public GameMap() {
|
public GameMap() {
|
||||||
loadSprites();
|
loadSprites();
|
||||||
loadMap("maps/map1.csv");
|
mapData = loadMap("maps/map1.csv");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadMap(String path) {
|
private MapTile[][] loadMap(String path) {
|
||||||
List<int[]> rows = new ArrayList<>();
|
MapTile[][] data = new MapTile[MAP_ROW_SIZE][MAP_COL_SIZE];
|
||||||
|
|
||||||
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)))) {
|
||||||
|
|
||||||
String line;
|
String line;
|
||||||
while ((line = br.readLine()) != null) {
|
int rowIndex = 0;
|
||||||
|
while ((line = br.readLine()) != null && rowIndex < MAP_ROW_SIZE) {
|
||||||
String[] tokens = line.split(",");
|
String[] tokens = line.split(",");
|
||||||
int[] row = new int[tokens.length];
|
if (tokens.length != MAP_COL_SIZE) {
|
||||||
for (int i = 0; i < tokens.length; i++) {
|
throw new IllegalStateException(
|
||||||
row[i] = Integer.parseInt(tokens[i].trim());
|
"Invalid map format: row " + rowIndex + " has " + tokens.length +
|
||||||
}
|
" columns, expected " + MAP_COL_SIZE
|
||||||
rows.add(row);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException | NullPointerException e) {
|
for (int col = 0; col < MAP_COL_SIZE; col++) {
|
||||||
e.printStackTrace();
|
int value = Integer.parseInt(tokens[col].trim());
|
||||||
|
data[rowIndex][col] = new MapTile(getSprite(value), value);
|
||||||
}
|
}
|
||||||
mapData = rows.stream()
|
rowIndex++;
|
||||||
.map(row -> IntStream.of(row)
|
}
|
||||||
.mapToObj(value -> new MapTile(getSprite(value), value))
|
|
||||||
.toArray(MapTile[]::new))
|
if (rowIndex != MAP_ROW_SIZE) {
|
||||||
.toArray(MapTile[][]::new);
|
throw new IllegalStateException(
|
||||||
|
"Invalid map format: found " + rowIndex + " rows, expected " + MAP_ROW_SIZE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
log.error("Failed to open inputstream: {}", e.getMessage(), e);
|
||||||
|
} catch (IOException e){
|
||||||
|
log.error("Failed to read resource: {}", e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BufferedImage getSprite(int value) {
|
private BufferedImage getSprite(int value) {
|
||||||
@ -139,12 +151,13 @@ public class GameMap {
|
|||||||
public boolean isPassable(List<Point> list){
|
public boolean isPassable(List<Point> list){
|
||||||
return list.stream().allMatch(p -> isPassable(p.x, p.y));
|
return list.stream().allMatch(p -> isPassable(p.x, p.y));
|
||||||
}
|
}
|
||||||
public boolean isPassable(int x, int y) {
|
|
||||||
int row = getRow(y);
|
public boolean isPassable(int screenX, int screenY) {
|
||||||
int col = getCol(x);
|
int row = screenToRow(screenY);
|
||||||
int tileY = (y - OFFSET_Y) % MAP_TILESIZE;
|
int col = screenToCol(screenX);
|
||||||
int tileX = (x - OFFSET_X) % MAP_TILESIZE;
|
int tileY = (screenY - OFFSET_Y) % MAP_TILESIZE;
|
||||||
log.trace("Point[x="+x+",y="+y+"] is row="+ row + ", col=" + col + " with reminder x=" +tileX+",y=" +tileY);
|
int tileX = (screenX - OFFSET_X) % MAP_TILESIZE;
|
||||||
|
log.trace("Point[x={},y={}] is row={}, col={} with reminder x={},y={}", screenX, screenY, row, col, tileX, tileY);
|
||||||
|
|
||||||
boolean[][] mask = mapData[row][col].getCollisionMask();
|
boolean[][] mask = mapData[row][col].getCollisionMask();
|
||||||
boolean b = mask == null || !mask[tileY][tileX];
|
boolean b = mask == null || !mask[tileY][tileX];
|
||||||
@ -152,36 +165,9 @@ public class GameMap {
|
|||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getCol(int x) {
|
|
||||||
return (x - OFFSET_X) / MAP_TILESIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getRow(int y) {
|
|
||||||
return (y - OFFSET_Y) / MAP_TILESIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getHeight() {
|
|
||||||
return GamePanel.SCREEN_HEIGHT;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeTileImage(Point destination) {
|
|
||||||
int row = getRow(destination);
|
|
||||||
int col = getCol(destination);
|
|
||||||
MapTile tile = mapData[row][col];
|
|
||||||
if(tile.getValue() == 0) tile.setImage(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getCol(Point point) {
|
|
||||||
return getCol(point.x);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getRow(Point point) {
|
|
||||||
return getRow(point.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSolid(Point pos) {
|
public boolean isSolid(Point pos) {
|
||||||
int row = getRow(pos);
|
int row = screenToRow(pos);
|
||||||
int col = getCol(pos);
|
int col = screenToCol(pos);
|
||||||
return isSolid(row,col);
|
return isSolid(row,col);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,11 +180,61 @@ public class GameMap {
|
|||||||
return solid;
|
return solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int columns() {
|
public void removeTileImage(Point destination) {
|
||||||
return mapData[0].length;
|
int row = screenToRow(destination);
|
||||||
}
|
int col = screenToCol(destination);
|
||||||
public int rows() {
|
MapTile tile = mapData[row][col];
|
||||||
return mapData.length;
|
if(tile.getValue() == 0) tile.setImage(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int screenToCol(Point point) {
|
||||||
|
return screenToCol(point.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int screenToRow(Point point) {
|
||||||
|
return screenToRow(point.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int columns() {
|
||||||
|
return MAP_COL_SIZE;
|
||||||
|
}
|
||||||
|
public int rows() {
|
||||||
|
return MAP_ROW_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int colToWorldX(int col){
|
||||||
|
return col * GameMap.MAP_TILESIZE + GameMap.OFFSET_X;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int rowToWorldY(int row){
|
||||||
|
return row * GameMap.MAP_TILESIZE + GameMap.OFFSET_Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int worldXtoCol(int x){
|
||||||
|
return x / GameMap.MAP_TILESIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int worldYtoRow(int y){
|
||||||
|
return y / GameMap.MAP_TILESIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Point coordToWorld(int row, int col){
|
||||||
|
return new Point(colToWorldX(col), rowToWorldY(row));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Point worldToScreen(Point world){
|
||||||
|
return new Point(world.x + OFFSET_X, world.y + OFFSET_Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Point screenToWorld(Point screen){
|
||||||
|
return new Point(screen.x - OFFSET_X, screen.y - OFFSET_Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int screenToCol(int screenX) {
|
||||||
|
return (screenX - OFFSET_X) / MAP_TILESIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int screenToRow(int screenY) {
|
||||||
|
return (screenY - OFFSET_Y) / MAP_TILESIZE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user