Skip to content

Tower Factory

karthikeya-v edited this page Oct 3, 2023 · 66 revisions

Introduction

Everything that exists in the game is an Entity. Entities on their own cannot do anything as much but act as containers in which components can be added which inevitably gives them their functionality and character. One of the main entities to be created in the game are Towers. In order to create tower entities and provide them with relevant components, a TowerFactory class has been implemented. The following part of this page explains how everything works in the TowerFactory class.

The UML diagram below offers a hierarchical perspective on the construction of various towers. It demonstrates the utilization of a foundational entity generated through the createBaseTower() method, as well as the incorporation of distinct components into specific tower construction methods.

Screenshot 2023-09-11 001857

Base Tower function: createBaseTower()

The function createBaseTower is in charge of assigning fundamental functional components such as the collider component, hitbox component, and Physics components that are identical for all entities. This function creates a base entity that can be further given special components. All the required components can be added simply by .addComponent() method.

An example of adding a ColliderComponent() to the tower entity.

Entity tower = new Entity()
    .addComponent(new ColliderComponent());

Creating a WeaponTower createWeaponTower()

This function uses the base entity created by createBaseTower function mentioned above and adds the (here add the link to added tasks)AITaskComponent, AnimationRenderComponent and all other components required by the weaponTower entity.

The AITaskComponent adds a new TowerCombatTask() to the tower entity. The TowerCombatTask changes state of the tower and also triggers events for animations to take place at different states of the tower. The animationRenderComponent is responsible for the idle, stowing, firing and deploying animations. All the configurations required for the animations are mentioned in the .atlas file at images/turret01.atlas. This is added to the render component which further uses these configs to animate different states of the tower. The following code loads assets from the .atlas file and adds the required animations for the weaponTower:

AnimationRenderComponent animator =
        new AnimationRenderComponent(
                ServiceLocator.getResourceService()
                        .getAsset("images/turret01.atlas", TextureAtlas.class));
animator.addAnimation("idle", 0.3f, Animation.PlayMode.LOOP);
animator.addAnimation("stow", 0.2f, Animation.PlayMode.NORMAL);
animator.addAnimation("deploy", 0.2f, Animation.PlayMode.REVERSED);
animator.addAnimation("firing", 0.25f, Animation.PlayMode.LOOP);

The image used for WeaponTowers/turrets:

turret_deployed

The CombatStatsComponent() and CostComponent() load configs from the configs.weapon file. The values assigned in the config files override the already existing values in the CostComponent() and CombatStatsComponent(). There are 3 files implementing configurations for weaponTower and wallTower. More information on where and how these files work can be found at Config files page. To understand working of config files, please refer to Configuring Entities page.

Finally, the AITaskComponent(), AnimationRenderComponent() CombatStatsComponent() and CostComponent() are added to the base entity created. For more information about how components work you can refer to the Components page.

Creating a wall createWallTower

The Wall tower is initialized using createWallTower function using the same base entity created using createBaseTower. Since the only functionality of wall tower is to obstruct the path of enemies, it does require a aitaskcomponent to constantly update to get the status of death and instead of using a image it uses the idle state in the atlas which is just a loop of one instance to appear as picture but as health reaches 0 it will update to death state and run its death animation and is flagged for delete. These components follow the same functionality path as in createWeaponTower or any other tower in the towerfactory.

wall
        .addComponent(new CombatStatsComponent(config.health, config.baseAttack))
        .addComponent(new CostComponent(config.cost))
        .addcomponent(animator)
        .addcomponent(aiTaskComponent)
        .addComponent(new WallTowerAnimationController());

The png image used for walls:

wallTower

Further Tower Creation

Furthermore complex and unique towers are created using the createBaseTower method. All the newly made towers will have the same component structure but will differ in component values and have different properties.

Droid Tower

The Droid Tower also called the slowing tower, fires projectiles that leave a slow effect on mobs when hit. This tower, along with all the other towers contains the AITaskComponent which adds the DroidCombatTask. The DroidCombatTask performs in a similar fashion to the Tower Combat Task, the only differences being different animation trigger phrases and different states in the finite state machine. Since the Droid Tower showcases attack animations from both top and bottom, the following states have been included to depict full animations:

AnimationRenderComponent animator =
        new AnimationRenderComponent(
                ServiceLocator.getResourceService()
                        .getAsset(DROID_ATLAS, TextureAtlas.class));

animator.addAnimation(IDLE_ANIM, DROID_SPEED, Animation.PlayMode.NORMAL);
animator.addAnimation(SHOOT_UP,DROID_SPEED, Animation.PlayMode.NORMAL);
animator.addAnimation(SHOOT_DOWN,DROID_SPEED, Animation.PlayMode.NORMAL);
animator.addAnimation(WALK_ANIM,DROID_SPEED, Animation.PlayMode.NORMAL);
animator.addAnimation(DEATH_ANIM,DROID_SPEED, Animation.PlayMode.NORMAL);
animator.addAnimation(GO_UP,DROID_SPEED, Animation.PlayMode.NORMAL);
animator.addAnimation(GO_DOWN,DROID_SPEED, Animation.PlayMode.NORMAL);

The DOWN and UP animations handle the up and down movement of turret of Droid tower. All the triggered animations by the Droid Combat Task are animated by Droid Animation Controller. This allows implementation of a unique strategy that can be effective against variety of mobs. Furthemore, shoot animations handle the firing animation once the turret enters respective up/down state. Complete animations executed in a sequential order look something like the following:

Droid Tower

Further down, the specific properties of the Droid Tower are added using the CombatStatsComponent and CostComponent which retrieve values from the config file.

TNT Tower

The TNT tower also adds a new mechanic to the game. since the nature of the tower includes hiding in the ground until enemies/mobs approach closer, this tower is impervious to damages caused by mob projectiles. When the mobs get sufficiently close, the tower explodes taking nearby mobs (or at least damaging them) along with it. This unique feature provides a offensive but currency extensive strategy to the player as once the tower explodes, it is deleted from the map and only new instances of the tower can be added making the tower a one-time use.

The functioning of the TNT tower is very similar to other towers, starting with the base Entity created using the createBaseTower and adding relevant components further down. A new combat task, named TNT Tower CombatTask is made that handles all the state transitions and animation triggering via a finite state machine and is added using the AITaskComponent. Further down, the AnimationRenderComponent adds the required animations specifying the animation speed and animation type which are executed by TNT Animation Controller. When all the animations are played in the correct order, they appear something like:

TNT Tower

Further down, tower specific stats are loaded using CombatStatsComponent and CostComponent from the config file. In addition to all other components a new TNT Damage Component is added that deals with the infliction of damage on the mobs. At the end all other required components along with instantiated (AnimationRender and AITaskComponent) are added.

Fire Tower

The Fire Tower derives its name from its unique ability to launch projectiles that leave a lingering "burn" effect upon impact. For a deeper understanding of the fire projectile mechanics, please refer to the Effects Component. This tower adheres to the same component architecture as other towers. Differences from other towers include a different configuration file(for health, attack damage and cost of the tower), a different combat Task for animation triggering and projectile spawning, and a different animationController (FireTowerAnimationController identical in functionality as Tower Animation Controller). All the different configurations from the config file are loaded using the CombatStatsComponent and the CostComponent. Similar to other towers, the AiTaskComponent adds FireTowerCombatTask and handles switching states of the tower along with triggering animations. The animations triggered by the combat task are observed by the AnimationRenderComponent which performs the animations based on the triggers. When performed sequentially, these animations, including the death animation, create the following visual sequence:

Fire Tower

Stun Tower

The stun tower, as its name suggests, fires a projectile that induces stun upon hitting its target. Further details regarding the functionality of the stun projectile can be found on the Effects Component page. This tower adheres to the same component structure, with varying values for health, attack damage, and cost being loaded from the config file. The AiTaskComponent associated with this tower is responsible for executing the StunTowerCombatTask, which functions similarly to the previously mentioned FireTowerCombatTask. It employs a finite state machine via the updateTowerState method to manage the tower's state and trigger animations. Just as before, the AnimationRenderComponent actively listens for these events and executes the necessary animations. Ultimately, the sequential order of animations appears as follows:

Stun Tower

Fireworks Tower

The fireworks tower fires a projectile that splits on contact with its target. It was chosen that the projectile would split into 3 smaller projectiles upon contact. Further details regarding the functionality of the split fireworks projectile can be found on the Projectile Factory page. This tower adheres to the same component structure as the other towers. However, it has its own config file (which is used to assign health, attack damage and cost values) and combat task (which is used to dictate how the tower behaves). The FireworksTowerCombatTask functions similarly to the above mentioned StunTowerCombatTask. It also employs a finite state machine via the updateTowerState method to manage the tower's state and trigger animations. Just as before, the AnimationRenderComponent actively listens for these events and executes the necessary animations. states of fireworks tower

Pierce Tower

The pierce tower fires a projectile that pierces through targets and does not dissipate upon contact. Further functionality of the pierce projectile can be found on the Projectile Factory page. The component structure of this tower adheres to the precedent set by the other towers. Similarly to the fireworks tower it has its own config file and combat task; which are used to set stats for the tower and to set the behaviour of the tower respectively. The PierceTowerCombatTask functions similarly to the StunTowerCombatTask. It also similarly uses the updateTowerState method to employ a state machine which manages the tower's state and trigger animations. These events are actively listened for by the AnimationRenderComponent which, in turn, executes the necessary animations. Idle state of pierce tower

Ricochet Tower

The ricochet tower fires a projectile that upon contact does damage and changes direction. The Projectile Factory page can be read to gain understanding about further functionality. This tower adheres to the component structures of the other towers. It also, like the previous towers, has its own config file (used for setting the health, attack damage and cost values) and combat task (which tells the tower how to behave). The RicochetTowerCombatTask was built off of the code for the StunTowerCombatTask and as such functions similarly. The tower also employs a finiste state machine via the updatTowerState mehod to manage the tower's state and trigger animations. Just as before, the AnimationRenderComponent actively listens for these events and executes the necessary animations. Idle state of pierce tower

Sequential Diagrams

TNT Tower

The following sequential UML diagram explains the life cycle of the TNT tower.

sequential diagram for TNT Tower

Clone this wiki locally