import java.awt.*; /** * Player — pure data class. * *

Holds position, velocity, input state, sprite frames, and hitbox. No Swing, no game logic — * GamePanel owns all of that. */ public class Player { // ── Identity ────────────────────────────────────────────────────────────── public final boolean isSeal; // false = bear, true = seal public String name = ""; // ── Position & physics ──────────────────────────────────────────────────── public int x, y; public int velocityY = 0; public int speed = 5; public boolean onGround = false; // ── Input flags (set by GamePanel's KeyListener) ────────────────────────── public boolean left, right, up; // ── Hitbox (offset inward from sprite top-left) ─────────────────────────── public final Rectangle hitbox = new Rectangle(5, 10, 20, 30); // ── Sprite animation ────────────────────────────────────────────────────── public Image[] walkFrames; public int currentFrame = 0; // ── Constructor ─────────────────────────────────────────────────────────── public Player(boolean isSeal, Image[] frames) { this.isSeal = isSeal; this.walkFrames = frames; } // ── Helpers ─────────────────────────────────────────────────────────────── /** Returns the current animation frame, or null if no sprites loaded. */ public Image currentSprite() { if (walkFrames == null || walkFrames.length == 0) return null; return walkFrames[currentFrame]; } /** Moves the player to (x, y) and repositions the hitbox to match. */ public void setPosition(int x, int y) { this.x = x; this.y = y; syncHitbox(); } /** Call after any manual change to x or y to keep the hitbox aligned. */ public void syncHitbox() { hitbox.setLocation(x + 5, y + 10); } /** Advance animation frame; typically called every N game-loop ticks. */ public void nextFrame() { if (walkFrames != null && walkFrames.length > 1) currentFrame = (currentFrame + 1) % walkFrames.length; } /** Reset to idle (frame 0). */ public void idleFrame() { currentFrame = 0; } /** Clear all movement input flags — call on level reset. */ public void clearInput() { left = right = up = false; } }