Player Animations - UQcsse3200/2026-studio-4 GitHub Wiki

Player Animations

Author: @YCQinBob (Bob)
Task #86. Do not replace this page wholesale; file an issue for corrections.

Author @YCQinBob
Feature Core Player Actions (#5)
Tasks #84 idle/walk · #85 melee clips · #86 this wiki · #87 JUnit
Branch core-player-features
Repo draft source/docs/player-animations.md

Scope

How the player sprite plays idle, walk, and melee slash clips.

Movement, dash, and weaponAttack already exist in PlayerActions (#5). This work only plays atlas clips so facing matches walk and swing.

Not this page: hitboxes, sword damage, Charm pickup, inventory, stats HUD, the engine Animations tutorial.

Intended flow

  1. Load images/idle_down.atlas (idle_down.png, page 768×1280).
  2. PlayerFactory registers looping idle_* / walk_* and one-shot attack_*.
  3. Spawn in idle_down.
  4. WASD → walkDown / walkLeft / walkRight / walkUp.
  5. Release → idle* for the last walk direction.
  6. J → attack, then weaponAttack with last facing (default down).
  7. PlayerAnimationController plays attack_* once, ignores idle/walk until the clip ends, then restores the last locomotion clip.

Diagonal facing: vertical wins (same as walk).

Controls

After Start, click the game window. Use an English layout. Do not focus the F1 terminal.

Input Events Animation
W / A / S / D walk then walkUp / walkLeft / walkDown / walkRight loop walk_*
Release WASD walkStop then idle* loop last-facing idle_*
J attack → weaponAttack + Vector2 one-shot attack_*, then idle/walk
Space dash movement only; no dash clip
K specialAttack sound only; no clip; does not fire weaponAttack

Desktop default is the keyboard factory. Arrows / touch-down attack are TouchPlayerInputComponent.

Clip map

Events are camelCase; atlas names are snake_case.

Event Atlas clip
idleDown idleLeft idleRight idleUp idle_down idle_left idle_right idle_up
walkDown walkLeft walkRight walkUp walk_down walk_left walk_right walk_up
weaponAttack + facing attack_down attack_left attack_right attack_up

Attack facing (animateAttack: y first, then x):

Vector Clip
y < 0 attack_down
y > 0 attack_up
y == 0 and x < 0 attack_left
y == 0 and x > 0 attack_right
(0, 0) attack_down

Example: down-right walk → walk_down; J → attack_down.

Timing (PlayerFactory)

Clips Frame time Mode
idle_* walk_* 0.1s LOOP
attack_* 0.06s NORMAL (8 frames ≈ 0.48s; sword cooldown 0.5s)

A second J while attacking is ignored. All names must be addAnimation’d before startAnimation("idle_down").

Component contract

PlayerAnimationController listens on the player only. It does not spawn hitboxes.

  • While attacking, idle/walk only store the next clip name.
  • When AnimationRenderComponent.isFinished(), locomotion resumes.
  • Does not listen to dash or specialAttack.

See (do not overwrite): PlayerActions · PlayerAnimationController · Animations

Code

File
Controller PlayerAnimationController.java
Registration PlayerFactory.java
Events (existing; tests added) PlayerActions.java
Atlas source/core/assets/images/idle_down.atlas, idle_down.png

Tests for this work (not inventory/Charm): PlayerAnimationControllerTest, PlayerActionsTest, extra WASD/J/K/Space on KeyboardPlayerInputComponentTest (E was already on the branch), TouchPlayerInputComponentTest.

Automated verification

Run from source with JDK 21:

./gradlew :core:test --tests com.csse3200.game.components.player.PlayerAnimationControllerTest --tests com.csse3200.game.components.player.PlayerActionsTest --tests com.csse3200.game.components.player.KeyboardPlayerInputComponentTest --tests com.csse3200.game.components.player.TouchPlayerInputComponentTest