Skip to content

How Animation Works

Harikesha Suresh edited this page Sep 11, 2022 · 1 revision

Introduction

This is a guide on using the EntityDirectionComponent and direction setting logic in PhysicsMovementComponent to animate your character, may that be animations for movement or attacks, the following animation directions can be achieved.

  • North
  • South
  • East
  • West

Entity Direction Component

This is a simple component attached to any entity that requires keeping track of which direction it's pointing in, it uses a simple enum EntityDirection to store the four compass direction; NORTH, SOUTH, EAST, WEST, DEFAULT, where DEFAULT is set upon initialising the component and changed to the appropriate direction in PhysicsMovementComponent.

UML

image

How it works

  1. Add the animation when creating your entity as follows:
AnimationRenderComponent animator =
        new AnimationRenderComponent(
            ServiceLocator.getResourceService().getAsset("images/blue_joker.atlas", TextureAtlas.class));

    animator.addAnimation(MOVE_EAST, 0.1f, Animation.PlayMode.LOOP);
    animator.addAnimation(MOVE_WEST, 0.1f, Animation.PlayMode.LOOP);
    animator.addAnimation(MOVE_SOUTH, 0.1f, Animation.PlayMode.LOOP);
    animator.addAnimation(MOVE_NORTH, 0.1f, Animation.PlayMode.LOOP);
    animator.addAnimation("default", 1f, Animation.PlayMode.NORMAL);

    animator.addAnimation(ATTACK_NORTH, 0.1f, Animation.PlayMode.LOOP);
    animator.addAnimation(ATTACK_SOUTH, 0.1f, Animation.PlayMode.LOOP);
    animator.addAnimation(ATTACK_EAST, 0.1f, Animation.PlayMode.LOOP);
    animator.addAnimation(ATTACK_WEST, 0.1f, Animation.PlayMode.LOOP);

    blueJoker
              .addComponent(new CombatStatsComponent(config.troops, config.health, config.baseAttack,
                                                     config.baseDefence, config.landSpeed, config.range))
              .addComponent(animator)
              .addComponent(new EnemyAnimationController());

    blueJoker .getComponent(AnimationRenderComponent.class).scaleEntity();
  1. The animation controller class must be written in the following manner, UML diagram of EnemyAnimationController is presented as an example of how an animation controller for movable units should be structured.

image

The create function must be populated as follows

@Override
    public void create() {
        super.create();
        animator = this.entity.getComponent(AnimationRenderComponent.class);
        entity.getEvents().addListener("goWest", this::animateWest);
        entity.getEvents().addListener("goEast", this::animateEast);
        entity.getEvents().addListener("goNorth", this::animateNorth);
        entity.getEvents().addListener("goSouth", this::animateSouth);

        entity.getEvents().addListener("default", this::defaultAnimation);

        entity.getEvents().addListener("attackNorth", this::attackNorth);
        entity.getEvents().addListener("attackSouth", this::attackSouth);
        entity.getEvents().addListener("attackWest", this::attackWest);
        entity.getEvents().addListener("attackEast", this::attackEast);
    }

Example animation method

// Under EnemyAnimationController class
public void animateWest(){ animator.startAnimation("move-west"); }

The only mandatory animation events that need to be added are first five ("goWest" - "default"), as these are triggered in physics movement component for movement animations, the last four are specific to enemy units and can be replaced (or not) with events specific to your actions.

(Make sure that your movement events are labelled as goWest, goEast, goNorth and goSouth)

  1. Once the EntityDirectionComponent is added to an entity and animation controller has been made, the PhysiscsMovementComponent sets the direction if it has changed by triggering the following movement animation events upon setting a new direction:

    • "goWest"
    • "goEast"
    • "goSouth"
    • "goNorth"
  2. In addition we've made an attempt at implementing attack animation, this is done in TouchAttackComponent by checking for the direction the entity is in and triggering its respective attack animation.

// Excerpt from TouchAttackComponent
// isAtacking is a private boolean set to false by default
// Should be from line 70 onwards.
if (targetStats != null) {
      targetStats.hit(combatStats);
      if (targetStats.getHealth() > 0) {
        if (!isAttacking) {
          isAttacking = true;
          switch (entityDirectionComponent.getEntityDirection()) {
            case DEFAULT:
              break;
            case WEST:
              entity.getEvents().trigger("attackWest");
              break;
            case EAST:
              entity.getEvents().trigger("attackEast");
              break;
            case NORTH:
              entity.getEvents().trigger("attackNorth");
              break;
            case SOUTH:
              entity.getEvents().trigger("attackSouth");
              break;
          }
        }
      } else {
        isAttacking = false;
//        target.dispose();
      }
    }

A similar sequence can be done for worker components when they're mining or building something.

Additional Notes

  • Make sure your .atlas files has an entry for default or else this will cause runtime errors.

Table of Contents

Home

Game

Game Home

Design Influences

Gameplay Features

Style

Story

Friendly Units
Map
City
Buildings
Unit Selections

Spell

Game User Testing: Theme of Unit Selection & Spell System

UI User Testing

Tutorial

Resource Stats Display

Loading Screen Bar

Health Bars
In Game menu
  • Feature
  • User Testing:In Game Menu

Landscape Tile Design

Landscape Tile Design Feedback

Weather Design

Weather Design Feedback

Camera Movement

Enemy design

Enemy Units

Enemy AI

How Animation Works

Map Flooding

Game Engine

Getting Started

Entities and Components

Service Locator

Loading Resources

Logging

Unit Testing

Debug Terminal

Input Handling

UI

Animations

Audio

AI

Physics

Game Screens and Areas

Terrain

Concurrency & Threading

Settings

Troubleshooting

MacOS Setup Guide

Clone this wiki locally