-
Notifications
You must be signed in to change notification settings - Fork 3
Human Enemies and HumanAnimationController
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.
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.
All of the enemies require this Atlas image, if this is missing, then the a NullPointerException
will be thrown and the game will crash.
These are the movement animations that will be used when the any movement task is called.
These are the movement animations that will be used when an attack is called from an attack task.
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;
}
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.
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.
- The chase entity will call the movement with
start()
on the generic MovementClass which will begin the movement - The MovementTask will use the
PhysicsMovementComponent
and this will handle the event trigger back to the entity. - The
HumanAnimationController
class has listeners for the "RightStart" string event which will call the functionanimateRight()
from within the class. - The function
animateRight()
will cause theAnimationRenderComponent
class to animate the movement to the right.
Design Document
- Story
- Music
-
Characters
- Main Character
- Bosses
-
Enemies
- Sprint 1: Final Design
-
Sprint 2: Elvish Boss
- Decision to make our boss a mage
- Design Inspiration: Staff Weapon
- Design decisions for boss
- Archery attack animation for minions
- Different types of minion elves and designs
- Melee attack animation
- Boss attack animation using sceptre
- Design Inspiration: Shooting fireballs
- Mage Boss attack method: fireball
- Sprint 3: Walk Animations and Design Amendments
- Sprint 4: Refining animations
- Map Design
- User + Play Testing
- Gameplay
- Art Style Design Guidelines
- Emotional Goals