Repository navigation
Enemy Animation Sprites
Part of the Enemies feature. Ticket: New Enemy Sprites.
Enemies are drawn with an AnimationRenderComponent backed by a libGDX texture atlas. EnemyAnimationController chooses the animation from the enemy's state. This page covers the atlas format, how each enemy is sized and animated, and how to add animations for a new enemy.
Each enemy has a .atlas file and a PNG sheet in assets/images/enemies/.
| Region | Purpose |
|---|---|
default |
Required. scaleEntity() fails without it. It points at the idle frame. |
walk |
Looping walk cycle, one region per frame, indexed from 0. |
idle |
A single frame. It points at the middle walk frame, so nothing is duplicated in the PNG. |
attack / sweep / hurt / laser
|
Optional, one-shot animations, only for the enemies that use them. |
Notes:
- All frames of one enemy sit on the same canvas size, with the feet on a shared baseline and the body at a shared pivot. This stops the sprite jittering or shifting when it flips to face the player.
- Filtering is
Nearest,Nearest, so pixel art stays sharp. - Region names are global within an atlas file. Use the same names across enemies, but keep one
defaultper file.
| Enemy | Atlas | Animations | Frame size (px) |
|---|---|---|---|
| Skeleton warrior | skeleton_warrior.atlas |
walk (5), attack (5), idle
|
346×316 |
| Skeleton archer | skeleton_archer.atlas |
walk (12), idle
|
300×392 |
| Necromancer | necromancer.atlas |
walk (10), idle
|
308×392 |
| Calypso | calypso.atlas |
idle, walk, sweep, hurt, laser
|
see EnemyFactory
|
Plays attack when SweepAttackTask fires attackStart. The frame time is chosen so the thrust frame is showing when the hit lands
Walk and idle only so they have no attack animation.
-
sweepis her melee attack and plays onattackStart. -
hurtplays when she takes damage. -
laseris her phase 2 attack.TimerAttackTaskfireslaserStart, winds up for 0.6s, then spawns a beam entity textured withimages/projectiles/calypso_laser_beam.png. It fireslaserEndwhen it finishes
Frames sit on a wide canvas, for example to fit the warrior's sword thrust or the archer's bow. So EnemyFactory does this for each enemy:
- Calls
animator.scaleEntity(). - Works out the on-screen character height from the player's height.
- Scales the entity to the canvas using body height in pixels, so the character, not the canvas, matches the target height.
- Sizes the collider and hitbox to the body so empty sprite space can't hurt the player.
Each
addAnimation(...)call takes an anchor (x, y in pixels) that matches the pivot in the atlas. This keeps the sprite in place when it mirrors.
EnemyAnimationController listens for events and picks the animation:
- Moving selects
walk, stopped selectsidle. -
attackStartplayssweepif the enemy has one, otherwiseattack. - While an attack animation plays, walk and idle are held until it finishes.
- It flips the sprite with
setFlipXso the enemy faces the player.
- Clean and repack the sheet onto a uniform grid with the feet aligned.
- Create the
.atlaswithdefault,walkandidle, plus any extras. - Add both files to
assets/images/enemies/and register the atlas in the game area's asset list. - In the
createXmethod, add anAnimationRenderComponent, the animations with anchors, and anEnemyAnimationController. - Size the entity from the player's height and shrink the collider and hitbox to the body.
The base sprite art for the skeleton warrior, skeleton archer, necromancer and Calypso was generated with ChatGPT, then edited by the team.
| Asset | Generated with | Our changes |
|---|---|---|
| Enemy walk and attack sheets | ChatGPT | Background removal, frame alignment, repacking onto a uniform grid |
| Calypso laser and hurt sheets, beam sprite | ChatGPT | Background removal, beam cut out of the burst frame, rescaled to match the walk sheet |
The animation code, atlases and sizing logic in EnemyFactory were written by the team.
Entities and Components
Input Handling
Arrow Selection Wheel Arrow Selection Wheel — Sprint 3