-
Notifications
You must be signed in to change notification settings - Fork 1
Animations for Air Boss
The Griffin (Air) boss is an enemy in the game with animations reflecting it flying:
Gust of Wind, which Griffin shoots toward player while flying away.
/**
* This class listens to events related to the Boss entity's state and plays the appropriate animation
* when one of the events is triggered. The Boss has animations for wandering and chasing in both the
* left and right directions.
*/
public class BossAnimationController extends Component {
// Animation render component responsible for playing animations
private AnimationRenderComponent animator;
/**
* Called when the component is created. Sets up listeners for the Boss movement events
* and links them to corresponding animation triggers.
*/
@Override
public void create() {
super.create();
// Retrieves the AnimationRenderComponent from the entity
animator = this.entity.getComponent(AnimationRenderComponent.class);
// Set up listeners for movement-related events and assign appropriate animations
entity.getEvents().addListener("wanderLeft", this::animateWanderLeft);
entity.getEvents().addListener("wanderRight", this::animateWanderRight);
entity.getEvents().addListener("chaseLeft", this::animateChaseLeft);
entity.getEvents().addListener("chaseRight", this::animateChaseRight);
}
/**
* Plays the wander animation with the entity facing left by flipping the animation on the X-axis.
*/
private void animateWanderLeft() {
animator.setFlipX(true);
animator.startAnimation("wander");
}
/**
* Plays the wander animation with the entity facing right (default direction).
*/
private void animateWanderRight() {
animator.setFlipX(false);
animator.startAnimation("wander");
}
/**
* Plays the chase animation with the entity facing left by flipping the animation on the X-axis.
*/
private void animateChaseLeft() {
animator.setFlipX(true);
animator.startAnimation("chase");
}
/**
* Plays the chase animation with the entity facing right (default direction).
*/
private void animateChaseRight() {
animator.setFlipX(false);
animator.startAnimation("chase");
}
}
/**
* Creates a boss NPC to be used as a boss entity by more specific NPC creation methods.
*
* @param target the entity to chase
* @param type the type of the boss
* @return entity
*/
public static Entity createBossNPC(Entity target, Entity.EnemyType type, BaseEnemyEntityConfig config) {
AnimationRenderComponent animator =
new AnimationRenderComponent(
ServiceLocator.getResourceService().getAsset(config.getSpritePath(), TextureAtlas.class));
animator.addAnimation("wander", 0.1f, Animation.PlayMode.LOOP);
animator.addAnimation("chase", 0.1f, Animation.PlayMode.LOOP);
Entity npc = new Entity()
.addComponent(animator)
.addComponent(new BossAnimationController());
return npc;
}
public class WindGustAnimationController extends Component {
AnimationRenderComponent animator;
@Override
public void create() {
super.create();
animator = this.entity.getComponent(AnimationRenderComponent.class);
entity.getEvents().addListener("ProjectileMove", this::animateWaterSpiral);
}
private void animateWaterSpiral() {
animator.startAnimation("windGust");
}
}
public static Entity createWindGust(Entity target) {
Entity windGust = createBaseProjectile(target);
BaseEnemyEntityConfig config = configs.windGust;
AITaskComponent aiTaskComponent = new AITaskComponent();
aiTaskComponent.addTask(new ProjectileMovementTask(target, 10));
windGust.addComponent(aiTaskComponent);
TextureAtlas windGustAtlas = ServiceLocator.getResourceService().getAsset(config.getSpritePath(), TextureAtlas.class);
AnimationRenderComponent animator = new AnimationRenderComponent(windGustAtlas);
animator.addAnimation("windGust", 0.1f, Animation.PlayMode.LOOP);
windGust
.addComponent(animator)
.addComponent(new WindGustAnimationController());
windGust.setScale(5.0f, 5.0f);
windGust.getComponent(PhysicsMovementComponent.class).changeMaxSpeed(new Vector2(config.getSpeed(), config.getSpeed()));
return windGust;
}
Visual Testing - https://youtu.be/yU9CXT3zjS0
AttackOnAnimals.-.Bosses.Visual.Test.-.Sprint.3.mov
For visual confirmation of the animations and behaviour of the Griffin (Air Boss) and its Wind Gust projectile, a video recording was created to ensure the following aspects are functioning as intended:
-
Wander Animation (Griffin): The Griffin boss flies around its designated area when not engaged with the player. The animation smoothly reflects its wandering state, with correct left and right flipping depending on the direction of its movement.
-
Chase Animation (Griffin): When the player is detected, the Griffin boss transitions into a chase animation. The animation runs smoothly, with the boss flipping its orientation based on the direction it is chasing, ensuring there are no visible glitches.
-
Wind Gust Animation: The special ability of the Griffin allows it to shoot a gust of wind toward the player while flying. This animation was confirmed to play correctly, with the projectile following a smooth and accurate trajectory toward the player.
All these animations were visually confirmed in the gameplay environment and documented through the video above. This method of visual testing compensates for the limitations of automated testing in areas of graphical rendering, ensuring that the animations behave as expected in a live game scenario.
The automated testing results show that the Boss Factory and related systems for the Griffin boss have a 76.4% code coverage, focusing primarily on logic and functionality. The remaining 23.6% of the code, which is not covered by tests, mainly deals with the visual rendering of animations and effects, which have been verified through the visual testing mentioned above.
- Line Coverage: 76.0% — This measures how much of the executable code has been tested. The uncovered lines are primarily related to graphical rendering, which is better tested visually rather than through automation.
- Bugs: 0 — No bugs were identified in the code.
- Vulnerabilities: 0 — No security vulnerabilities were detected, ensuring that the system is secure and reliable.
- Code Smells: 7 — These refer to minor inefficiencies in the code that could be improved for better readability and maintainability. However, none of these affect the performance or functionality of the game.