Skip to content

Commit

Permalink
made the tower fireworks from created to working state the tower is c…
Browse files Browse the repository at this point in the history
…urrently spawned in and is using the fireworks projectile and the tower combat has been modified for the charging start and end states created animation controller, atlas files, sprite sheet for the animations.(current tower state : almost finished)
  • Loading branch information
karthikeya-v committed Oct 1, 2023
1 parent 0386c95 commit cacf4fc
Show file tree
Hide file tree
Showing 8 changed files with 659 additions and 33 deletions.
488 changes: 488 additions & 0 deletions source/core/assets/images/towers/fireworks_tower.atlas

Large diffs are not rendered by default.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 18 additions & 4 deletions source/core/src/main/com/csse3200/game/areas/ForestGameArea.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ public class ForestGameArea extends GameArea {
"images/mobboss/demon.png",
"images/mobboss/demon2.png",
"images/mobs/fire_worm.png",
"images/mobboss/patrick.png"
"images/mobboss/patrick.png",
"images/towers/fireworks_tower.png"
};
private static final String[] forestTextureAtlases = {
"images/economy/econ-tower.atlas",
Expand Down Expand Up @@ -154,7 +155,8 @@ public class ForestGameArea extends GameArea {
"images/mobs/wizard.atlas",
"images/mobs/water_queen.atlas",
"images/mobs/water_slime.atlas",
"images/mobboss/patrick.atlas"
"images/mobboss/patrick.atlas",
"images/towers/fireworks_tower.atlas"
};
private static final String[] forestSounds = {
"sounds/Impact4.ogg",
Expand Down Expand Up @@ -274,13 +276,14 @@ public void create() {
//spawnXenoGrunts();
//startWaveTimer();
spawnScrap();
//spawnDeflectXenoGrunt(15, 5);
//spawnSplittingXenoGrunt(15, 4);
spawnDeflectXenoGrunt(15, 5);
spawnSplittingXenoGrunt(15, 4);
spawnScrap();
spawnTNTTower();
spawnWeaponTower();
spawnGapScanners();
spawnDroidTower();
spawnFireWorksTower();

}

Expand Down Expand Up @@ -653,6 +656,17 @@ private void spawnTNTTower() {
spawnEntityAt(weaponTower, randomPos, true, true);
}

}
private void spawnFireWorksTower() {
GridPoint2 minPos = new GridPoint2(0, 2);
GridPoint2 maxPos = terrain.getMapBounds(0).sub(2, 2);

for (int i = 0; i < NUM_WEAPON_TOWERS; i++) {
GridPoint2 randomPos = RandomUtils.random(minPos, maxPos);
Entity FireWorksTower = TowerFactory.createFireworksTower();
spawnEntityAt(FireWorksTower, randomPos, true, true);
}

}

private void spawnDroidTower() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import com.csse3200.game.ai.tasks.DefaultTask;
import com.csse3200.game.ai.tasks.PriorityTask;
import com.csse3200.game.components.CombatStatsComponent;
import com.csse3200.game.components.ProjectileEffects;
import com.csse3200.game.entities.Entity;
import com.csse3200.game.entities.factories.ProjectileFactory;
import com.csse3200.game.physics.PhysicsEngine;
Expand All @@ -27,9 +26,12 @@ public class FireworksTowerCombatTask extends DefaultTask implements PriorityTas
// The type of targets this tower will detect
private static final short TARGET = PhysicsLayer.NPC;
//Following constants are names of events that will be triggered in the state machine
private static final String IDLE = "startIdle";
public static final String ATTACK = "startAttack";
public static final String DEATH = "startDeath";
private static final String IDLE = "idleStart";
public static final String ATTACK = "attackStart";
public static final String DEATH = "deathStart";
public static final String CHARGE_END = "chargeEnd";
public static final String CHARGE_START = "chargeStart";


// Class attributes
private final int priority;
Expand All @@ -42,9 +44,9 @@ public class FireworksTowerCombatTask extends DefaultTask implements PriorityTas
private final RaycastHit hit = new RaycastHit();

public enum STATE {
IDLE, ATTACK, DEATH
Idle,Attack, Death, Charge_start, Charge_end
}
public STATE towerState = STATE.IDLE;
public STATE towerState = STATE.Idle;

/**
* @param priority Task priority when targets are detected (0 when nothing is present)
Expand Down Expand Up @@ -89,35 +91,53 @@ public void update() {
*/
public void updateTowerState() {

if (owner.getEntity().getComponent(CombatStatsComponent.class).getHealth() <= 0 && towerState != STATE.DEATH) {
if (owner.getEntity().getComponent(CombatStatsComponent.class).getHealth() <= 0 && towerState != STATE.Death) {
owner.getEntity().getEvents().trigger(DEATH);
towerState = STATE.DEATH;
towerState = STATE.Death;
return;
}

switch (towerState) {
case IDLE -> {
case Idle -> {
if(isTargetVisible()) {
owner.getEntity().getEvents().trigger(CHARGE_START);
towerState = STATE.Charge_start;
}
}
case Charge_start -> {
if (isTargetVisible()) {
owner.getEntity().getEvents().trigger(ATTACK);
towerState = STATE.ATTACK;
towerState = STATE.Attack;
} else {
owner.getEntity().getEvents().trigger(CHARGE_END);
towerState = STATE.Charge_end;
}
}
case ATTACK -> {
if (!isTargetVisible()) {
owner.getEntity().getEvents().trigger(IDLE);
towerState = STATE.IDLE;

case Charge_end -> {
if (isTargetVisible()) {
owner.getEntity().getEvents().trigger(ATTACK);
towerState = STATE.Attack;
} else {
owner.getEntity().getEvents().trigger(IDLE);
towerState = STATE.Idle;
}
}

case Attack -> {
if (isTargetVisible()) {
owner.getEntity().getEvents().trigger(ATTACK);
Entity newProjectile = ProjectileFactory.createSplitFireWorksFireball(PhysicsLayer.NPC,
// double check if this is the correct projectile to call
new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f),
3);
Entity newProjectile = ProjectileFactory.createFireworks(PhysicsLayer.NPC,
new Vector2(100, owner.getEntity().getPosition().y), new Vector2(2f, 2f));
newProjectile.setPosition((float) (owner.getEntity().getPosition().x + 0.25),
(float) (owner.getEntity().getPosition().y + 0.25));
ServiceLocator.getEntityService().register(newProjectile);
} else {
owner.getEntity().getEvents().trigger(IDLE);
towerState=STATE.Idle;
}
}
case DEATH -> {
case Death -> {
if (owner.getEntity().getComponent(AnimationRenderComponent.class).isFinished()) {
owner.getEntity().setFlagForDelete(true);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.csse3200.game.components.tower;

import com.csse3200.game.components.Component;
import com.csse3200.game.rendering.AnimationRenderComponent;

/**
* This class listens to events relevant to DroidTower entity's state and plays the animation when one
* of the events is triggered.
*/
public class FireworksTowerAnimationController extends Component {
private AnimationRenderComponent animator;

/**
* Creation call for a DroidAnimationController, fetches the animationRenderComponent that this controller will
* be attached to and registers all the event listeners required to trigger the animations and sounds.
*/
@Override
public void create() {
super.create();
animator = this.entity.getComponent(AnimationRenderComponent.class);
entity.getEvents().addListener("idleStart", this::animateDefault);
entity.getEvents().addListener("chargeStart", this::animateChargeStart);
entity.getEvents().addListener("chargeEnd", this::animateChargeEnd);
entity.getEvents().addListener("attackStart", this::animateAttack);
entity.getEvents().addListener("deathStart", this::animateDeath);

}

/**
* the towers starts charging to shoot a projectile
*/
void animateChargeStart() {
animator.startAnimation("Charge");
}

/**
* the towers starts charging to shoot a projectile and after that this
* animation is the wind down of that charging up of the tower
*/
void animateChargeEnd() {
animator.startAnimation("Charge_end");
}

/**
* THIS IS TO SHOW THE TOWER DEATH IN THIS SITUATION THE TOWER GETS BLASTED
*/
void animateAttack() {
animator.startAnimation("Attack");
}


void animateDeath() {
animator.startAnimation("Death");
}


/**
* Triggers the "default" or "Idle animation for the entity.
* This method should be invoked when the entity returns to its default state.
*/
void animateDefault() {
animator.startAnimation("Idle");
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.csse3200.game.entities.configs;

public class HealTowerConfig {
public int health = 1;
public int baseAttack = 0;
public int cost = 1;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ public class baseTowerConfigs {
public FireworksTowerConfig fireworksTower = new FireworksTowerConfig();
public PierceTowerConfig pierceTower = new PierceTowerConfig();
public RicochetTowerConfig ricochetTower = new RicochetTowerConfig();
public HealTowerConfig HealTower = new HealTowerConfig();
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public class TowerFactory {
private static final String TURRET_ATLAS = "images/towers/turret01.atlas";
private static final String FIRE_TOWER_ATLAS = "images/towers/fire_tower_atlas.atlas";
private static final String STUN_TOWER_ATLAS = "images/towers/stun_tower.atlas";
private static final String FIREWORKS_TOWER_ATLAS = "images/towers/fireworks_tower.atlas";
private static final String TNT_ATLAS = "images/towers/TNTTower.atlas";
private static final String DROID_ATLAS = "images/towers/DroidTower.atlas";
private static final float DROID_SPEED = 0.25f;
Expand Down Expand Up @@ -83,6 +84,12 @@ public class TowerFactory {
private static final float STUN_TOWER_ATTACK_SPEED = 0.12f;
private static final String STUN_TOWER_DEATH_ANIM = "death";
private static final float STUN_TOWER_DEATH_SPEED = 0.12f;
private static final String FIREWORKS_TOWER_DEATH_ANIM ="DEATH";
private static final float FIREWORKS_TOWER_ANIM_SPEED = 0.4f;
private static final String FIREWORKS_TOWER_CHARGE_START_ANIM ="Charge";
private static final String FIREWORKS_TOWER_CHARGE_END_ANIM ="Charge_end";
private static final String FIREWORKS_TOWER_IDLE_ANIM ="Idle";
private static final String FIREWORKS_TOWER_ATTACK_ANIM ="Attack";
private static final int INCOME_INTERVAL = 300;
private static final int INCOME_TASK_PRIORITY = 1;
private static final String ECO_ATLAS = "images/economy/econ-tower.atlas";
Expand Down Expand Up @@ -318,22 +325,26 @@ public static Entity createFireworksTower() {
AITaskComponent aiTaskComponent = new AITaskComponent()
.addTask(new FireworksTowerCombatTask(COMBAT_TASK_PRIORITY, WEAPON_TOWER_MAX_RANGE));

// NEED TO MAKE FIREWORKS_TOWER_ATLAS
// AnimationRenderComponent animator =
// new AnimationRenderComponent(
// ServiceLocator.getResourceService()
// .getAsset(FIREWORKS_TOWER_ATLAS, TextureAtlas.class));

AnimationRenderComponent animator =
new AnimationRenderComponent(
ServiceLocator.getResourceService()
.getAsset(FIREWORKS_TOWER_ATLAS, TextureAtlas.class));
animator.addAnimation(FIREWORKS_TOWER_ATTACK_ANIM, FIREWORKS_TOWER_ANIM_SPEED, Animation.PlayMode.NORMAL);
animator.addAnimation(FIREWORKS_TOWER_IDLE_ANIM, FIREWORKS_TOWER_ANIM_SPEED, Animation.PlayMode.LOOP);
animator.addAnimation(FIREWORKS_TOWER_DEATH_ANIM, FIREWORKS_TOWER_ANIM_SPEED, Animation.PlayMode.NORMAL);
animator.addAnimation(FIREWORKS_TOWER_CHARGE_END_ANIM, FIREWORKS_TOWER_ANIM_SPEED, Animation.PlayMode.LOOP);
animator.addAnimation(FIREWORKS_TOWER_CHARGE_START_ANIM, FIREWORKS_TOWER_ANIM_SPEED, Animation.PlayMode.LOOP);

fireworksTower
.addComponent(new CombatStatsComponent(config.health, config.baseAttack))
.addComponent((new CostComponent(config.cost)))
.addComponent(aiTaskComponent);
// NEED TO ADD ANIMATIONS
// .addComponent(animator)
// .addComponent(new FireworksTowerAnimationController());
.addComponent(aiTaskComponent)
.addComponent(animator)
.addComponent(new FireworksTowerAnimationController());

fireworksTower.setScale(1.5f, 1.5f);
PhysicsUtils.setScaledCollider(fireworksTower, 0.5f, 0.5f);
PhysicsUtils.setScaledCollider(fireworksTower, 0.2f, 0.2f);
return fireworksTower;
}

Expand Down Expand Up @@ -384,6 +395,25 @@ public static Entity createRicochetTower() {
PhysicsUtils.setScaledCollider(ricochetTower, 0.5f, 0.5f);
return ricochetTower;
}
public static Entity createHealTower() {
Entity ricochetTower = createBaseTower();
HealTowerConfig config = configs.HealTower;

AITaskComponent aiTaskComponent = new AITaskComponent()
.addTask(new RicochetTowerCombatTask(COMBAT_TASK_PRIORITY, WEAPON_TOWER_MAX_RANGE));

// ADD AnimationRenderComponent

ricochetTower
.addComponent(new CombatStatsComponent(config.health, config.baseAttack))
.addComponent((new CostComponent(config.cost)))
.addComponent(aiTaskComponent);
// ADD ANIMATION COMPONENTS

ricochetTower.setScale(1.5f, 1.5f);
PhysicsUtils.setScaledCollider(ricochetTower, 0.5f, 0.5f);
return ricochetTower;
}

/**
* Creates a generic tower entity to be used as a base entity by more specific tower creation methods.
Expand Down

0 comments on commit cacf4fc

Please sign in to comment.