133 lines
4.7 KiB
Java
133 lines
4.7 KiB
Java
package se.urmo.game.entities;
|
|
|
|
import lombok.Getter;
|
|
import lombok.Setter;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import se.urmo.game.collision.CollisionChecker;
|
|
import se.urmo.game.util.Direction;
|
|
import se.urmo.game.main.Game;
|
|
import se.urmo.game.map.GameMap;
|
|
import se.urmo.game.util.LoadSave;
|
|
import se.urmo.game.util.MiscUtil;
|
|
|
|
import java.awt.*;
|
|
import java.awt.image.BufferedImage;
|
|
import java.util.Arrays;
|
|
|
|
|
|
@Slf4j
|
|
public class PacMan {
|
|
public static final int PACMAN_SIZE = 32;
|
|
public static final int PACMAN_OFFSET = PACMAN_SIZE / 2;
|
|
private static final int COLLISION_BOX_SIZE = 16;
|
|
private static final int COLLISION_BOX_OFFSET = (PACMAN_SIZE - COLLISION_BOX_SIZE) / 2;
|
|
private final Game game;
|
|
private final Point startPosition;
|
|
private int aniTick = 0;
|
|
private int aniIndex = 0;
|
|
private static final int ANIMATION_UPDATE_FREQUENCY = 10;
|
|
private int speed = 1;
|
|
@Setter
|
|
private boolean moving;
|
|
private final BufferedImage[][] movmentImages = new BufferedImage[4][4];
|
|
@Getter
|
|
private Point position;
|
|
private static final BufferedImage COLLISION_BOX = MiscUtil.createOutlinedBox(COLLISION_BOX_SIZE, COLLISION_BOX_SIZE, Color.yellow, 2);
|
|
private final CollisionChecker collisionChecker;
|
|
@Setter
|
|
@Getter
|
|
private Direction direction = Direction.NONE;
|
|
|
|
public PacMan(Game game, CollisionChecker collisionChecker) {
|
|
this.game = game;
|
|
this.collisionChecker = collisionChecker;
|
|
this.position = new Point(
|
|
26 * GameMap.MAP_TILESIZE + GameMap.OFFSET_X,
|
|
13 * GameMap.MAP_TILESIZE + GameMap.OFFSET_Y + (GameMap.MAP_TILESIZE / 2));
|
|
this.startPosition = this.position;
|
|
loadAnimation();
|
|
}
|
|
|
|
private void loadAnimation() {
|
|
BufferedImage[][] image = new BufferedImage[3][4];
|
|
|
|
BufferedImage img = LoadSave.GetSpriteAtlas("sprites/PacManAssets-PacMan.png");
|
|
for (int row = 0; row < 3; row++) {
|
|
for (int col = 0; col < 4; col++) {
|
|
image[row][col] = img.getSubimage(PACMAN_SIZE * col, PACMAN_SIZE * row, PACMAN_SIZE, PACMAN_SIZE);
|
|
}
|
|
}
|
|
movmentImages[Direction.RIGHT.ordinal()] = image[0];
|
|
movmentImages[Direction.LEFT.ordinal()] = Arrays.stream(image[0])
|
|
.map(i -> LoadSave.rotate(i, 180))
|
|
.toArray(BufferedImage[]::new);
|
|
movmentImages[Direction.DOWN.ordinal()] = Arrays.stream(image[0])
|
|
.map(i -> LoadSave.rotate(i, 90))
|
|
.toArray(BufferedImage[]::new);
|
|
movmentImages[Direction.UP.ordinal()] = Arrays.stream(image[0])
|
|
.map(i -> LoadSave.rotate(i, 270))
|
|
.toArray(BufferedImage[]::new);
|
|
}
|
|
|
|
public void draw(Graphics g) {
|
|
g.drawImage(
|
|
movmentImages[direction==Direction.NONE ? 0 : direction.ordinal()][aniIndex],
|
|
position.x - PACMAN_OFFSET,
|
|
position.y - PACMAN_OFFSET,
|
|
PACMAN_SIZE,
|
|
PACMAN_SIZE, null);
|
|
g.drawImage(COLLISION_BOX, position.x - COLLISION_BOX_OFFSET, position.y - COLLISION_BOX_OFFSET, COLLISION_BOX_SIZE, COLLISION_BOX_SIZE, null);
|
|
//g.setColor(Color.BLUE);
|
|
//g.fillRect(position.x-1, position.y-1, 3, 3);
|
|
}
|
|
|
|
public void update() {
|
|
updateAnimationTick();
|
|
if(moving) {
|
|
Point newPosition = switch (direction) {
|
|
case RIGHT -> new Point(position.x + speed, position.y);
|
|
case LEFT -> new Point(position.x - speed, position.y);
|
|
case UP -> new Point(position.x, position.y - speed);
|
|
case DOWN -> new Point(position.x, position.y + speed);
|
|
default -> throw new IllegalStateException("Unexpected value: " + direction);
|
|
};
|
|
log.debug("At: {},trying to move {} to {}", position, direction.name(), newPosition);
|
|
Point destination = collisionChecker.getValidDestination(direction, newPosition, COLLISION_BOX_SIZE, COLLISION_BOX_SIZE);
|
|
|
|
if (destination != null) {
|
|
position = destination;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void updateAnimationTick() {
|
|
if (moving) {
|
|
aniTick++;
|
|
if (aniTick >= ANIMATION_UPDATE_FREQUENCY) {
|
|
aniTick = 0;
|
|
aniIndex++;
|
|
if (aniIndex >= 4) {
|
|
aniIndex = 0;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
public double distanceTo(Point point) {
|
|
return position.distance(point);
|
|
}
|
|
|
|
public void loseLife() {
|
|
|
|
}
|
|
|
|
public void resetPosition() {
|
|
position = startPosition;
|
|
}
|
|
|
|
public Image getLifeIcon() {
|
|
return movmentImages[0][1];
|
|
}
|
|
}
|