Combat Animation Foundation - UQcsse3200/2026-studio-3 GitHub Wiki

Combat Animation Foundation

1. Overview

When a card is played, a short visual plays on the target based on the resolved effect type. The system is split into two layers:

  • Rendering components — reusable "how to draw" logic. Not tied to any specific effect; any teammate's effect can use any of these.
  • Registration files — each teammate's own file, where they decide which rendering component to use for which effect type, and with what parameters (colour, size, duration, etc.).

This split means rendering logic is shared and rarely changes, while each person's own design choices live in their own file with no risk of conflicts.

2. Core files

EffectVisualStyle.java

A plain data record describing how one visual looks: icon path (or null for a generated glow), colour, duration, start/end scale, and upward drift. Used by the Icon Scale & Fade rendering component below.

EffectVisualRegistry.java

A lookup table mapping EffectType to its visual style. Each teammate registers their own effect types into this shared registry from their own file. Unregistered types fall back to a default glow instead of crashing.

BattleAnimationCoordinator.java

Listens to the battle system's existing card-effect events. When a card resolves, it looks up each effect's style from the registry, spawns the right visual on the right target (single enemy, all enemies, or the player), staggers multiple effects in time so they don't overlap, and cleans up finished visuals automatically. Already wired into BattleScreen; nothing else needs to touch it.

3. Rendering styles — one file per style

Each style is its own independent component file. If your effect fits one of these, reuse it (just register your own parameters — colour, size, duration — in your own registration file). Before building a new rendering style, check this table first and post in the group chat — don't build a new one without checking, so we don't end up with two components doing the same thing.

Style File Good for
Icon Scale & Fade EffectVisualComponent.java A single icon that grows and fades — most status/buff effects (shield for Block, heart for Heal, etc.)
Burst / Particles EffectBurstComponent.java Several small particles fly outward and fade — used for Damage (round dots) and Sunder (jagged spinning shards with a downward drop). Shape and gravity are per-effect parameters, not hardcoded — see the owning registration file for how to configure a new combination.
Path / Slash EffectProjectileComponent.java A slim shape travels from an offset point, through the target, to another offset point, fading as it goes — used for Pierce. Direction, reach and travel speed are constructor parameters, tuned per-effect in the registration file rather than in this component.

More styles will be added to this table as they're built — if what you need isn't here yet, that's expected; just check with the group before starting one.

4. How to register your own effect

public final class YourEffectVisuals {
  public static void registerAll(EffectVisualRegistry registry) {
    registry.register(
        EffectType.YOUR_TYPE,
        new EffectVisualStyle("icon/path.png", Color.YOUR_COLOUR, duration, startScale, endScale, rise));
  }
}

Then in BattleScreen, add one line calling your registerAll(effectVisualRegistry) next to the existing registration calls — nothing else to change.

5. Offensive effect visuals (Damage, Pierce, Sunder)

Effect Style Look Demo
Damage Burst / Particles (EffectBurstComponent, ParticleShape.DOT) Round orange-red dots scatter outward and fade damage
Pierce Path / Slash (EffectProjectileComponent) A slim white blade slashes through the target, fading as it travels pierce
Sunder Burst / Particles (EffectBurstComponent, ParticleShape.SHARD, gravity on) Grey jagged shards spin, fly out, then fall like broken armour sunder2

6. Player effect visuals (Block, Fortify, Heal, Strength, Energy Gain, Cleanse)

Effect Style Look Demo
Block Icon (EffectVisualComponent) A shield icon grows over the player, drifts slightly upward and fades Block effect
Fortify Icon (EffectVisualComponent) A fortify icon swells larger than Block's, with only a slight upward drift, then fades Fortify effect (Iron Oath)
Heal Icon (EffectVisualComponent) A heal icon grows and floats clearly upward as it fades, reading as health rising Heal effect (Bandage)
Strength Icon (EffectVisualComponent) A buff icon swells to 1.5× in place with no drift, reading as powering up (placeholder art: enemy buff intent icon) Strength effect (Inner Focus)
Energy Gain Burst / Particles (EffectBurstComponent, ParticleShape.DOT) Yellow sparks scatter outward and shrink away to nothing Energy Gain effect (Astral Ward)
Cleanse Burst / Particles (EffectBurstComponent, ParticleShape.SHARD, gravity on) Purple shards spin off the player and fall away, like debuffs dropping off Cleanse effect (Purify)

7.Enemy Status Effect Animations(POISON, VULNERABLE, FEEBLE)

Effect Style Look Demo
Poison Animated green bubbles and wisps Bright green bubbles gather around the enemy, expand and break apart in a repeating cycle. POISON
Vulnerable Animated cracked shield A red shield appears over the enemy, develops glowing cracks and breaks into fragments. VULNERABLE
Feeble Animated downward chevrons and wisps Stacked purple downward-pointing shapes appear over the enemy, surrounded by curling purple wisps. FEEBLE
Two active statuses Two animated effects on an elliptical orbit The red Vulnerable shield and purple Feeble effect move around the enemy while continuing their individual animations.(Only one of the possible two-status combinations is shown.) TWO_STATUS_EFFECTS
Three active statuses Three animated effects on an elliptical orbit Green Poison bubbles, the red Vulnerable shield and the purple Feeble effect move around the enemy, remaining upright as they animate. THREE_STATUS_EFFECTS

Enemy Attack Movement

EnemyAnimationController.java moves the enemy forward and back while playing available attack frames. BattleController waits through runAfterAttack() before advancing to the next enemy. Movement does not apply additional damage.

8.Effect Visual System

How a card effect becomes an on-screen animation.

1. Registration & Lookup

classDiagram
    class EffectType {
        <<enumeration>>
        DAMAGE
        BLOCK
        HEAL
        POISON
        VULNERABLE
        FEEBLE
        STRENGTH
        SUNDER
        ENERGY_GAIN
        PIERCE
        CLEANSE
        FORTIFY
        +usesDuration() boolean
    }

    class EffectVisualStyle {
        <<record>>
        +String iconPath
        +Color color
        +float duration
        +float startScale
        +float endScale
        +float rise
    }

    class EffectVisualRegistry {
        -Map~EffectType, EffectVisualStyle~ styles
        +register(type, style) void
        +lookup(type) EffectVisualStyle
    }

    class OffensiveEffectVisuals {
        <<registrar>>
        +registerAll(registry)$ void
    }
    class PlayerEffectVisuals {
        <<registrar>>
        +registerAll(registry)$ void
    }
    class EnemyStatusEffectVisuals {
        <<registrar>>
        +registerAll(registry)$ void
    }

    OffensiveEffectVisuals ..> EffectVisualRegistry : register
    PlayerEffectVisuals ..> EffectVisualRegistry : register
    EnemyStatusEffectVisuals ..> EffectVisualRegistry : register
    EffectVisualRegistry ..> EffectVisualStyle : stores
    EffectVisualRegistry ..> EffectType : keys by
Loading

Each effect type's visual style is registered into a shared lookup table used at runtime.

2. Runtime Dispatch

classDiagram
    class BattleAnimationCoordinator {
        -BattleController controller
        -CardEffectHandler effectHandler
        -EffectVisualRegistry registry
        +create() void
        +update() void
        -spawnVisual(type, target, startDelay, playApplication) void
    }
    class RenderComponent {
        <<abstract>>
    }
    class EffectVisualComponent {
        -Texture texture
        -float baseSize
        -float startDelay
        +isExpired() boolean
        #draw(batch) void
    }
    class EffectBurstComponent {
        -boolean hasGravity
        -ParticleShape shape
        +isExpired() boolean
        #draw(batch) void
    }
    class EffectProjectileComponent {
        -float travelAngleDeg
        -float reach
        +isExpired() boolean
        #draw(batch) void
    }
    class EnemyStatusEffectVisualComponent {
        -Entity target
        -EffectType statusType
        -TextureRegion[] frames
        ~represents(target, type) boolean
        ~replay(delay) void
        +isExpired() boolean
    }

    BattleAnimationCoordinator ..> EffectVisualComponent : else default
    BattleAnimationCoordinator ..> EffectBurstComponent : usesBurst
    BattleAnimationCoordinator ..> EffectProjectileComponent : usesProjectile
    BattleAnimationCoordinator ..> EnemyStatusEffectVisualComponent : supports
    EffectVisualComponent --|> RenderComponent
    EffectBurstComponent --|> RenderComponent
    EffectProjectileComponent --|> RenderComponent
    EnemyStatusEffectVisualComponent --|> RenderComponent
Loading

Based on the effect type, dispatches to the matching visual component to play the animation.

⚠️ **GitHub.com Fallback** ⚠️