Skip to content

Slimey Boy

gregchan550 edited this page Oct 3, 2023 · 2 revisions

Overview

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.

Usage

To use SlimeyBoyTask :

  1. Create an instance of SlimeyBoyTask in MobBossFactory.
  2. 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());

State Management: update() and changeState(SlimeState state)

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.

State Descriptions

TRANSFORM
  • 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 the seekAndDestroy() function which starts a movement task towards the closest human entity.
MOVE
  • 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.
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.

Finding closest human entity: seekAndDestroy()

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);
    }

Check if target is reached: targetFound()

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;
    }

Check if target is reached: targetFound()

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;
    }

Apply damage to nearby human entities: applyAoeDamage(Array<Entity> targets, int damage)

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);
            }
        }
    }
Clone this wiki locally