Enemies' Features - UQcsse3200/2023-studio-2 GitHub Wiki

Overview

Responsible for enemy movement, skins, spawning and damaging other entities (such as player, extractors, ship). Enemies may have attack methods that change between planets and spawning speeds may be variable (linear difficulty, exponential difficulty, etc.)

Enemy Types

Enemies can have two different types:

  • EnemyType.Melee Melee enemies will only damage entities when they collide with the specific entity they target.
  • EnemyType.Ranged Ranged enemies will fire a projectile when they get within a set distance where the projectile will deal damage when it collides with the target entity.

Enemy Behaviours

Enemies can also have two different behaviours:

  • EnemyBehaviour.PTE PTE stands for Player-Targeting-Enemy which means the enemy will prioritise the player over other targetable entities on the game area. If the player becomes invisible then the enemy will target the next priority
  • EnemyBehaviour.DTE DTE stands for Destructible-Targeting-Enemy which means the enemy will prioritise destructible entities like extractors and turrets. If there are no extractors or turrets in the game area the enemies will then target the player.

How to spawn enemies

  1. Decide on Enemy Look and Name:

    • Look: Decide on the appearance or sprite of your enemy.
    • Name: Choose a name for your enemy. For example:
      • Look:
      • Name: Necromancer
  2. Create Spritesheet:

    • Create a spritesheet for your enemy with both a PNG image and an atlas file.
    • Create a new folder in the "images" directory with the name of your enemy. For example:
      • Create a folder named "Necromancer" under "images" so that the directory becomes "images/Necromancer."
      • Screenshot 2023-10-11 at 7 02 16 pm
  3. Define Enemy Stats and Behavior in enemy.json:

    • Configure your enemy's stats, type, and behavior in the "enemy.json" file. This step defines your enemy's characteristics and abilities.
    • Screenshot 2023-10-11 at 6 45 05 pm
  4. Add your new enemy to the EnemyName enum for config selection:

    • Add your name enum to the class constructor and the getter function for string selection of your name enum.

    • Screenshot 2023-10-11 at 7 12 19 pm
  5. Add Atlas Path to main.json:

    • Include the path to your enemy's atlas file in the "main.json" file for the levels where you want to spawn your enemy. For instance, if you want to add the Necromancer to the Earth level, update the relevant section in "levels/earth/main_area/main.json."
    • Screenshot 2023-10-11 at 6 55 47 pm
  6. Spawn the Enemy via Spawner:

    • To spawn your enemy in the game, you'll use a spawner entity placed on the map. Spawners are configured in the level's configuration files.

    • Access the "spawners.json" file for the specific level where you want to spawn your enemy. In the example, the Necromancer is added to "levels/earth/main_area/entities/spawners.json."

    • Screenshot 2023-10-11 at 6 50 42 pm
    • In the spawners configuration, you can specify three types of enemies to spawn per wave in order. Adjust the quantity of each enemy by modifying the number next to its name.

This process allows you to customize and spawn enemies in your game world.

Enemy functionalities

Dropping Mechanic (Sprint 2)

At death enemy entity drop a random power potion. https://github.com/UQcsse3200/2023-studio-2/assets/138426092/8fa3407f-19f5-49aa-a826-eb187dfee554

Animations

Animation types

Each specific enemy animation was retrieved online with free copyright access and usages.
The followings are some examples on animation sequence for base melee enemy:

image

To achieve a moving image, the animator components were set to loop through this sequence at 0.05 - 0.3f/second.

Invisibility (Sprint 4)

The InvisibilityComponent is a class in our game that provides invisibility functionality to an enemy. This component allows the entity to toggle between invisible and visible states, affecting its movement speed and triggering events when the invisibility state changes.

Invis.mp4

targetComponent Class

The targetComponent class is a component that manages the targeting and behavior of enemy NPCs within a game. It is responsible for updating the targets and behaviors of these NPCs based on the specified configuration and AI tasks.

Methods

public void create()
public void updateTargets()

The create method is used to initialize the targetComponent by adding an event listener to reevaluate and update the targets. The updateTargets method is responsible for updating the targets of the enemy NPCs. It disposes of the current AI component and retrieves a list of target entities based on their HitboxComponent. It then assigns specific behaviors to each of these target entities using the EnemyFactory.enemyBehaviourSelector method.

Directional Animations (Sprint 2)

Player position dictates the direction that the enemy is facing. This applies for chasing, attacking and standing animation. The new animation controllers loop through different sequences for both left and right motions to give the effect that the enemy is actively tracking the player.

The enemy direction is calculated using the getDirection() method and the animations are triggered respectively. Example: HitBoxComponent();

Animation Implementation (Sprint 1)

Different types of animation can be added to an animator which is then attached to an enemy entity object

image

Specific animations are triggered by a listener

image

Trigger:

image

Autonomous enemy animation triggers with moving direction:

- This includes standing, moving left and right.(Modified version of wandering task)

Other currently available actions and not limited to: : - Death - Attack - Explode (used for bullet entity) This animator component can be reused for all enemies that will be created later including adding a larger variety of animations. Further development for animations: 4 directionals Larger animations pool Complex and interactive animation with surrounding objects Bullets:

image

Audio

Death Component

The DeathComponent is a class that is part of the game development framework and is used to handle the death and disposal of entities within a game. Typically, it is attached to killable entities. When the health of the entity reaches zero, this component orchestrates the entity's death, including playing a death animation, disposing of the entity, and potentially spawning power-up items. This wiki provides an overview of the DeathComponent class and its functionality.

Class Structure
The DeathComponent class is structured as follows:

package com.csse3200.game.components;

// Import statements...

public class DeathComponent extends Component {
    private CombatStatsComponent combatStats;
    private Boolean notkilled;
    private boolean isDying = false;

    @Override
    public void create() {
        // Initialization and event listener setup...
    }

    public void kill(int health) {
        // Handling the death process...
    }

    public boolean getIsDying() {
        return isDying;
    }
}

Tasks

Task interactions (Sprint 3)

image

ShootTask (Sprint 1)

The shoot task launches a projectile from the owner entity towards a designated target entity. The task's constructor accepts the target enemy as its sole parameter. Once initiated, it uses the target location vector to generate a projectile within the projectile factory. The spawn point of the projectile is then calculated using the owner entity location. If the target entity is above the owner it will be fired up 1 grid point on the y axis from the owner entity's location, otherwise it will be spawned at the owner location. The spawn point is then used to spawn the projectile into the game area.

Example use:

AimTask (Sprint 1)

Aim task causes the enemy to wait and shoot after designated time intervals when added to an enemies aiTaskComponent. It takes in a wait time, target and range parameter. Once this task is started it creates a shoot task utilizing the target entity and wait task utilizing the wait time parameter. The task then continuously cycles through the wait task and shoot task when active.

Example creation and adding to aiComponent:

ChaseTask (Sprint 1)

The chase task was adjusted so it has a shootDistance parameter. This is the distance from where ranged enemies will stop to shoot at the target. This was implemented by setting the base shootDistance to 0 so that this addition will not affect the instances where the original chase task was already used. A new constructor was made which takes in a shootDistance variable and will adjust the base distance accordingly.

BossTask (Sprint 2)

The Boss has one special attack which activates when its health is 50% or below. It will trigger one Bloom of projectiles (Multiple Projectiles expanding outward). The projectiles used are reused entities and assets from the Projectile Entity, refer to Projectile Entities (Link). Once player or structure comes into contact with projectile, it deals damage and explodes.

Boss Task The Boss Task class controls all actions of the Boss, including Movement and Attacking, and Special Attack. Acting like a controller, the Boss Task controls what Task is active for the Boss, and allows for multiple actions to act out when required.

Example: Changing Boss current actions (BossTask)

Boss Special Attack

Release one instances of projectiles, where all directionality of projectiles are predetermined through calculations to form a circle.

Example: Calculating direction for all projectiles (SpecialAttackTask)

Run Task (Sprint 2)

The run task takes in a target entity, run distance and priority as parameters. The task then calculates the distance between the owner entity and target entity. If this distance is below the run distance parameter, the priority is set to the given priority. When active, it will change the speed of the entity and then calculate a new vector position for the entity to run to based on the position of the target with respect to the owner entity. Upon stopping, the entity speed is then set back to the previous speed.

Spray task (Sprint 3):

This task replaces the current chase task where enemy fire bullets that split and spray in multiple directs making it challenging to dodge compare to the original single firing mode

Spray.mp4

Spawn task (Sprint 3):

The spawnTask takes in target entity as its sole parameter when being initialized. This will be the target for entities spawned within the task. The task then spawns in enemies using the spawnEnemy function. This function can take in 0, 1 or 2 entities as parameters. The function then takes the entities and spawns them either to the left or right of the owner entity.

Spawn Attack Task (Sprint 3):

The SpawnAttackTask takes in wait time, target entity and priority as parameters. The wait time is the time to wait between spawning entities. The target is the target entity to use when spawning in the additional entities. And the priority is the priority of the task. The task maintains an array list containing all entities which have been spawned using the SpawnAttackTask. The entities are created and added to the list then passed on to the SpawnTask which handles spawning the entities into the game. Once the maximum number of entities has been spawned (currently 2), the task constantly checks and removes all dead entities from the list. If the list then contains less the maximum number of entities, a new one will be created, added to the list and spawned in.

spawn.mp4

God task (Sprint 3):

This task involves firing bullets in a sequential manner with incrementing angles to create a spiraling effect.

Untitled_video_-_Made_with_Clipchamp_11.mp4

Enemy Wiki

Boss PTE: Knight (Sprint 2)

Attack Running Idle Death
image image image image

Range PTE: Necromancer (Sprint 3)

Melee DTE: RoboMan (Sprint 2)

Final boss: Guardian (Sprint 3)

Variance 1 Variance 2 Variance 3
image image image

Melee PTE: Chain (Sprint 3)

Future Development

  • bug fixes
  • animations and audio for a better gaming experience

Component Interactions (Sprint 4)

⚠️ **GitHub.com Fallback** ⚠️