Skip to content

Vulture

ZarifHilman edited this page Oct 21, 2026 · 3 revisions

← Back to Enemies

Description

Vulture is the only flying-type enemy in the game. It is the fastest entity within the game and has the lowest hit points. Unlike the Skeleton Warrior, it performs a collision attack where damage will be triggered upon getting in contact with the player hit box.

The Vulture uses a flying AI behaviour that allows it to pursue the player in two dimensions without the ground-edge restrictions used by ground-based enemies. Its combat behaviour combines contact damage, knockback, and repositioning after a successful attack, creating a hit-and-retreat fighting pattern.

Enemy Stat

Stat Values
HP 20
Damage 2
Attack Type Melee (contact attack)
Attack Range 1.0
Speed 2.5
Maximum Speed 4.5
Behaviour Flying
Gravity Disabled
View Distance 6.0
Maximum Chase Distance 12.5
Chase Priority 10
Reposition Priority 25
Reposition Distance 3.0
Wander Range X 4.0
Wander Range Y 0.0
Wander Wait Time 1.0
Knockback Force 10.0
Contact Attack Interval 0.25 seconds

The enemy's values are configured in core/assets/configs/Enemies.json. The contact attack interval and knockback behaviour are implemented in TouchAttackComponent.java.

Components

EnemyFactory.java

The main class responsible for creating enemies.

The Vulture is created through the createVulture(Entity target) method, which uses the shared createEnemy() method to initialise common enemy components and AI tasks.

public static Entity createVulture(Entity target) {
    EnemyConfig config = configs.vulture;
    Entity vulture = createEnemy(target, config);

    AnimationRenderComponent animator =
        new AnimationRenderComponent(
            ServiceLocator.getResourceService()
                .getAsset("images/enemies/vulture.atlas", TextureAtlas.class));

    animator.addAnimation("walk", 0.15f, Animation.PlayMode.LOOP);
    animator.addAnimation("idle", 0.15f, Animation.PlayMode.LOOP);

    vulture
        .addComponent(animator)
        .addComponent(new EnemyAnimationController(target))
        .addComponent(new ChaseSoundComponent("sounds/osprey.ogg", 0.15f));

    vulture.getComponent(AnimationRenderComponent.class).scaleEntity();
    return vulture;
}

The shared enemy factory also provides the Vulture with components for:

  • Physics and movement
  • Collision detection and hitboxes
  • Combat statistics and contact attacks
  • Enemy death handling
  • Health bar rendering
  • Status effects, including poison, burn, and slow
  • Item drops
  • AI task management

The Vulture's movement component uses the configured maximum speed and disables gravity.

ChaseTask.java

The Vulture uses ChaseTask to pursue the player when the player is within its detection range and visible.

The task is configured using:

  • Chase priority: 10
  • View distance: 6.0
  • Maximum chase distance: 12.5
  • Behaviour: "flying"

When inactive, the chase task becomes eligible if the player is within the view distance and has an unobstructed line of sight.

While chasing, the Vulture continuously updates its movement target to the player's current position.

Unlike ground enemies, flying enemies do not initialise or use the ground-edge detector in this task. This allows the Vulture to pursue the player without stopping at platform edges.

The task stops being eligible when the player exceeds the maximum chase distance or is no longer visible.

TouchAttackComponent.java

The Vulture performs contact-based melee attacks rather than using a separate melee attack task.

The shared enemy factory adds:

new TouchAttackComponent(PhysicsLayer.PLAYER, 10f)

Here:

  • PhysicsLayer.PLAYER restricts valid attack targets to the player layer.
  • 10f represents the knockback force, not attack damage.
  • Attack damage comes from the Vulture's configured baseAttack value of 2.

When the Vulture's hitbox collides with a valid target, the component tracks the collision and attempts an attack after a delay of 0.25 seconds.

If the collision continues, further attacks can occur at the same interval.

When an attack is performed against a target with CombatStatsComponent, the component:

  1. Applies knockback away from the Vulture if the target has a physics body.
  2. Calls the target's combat statistics to apply the attack.
  3. Sets a flag to emit the hitPlayer event on a subsequent update.

When contact ends, the component clears the tracked collision and resets the contact timer.

RepositionTask.java

The Vulture uses RepositionTask to move away from the player after performing a contact attack.

The task listens for the hitPlayer event emitted by TouchAttackComponent.

The Vulture's repositioning configuration is:

  • Reposition priority: 25
  • Reposition distance: 3.0
  • Behaviour: "flying"

When the event is received, the task requests repositioning.

When started, it calculates a direction away from the player and sets a movement destination approximately three world units from its current position.

For flying enemies, the direction is calculated in two dimensions, allowing movement both horizontally and vertically.

Unlike ground enemies, the flying reposition task skips ground-edge detection.

The reposition priority of 25 is higher than the chase priority of 10, allowing the AI task scheduler to prioritise repositioning when requested.

WanderTask.java

The Vulture is also assigned a WanderTask through the shared enemy factory.

Its configuration includes:

  • Horizontal wander range: 4.0
  • Vertical wander range: 0.0
  • Wander wait time: 1.0
  • Behaviour: "flying"

This provides an alternative movement task when higher-priority AI tasks are not selected.

PhysicsMovementComponent.java

The Vulture uses PhysicsMovementComponent to move towards the destinations supplied by its AI tasks.

The shared enemy factory constructs the component using the configured maximum speed:

new PhysicsMovementComponent(
    new Vector2(config.maxSpeed, config.maxSpeed),
    config.gravity)

For the Vulture:

  • Maximum movement speed is configured as 4.5 on each axis.
  • Gravity is disabled.
  • Movement tasks can specify two-dimensional destinations.

Animation and Sound

The Vulture uses AnimationRenderComponent with the following texture atlas:

images/enemies/vulture.atlas

The factory registers two looping animations:

Animation Frame Duration Play Mode
walk 0.15 seconds LOOP
idle 0.15 seconds LOOP

EnemyAnimationController is responsible for controlling the enemy's animations.

The Vulture also includes:

new ChaseSoundComponent("sounds/osprey.ogg", 0.15f)

This attaches a chase-related sound component using the osprey.ogg audio asset.

AI Behaviour

The Vulture combines three movement behaviours with its contact attack:

  1. Wandering: The Vulture has a configured wandering task.
  2. Chasing: When the player is within detection range and visible, the Vulture can chase the player's position.
  3. Contact Attack: When the Vulture's hitbox remains in contact with the player, it can inflict damage and knockback.
  4. Repositioning: A contact attack triggers hitPlayer, requesting movement away from the player.
  5. Resuming AI: After repositioning finishes, the AI scheduler can select another eligible task.

This creates an intended hit-and-retreat pattern rather than a stationary melee attack.

Testing

The Vulture relies on shared enemy components and AI tasks. The following unit test classes provide relevant coverage, although the inspected tests are not dedicated Vulture integration tests.

TouchAttackComponentTest.java

This class tests the shared contact attack component.

Verified test cases include:

Test Purpose
shouldAttack Confirms contact attacks damage valid targets
shouldNotAttackOtherLayer Confirms targets on other physics layers are ignored
shouldNotAttackWithoutCombatComponent Checks safe handling of targets without combat statistics
shouldNotHurtUntilTheyHaveBeenTouchingForALittleWhile Verifies the contact attack delay
shouldKeepAnnouncingHitsWhileTheyStayInContact Verifies repeated hitPlayer events during continued contact
shouldStopHurtingOnceTheContactEnds Verifies attacks stop after contact ends
shouldIgnoreContactsThatAreNotWithItsOwnHitbox Verifies unrelated fixtures do not trigger attacks
shouldAnnounceTheHitOnTheResponsibleEntityWhenGivenOne Verifies hit events are emitted by the designated owner
shouldNotAnnounceAHitOnATargetThatCannotBeHurt Verifies targets without combat stats do not produce hit events
shouldPushTheTargetAwayFromTheAttacker Verifies horizontal knockback direction
shouldPushUpwardWhenTheTargetIsAbove Verifies vertical knockback direction
shouldPushHarderWithMoreKnockback Verifies stronger knockback produces greater velocity
shouldNotPushWithoutKnockback Verifies zero knockback does not push the target

RepositionTaskTest.java

This class tests repositioning behaviour for ground enemies using the same shared RepositionTask.

Relevant verified tests include:

  • shouldNotWantToRunUntilItHasHitThePlayer
  • shouldWantToRunOnceItHasHitThePlayer
  • shouldKeepItsPriorityWhileRunning
  • shouldClearTheRequestOnceStarted
  • shouldBackAwayFromThePlayerAlongTheFloor
  • shouldFinishOnceItHasReachedItsSpot
  • shouldStopAtALedgeInsteadOfBackingOffIt
  • shouldStopMovingWhenStopped

These tests confirm the task's event activation, priority, retreat movement, and stopping behaviour for ground enemies.

The Vulture-specific flying branch is implemented in RepositionTask.java, but these tests do not directly verify flying repositioning.

ChaseTaskBehaviourTest.java

This class tests ground-based chase behaviour, including:

  • Stopping at ledges on either side
  • Continuing to chase over solid ground
  • Resuming movement when the player moves behind the enemy

These tests cover the shared chase task's ground behaviour.

The Vulture uses the "flying" branch of ChaseTask.java, which skips ground-edge detection. The inspected test class does not directly test that flying branch.

Testing Limitations

The inspected test files verify shared components and ground-based AI behaviour. They do not establish that the complete Vulture chase, attack, knockback, and retreat sequence has been tested together.

Dedicated flying-enemy tests would provide stronger coverage of:

  • Flying chase movement
  • Two-dimensional repositioning
  • Contact attacks followed by retreat
  • AI task transitions between chasing and repositioning

Sprite

vulture_fly

The Vulture's sprite animations are loaded from images/enemies/vulture.atlas.

Relevant Source Files

  • core/assets/configs/Enemies.json
  • core/src/main/com/csse3200/game/entities/factories/EnemyFactory.java
  • core/src/main/com/csse3200/game/components/TouchAttackComponent.java
  • core/src/main/com/csse3200/game/components/tasks/ChaseTask.java
  • core/src/main/com/csse3200/game/components/tasks/RepositionTask.java
  • core/src/main/com/csse3200/game/components/tasks/WanderTask.java
  • core/src/test/com/csse3200/game/components/TouchAttackComponentTest.java
  • core/src/test/com/csse3200/game/components/tasks/RepositionTaskTest.java
  • core/src/test/com/csse3200/game/components/tasks/ChaseTaskBehaviourTest.java

Clone this wiki locally