-
Notifications
You must be signed in to change notification settings - Fork 1
Combat Animal Animations
The combat animation system in our game currently supports two animation states: IDLE and MOVE. These animations are controlled by the CombatAnimationController
component and are used for both player and enemy entities in the Combat Screen.
- IDLE animations are automatically started when entities are added to the Combat Screen.
- MOVE animations are triggered when the player interacts with Move buttons (Attack, Guard, Sleep, or Items). MOVE animations are replaced by IDLE animations when a combat turn is being processed by the UI.
An example of IDLE and MOVE animations for the Enemy Frog can be seen in this video demonstration.
This class is responsible for switching between combat animations and controlling the direction entities are facing. It listens to events and triggers the appropriate animation.
public class CombatAnimationController extends Component {
AnimationRenderComponent animator;
@Override
public void create() {
super.create();
animator = this.entity.getComponent(AnimationRenderComponent.class);
entity.getEvents().addListener("idleLeft", this::animateIdleLeft);
entity.getEvents().addListener("idleRight", this::animateIdleRight);
entity.getEvents().addListener("moveLeft", this::animateMoveLeft);
entity.getEvents().addListener("moveRight", this::animateMoveRight);
}
private void animateIdleLeft() {
if (this.entity.getEnemyType() != Entity.EnemyType.BEE) {
animator.setFlipX(true);
}
animator.startAnimation("combat_idle");
}
private void animateIdleRight() {
animator.setFlipX(false);
animator.startAnimation("combat_idle");
}
private void animateMoveLeft() {
if (this.entity.getEnemyType() != Entity.EnemyType.BEE) {
animator.setFlipX(true);
}
animator.startAnimation("combat_move");
}
private void animateMoveRight() {
animator.setFlipX(false);
animator.startAnimation("combat_move");
}
}
This class is responsible for creating entity instances for various animals in the Combat Screen. It provides a base method createCombatBaseEnemy()
which is used by specific entity creation methods.
public class CombatAnimalFactory {
private static final NPCConfigs configs =
FileLoader.readClass(NPCConfigs.class, "configs/enemyNPCs.json");
public static Entity createCombatBaseEnemy(BaseEnemyEntityConfig config, Entity.EnemyType type) {
Entity entity = new Entity()
.addComponent(new PhysicsComponent())
.addComponent(new ColliderComponent());
PhysicsUtils.setScaledCollider(entity, 0.9f, 0.4f);
entity.setEnemyType(type);
TextureAtlas textureAtlas = ServiceLocator.getResourceService().getAsset(config.getSpritePath(), TextureAtlas.class);
AnimationRenderComponent animator = new AnimationRenderComponent(textureAtlas);
animator.addAnimation("combat_idle", 0.8f, Animation.PlayMode.LOOP);
animator.addAnimation("combat_move", 0.2f, Animation.PlayMode.LOOP);
entity.addComponent(animator)
.addComponent(new CombatAnimationController());
return entity;
}
// Example of a specific enemy creation method
public static Entity createChickenCombatEnemy() {
BaseEnemyEntityConfig config = configs.chicken;
Entity chickenEnemy = createCombatBaseEnemy(config, Entity.EnemyType.CHICKEN);
chickenEnemy.scaleHeight(110.0f);
return chickenEnemy;
}
// Other enemy creation methods...
}
Changes in animations (between IDLE and MOVE) are triggered from this class. Specifically, the functions startEnemyAnimation(CombatAnimation animation)
and startPlayerAnimation(CombatAnimation animation)
are called from CombatButtonDisplay.java
.
public void startEnemyAnimation(CombatAnimation animation) {
switch (animation) {
case IDLE:
enemyDisplay.getEvents().trigger("idleLeft");
break;
case MOVE:
enemyDisplay.getEvents().trigger("moveLeft");
break;
}
}
combatArea.startEnemyAnimation(CombatArea.CombatAnimation.IDLE);
combatArea.startEnemyAnimation(CombatArea.CombatAnimation.MOVE);
classDiagram
class Entity {
+addComponent(Component)
+getComponent(Class)
+setEnemyType(EnemyType)
}
class Component {
+create()
}
class CombatAnimationController {
-AnimationRenderComponent animator
+create()
-animateIdleLeft()
-animateIdleRight()
-animateMoveLeft()
-animateMoveRight()
}
class AnimationRenderComponent {
+setFlipX(boolean)
+startAnimation(String)
+addAnimation(String, float, PlayMode)
}
class CombatAnimalFactory {
+createCombatBaseEnemy(BaseEnemyEntityConfig, EnemyType)
+createChickenCombatEnemy()
+createMonkeyCombatEnemy()
+createFrogCombatEnemy()
}
Entity "1" *-- "many" Component
CombatAnimationController --|> Component
CombatAnimationController --> AnimationRenderComponent
CombatAnimalFactory ..> Entity : creates
CombatAnimalFactory ..> CombatAnimationController : adds
sequenceDiagram
participant CombatScreen
participant CombatAnimalFactory
participant Entity
participant CombatAnimationController
participant AnimationRenderComponent
CombatScreen->>CombatAnimalFactory: createChickenCombatEnemy()
CombatAnimalFactory->>Entity: new Entity()
CombatAnimalFactory->>Entity: addComponent(AnimationRenderComponent)
CombatAnimalFactory->>Entity: addComponent(CombatAnimationController)
CombatAnimalFactory-->>CombatScreen: return chickenEnemy
CombatScreen->>Entity: getEvents().trigger("idleLeft")
Entity->>CombatAnimationController: animateIdleLeft()
CombatAnimationController->>AnimationRenderComponent: setFlipX(true)
CombatAnimationController->>AnimationRenderComponent: startAnimation("combat_idle")
CombatScreen->>Entity: getEvents().trigger("moveRight")
Entity->>CombatAnimationController: animateMoveRight()
CombatAnimationController->>AnimationRenderComponent: setFlipX(false)
CombatAnimationController->>AnimationRenderComponent: startAnimation("combat_move")
To use the combat animation system, e.g. add combat animal animations to a new enemy entity:
- Define
combat_idle
andcombat_move
animations in the entity's texture atlas. - Create enemy entities using the
CombatAnimalFactory
methods. - Ensure the necessary textures (sprite sheet image file) and texture Atlases are loaded into the
CombatArea
byCombatAreaConfig.java
. - Changes in animations will be triggered centrally from the
CombatArea
.
- The player is placed on the left side of the combat screen and faces right, while enemies face left.
- The
CombatAnimationController
handles flipping the entity sprite based on the direction it should face. - Special handling is implemented for the Bee enemy type, because it faces a different side in the sprite sheet.
- Animation speeds and entity scaling can be adjusted in the
CombatAnimalFactory
for each specific enemy type.
To create new types of animation sequences
- Define a new animation key in the relevant entity's texture atlas.
- Add the new animation to the
AnimationRenderComponent
in theCombatAnimalFactory
. - Add the new animation key to the enum in
CombatArea
and the switch case instartPlayerAnimation()
and/orstartEnemyAnimation()
of theCombatArea
. - Call the animation start functions with the new combat animation keys from the
CombatButtonDisplay
.