-
Notifications
You must be signed in to change notification settings - Fork 4
Slimey Boy
The SlimeyBoyTask is assigned to the slimeyBoy entity which is spawned after the demon boss dies. slimeyBoy is spawned at the same position that the demon boss dies with 500 HP. It then moves towards the closest human entity and does aoe damage based on how much health it has left to all remaining human entities. This task is attached to an AITaskComponent that is associated with the IceBoss entity.
To use SlimeyBoyTask
:
- Create an instance of
SlimeyBoyTask
in MobBossFactory. - Attach it to an
AITaskComponent
instance.
Example:
Entity slimeyBoy = createBaseBoss();
AITaskComponent aiTaskComponent = new AITaskComponent()
.addTask(new SlimeyBoyTask());
slimeyBoy
.addComponent(aiTaskComponent)
.addComponent(new CombatStatsComponent(500, 0))
.addComponent(animator)
.addComponent(new DemonAnimationController());
The update()
and changeState(SlimeState state)
methods manage slimeyBoy's states and transitions. These methods toggle between multiple states described by the SlimeState
enum: TRANSFORM
, MOVE
, and TAKE_HIT
.
- Description: Where the demon boss transforms into a slime.
- Behavior: Triggers the starting transform animation.
-
Transition: After the starting animation is finished, it will automatically change to the
MOVE
state and starts theseekAndDestroy()
function which starts a movement task towards the closest human entity.
- Description: Where slimeyBoy starts moving
-
Behavior: When
targetFound()
returns true, slimeyBoy does aoe damage to all nearby human entities based on how much health it has left. -
Transition: Changes state to
TAKE_HIT
.
- Description: When slimeyBoy reaches its target
- Behavior: After animation is finished, slimeyBoy deletes itself.
- Transition: None.
Method that calls the event that corresponds with the state:
private void animate() {
// Check if same animation is being called
if (prevState.equals(state)) {
return; // skip rest of function
}
switch (state) {
case IDLE -> slimey.getEvents().trigger("idle");
case MOVE -> slimey.getEvents().trigger("move");
case PROJECTILE_EXPLOSION -> slimey.getEvents().trigger("projectile_explosion");
case PROJECTILE_IDLE -> slimey.getEvents().trigger("projectile_idle");
case TAKE_HIT -> slimey.getEvents().trigger("take_hit");
case TRANSFORM -> slimey.getEvents().trigger("transform");
default -> logger.debug("Slimey boy animation {state} not found");
}
prevState = state;
}
NOTE: All the events triggered in this class are captured by event listeners in DemonAnimationController.
This method finds the closest humany entity and starts a movement task towards that entity
private void seekAndDestroy() {
lastTimeBounced = gameTime.getTime() - BOUNCE_TIME;
changeState(SlimeState.MOVE);
targetEntity = ServiceLocator.getEntityService().getClosestEntityOfLayer(
slimey, PhysicsLayer.HUMANS);
Vector2 targetPos;
if (targetEntity == null) {
targetPos = DEFAULT_POS;
} else {
targetPos = targetEntity.getPosition();
}
MovementTask slimeyMovementTask = new MovementTask(targetPos);
slimeyMovementTask.create(owner);
slimeyMovementTask.start();
slimey.getComponent(PhysicsMovementComponent.class).setSpeed(SLIMEY_SPEED);
}
This method checks if slimeyBoy has reached his destination by checking the distance between it and its destination.
private boolean targetFound() {
if (targetEntity == null) {
return false;
}
return currentPos.dst(targetEntity.getPosition()) < 1;
}
This method checks if slimeyBoy has reached his destination by checking the distance between it and its destination.
private boolean targetFound() {
if (targetEntity == null) {
return false;
}
return currentPos.dst(targetEntity.getPosition()) < 1;
}
This method does damage given to the given array of entities.
private void applyAoeDamage(Array<Entity> targets, int damage) {
for (int i = 0; i < targets.size; i++) {
Entity targetEntity = targets.get(i);
CombatStatsComponent targetCombatStats = targetEntity.
getComponent(CombatStatsComponent.class);
if (targetCombatStats != null) {
targetCombatStats.hit(damage);
}
}
}