Skip to content

Human Enemies and HumanAnimationController

Jonoym edited this page Oct 4, 2021 · 4 revisions

Human Enemies

The implementation of Human Enemies into the game has required a new Animation Controller as the Elf Animation Controller is very specialised to those enemies. Some differences between these Controllers is that the HumanAnimationController is generalised and can be used without requiring the type of enemy. This allows for much cleaner code and implementation that does not vary within the Atlas files.

HumanAnimationController

The animations types that are required in the Atlas file are shown below. The Atlas file can include extra animations if necessary but there are the minimum animations required to be a functioning enemy within the game.

This component will be added to the existing enemies to define the animations that they will be using. Further information about adding components to the enemy can be found at the page: AI.

default

All of the enemies require this Atlas image, if this is missing, then the a NullPointerException will be thrown and the game will crash.

moveLeft, moveRight, moveUp, moveDown,

These are the movement animations that will be used when the any movement task is called.

EnemyAttackUp, EnemyAttackDown, EnemyAttackLeft, EnemyAttackRight,

These are the movement animations that will be used when an attack is called from an attack task.

backDeath, frontDeath, leftDeath, rightDeath,

The animations that will be played once the enemy has been killed.

These animations will need to be added to the AnimationRenderComponent along with the animation will be looped, determined by Animation.PlayMode.NORMAL or Animation.PlayMode.LOOP as well as the duration of each frame.

A private function has been created in the NPC factory for a default animation settings. The function setHumanAnimations is shown below. The function will require an AnimationRenderComponent and will return itself once the animations have been added to the Component. This component will also need to be added to the Enemy entity.

    private static AnimationRenderComponent setHumanAnimations(AnimationRenderComponent animator) {

        animator.addAnimation("default", 0.2f, Animation.PlayMode.NORMAL);
        animator.addAnimation("moveLeft", 0.2f, Animation.PlayMode.LOOP);
        animator.addAnimation("moveRight", 0.1f, Animation.PlayMode.LOOP);
        animator.addAnimation("moveUp", 0.1f, Animation.PlayMode.LOOP);
        animator.addAnimation("moveDown", 0.1f, Animation.PlayMode.LOOP);
        animator.addAnimation("frontDeath", 0.5f, Animation.PlayMode.NORMAL);
        animator.addAnimation("backDeath", 0.5f, Animation.PlayMode.NORMAL);
        animator.addAnimation("leftDeath", 0.5f, Animation.PlayMode.NORMAL);
        animator.addAnimation("rightDeath", 0.5f, Animation.PlayMode.NORMAL);
        animator.addAnimation("EnemyAttackDown", 0.05f, Animation.PlayMode.NORMAL);
        animator.addAnimation("EnemyAttackUp", 0.05f, Animation.PlayMode.NORMAL);
        animator.addAnimation("EnemyAttackLeft", 0.05f, Animation.PlayMode.NORMAL);
        animator.addAnimation("EnemyAttackRight", 0.05f, Animation.PlayMode.NORMAL);

        return animator;
    }

UML Diagram

Due to the different tasks that the NPCs have, it was difficult to determine the architecture to be used to call the animations, The architecture that was decided on was the use of an EventHandler to implement the Observer pattern. The individual tasks will trigger events within the entity and this entity will receive the events and call the appropriate methods in the HumanAnimationController class. The HumanAnimationController class stores the animator class and will call the appropriate animation changes depending on what has been triggered. Although the tasks do not directly use the HumanAnimationController class as shown in the diagram, in reality, the Task will trigger an event which will be received by the entity and the HumanAnimationController will call the function due to this trigger.

Unlike what is shown in the diagram, the Architecture prevents the coupling between the tasks and the animations so each task does not need to call functions from it directly but through the event system. This means that tasks only needs to trigger the event when an animation is needed and each task class will not require direct access.

image

Sequence Diagram

The Sequence Diagram below has also been created to determine the set of events that should take place to call the animations. This has been used to code what has currently been implemented. The overall diagram shows that the highest priority task will trigger an event to cause the HumanAnimationController to call a method on the animator to animate the movement that is required by the Task.

The sequence diagram below has been used to visualise the events that take place when an NPC entity has ChaseTask as their highest priority and will start to chase the Target Entity in the right direction.

  1. The chase entity will call the movement with start() on the generic MovementClass which will begin the movement
  2. The MovementTask will use the PhysicsMovementComponent and this will handle the event trigger back to the entity.
  3. The HumanAnimationController class has listeners for the "RightStart" string event which will call the function animateRight() from within the class.
  4. The function animateRight() will cause the AnimationRenderComponent class to animate the movement to the right.

image

Table of Contents

Home

Design Document

Design Document

Design Document

Game Engine

Getting Started

Entities and Components

Item Drops from Entities

Service Locator

Loading Resources

Logging

Unit Testing

Debug Terminal

Input Handling

UI

Animations

Audio

AI

Physics

Game Screens and Areas

Terrain

Map Generation

Concurrency & Threading

Settings

Troubleshooting

MacOS Setup Guide

Clone this wiki locally