diff --git a/source/core/assets/configs/tower.json b/source/core/assets/configs/tower.json index 004dda33c..b11cf27c6 100644 --- a/source/core/assets/configs/tower.json +++ b/source/core/assets/configs/tower.json @@ -13,5 +13,15 @@ "health": 20, "baseAttack": 0, "cost": 1 + }, + "fireTower": { + "health": 10, + "baseAttack": 10, + "cost": 10 + }, + "stunTower": { + "health": 10, + "baseAttack": 10, + "cost": 10 } } \ No newline at end of file diff --git a/source/core/assets/images/background.png b/source/core/assets/images/background/background.png similarity index 100% rename from source/core/assets/images/background.png rename to source/core/assets/images/background/background.png diff --git a/source/core/assets/images/background1.png b/source/core/assets/images/background/background1.png similarity index 100% rename from source/core/assets/images/background1.png rename to source/core/assets/images/background/background1.png diff --git a/source/core/assets/images/building1.png b/source/core/assets/images/background/building1.png similarity index 100% rename from source/core/assets/images/building1.png rename to source/core/assets/images/background/building1.png diff --git a/source/core/assets/images/building2.png b/source/core/assets/images/background/building2.png similarity index 100% rename from source/core/assets/images/building2.png rename to source/core/assets/images/background/building2.png diff --git a/source/core/assets/images/mountain.png b/source/core/assets/images/background/mountain.png similarity index 100% rename from source/core/assets/images/mountain.png rename to source/core/assets/images/background/mountain.png diff --git a/source/core/assets/images/scrap.png b/source/core/assets/images/economy/scrap.png similarity index 100% rename from source/core/assets/images/scrap.png rename to source/core/assets/images/economy/scrap.png diff --git a/source/core/assets/images/scrapsUI.png b/source/core/assets/images/economy/scrapsUI.png similarity index 100% rename from source/core/assets/images/scrapsUI.png rename to source/core/assets/images/economy/scrapsUI.png diff --git a/source/core/assets/images/Attack_1.png b/source/core/assets/images/mobs/Attack_1.png similarity index 100% rename from source/core/assets/images/Attack_1.png rename to source/core/assets/images/mobs/Attack_1.png diff --git a/source/core/assets/images/Attack_2.png b/source/core/assets/images/mobs/Attack_2.png similarity index 100% rename from source/core/assets/images/Attack_2.png rename to source/core/assets/images/mobs/Attack_2.png diff --git a/source/core/assets/images/Charge_1.png b/source/core/assets/images/mobs/Charge_1.png similarity index 100% rename from source/core/assets/images/Charge_1.png rename to source/core/assets/images/mobs/Charge_1.png diff --git a/source/core/assets/images/Charge_2.png b/source/core/assets/images/mobs/Charge_2.png similarity index 100% rename from source/core/assets/images/Charge_2.png rename to source/core/assets/images/mobs/Charge_2.png diff --git a/source/core/assets/images/Dead.png b/source/core/assets/images/mobs/Dead.png similarity index 100% rename from source/core/assets/images/Dead.png rename to source/core/assets/images/mobs/Dead.png diff --git a/source/core/assets/images/Enabling-5.png b/source/core/assets/images/mobs/Enabling-5.png similarity index 100% rename from source/core/assets/images/Enabling-5.png rename to source/core/assets/images/mobs/Enabling-5.png diff --git a/source/core/assets/images/Enabling.png b/source/core/assets/images/mobs/Enabling.png similarity index 100% rename from source/core/assets/images/Enabling.png rename to source/core/assets/images/mobs/Enabling.png diff --git a/source/core/assets/images/Hurt.png b/source/core/assets/images/mobs/Hurt.png similarity index 100% rename from source/core/assets/images/Hurt.png rename to source/core/assets/images/mobs/Hurt.png diff --git a/source/core/assets/images/Idle.png b/source/core/assets/images/mobs/Idle.png similarity index 100% rename from source/core/assets/images/Idle.png rename to source/core/assets/images/mobs/Idle.png diff --git a/source/core/assets/images/Shot_1.png b/source/core/assets/images/mobs/Shot_1.png similarity index 100% rename from source/core/assets/images/Shot_1.png rename to source/core/assets/images/mobs/Shot_1.png diff --git a/source/core/assets/images/Shot_2.png b/source/core/assets/images/mobs/Shot_2.png similarity index 100% rename from source/core/assets/images/Shot_2.png rename to source/core/assets/images/mobs/Shot_2.png diff --git a/source/core/assets/images/Shutdown.png b/source/core/assets/images/mobs/Shutdown.png similarity index 100% rename from source/core/assets/images/Shutdown.png rename to source/core/assets/images/mobs/Shutdown.png diff --git a/source/core/assets/images/Walk.png b/source/core/assets/images/mobs/Walk.png similarity index 100% rename from source/core/assets/images/Walk.png rename to source/core/assets/images/mobs/Walk.png diff --git a/source/core/assets/images/boss_health.png b/source/core/assets/images/mobs/boss_health.png similarity index 100% rename from source/core/assets/images/boss_health.png rename to source/core/assets/images/mobs/boss_health.png diff --git a/source/core/assets/images/ghost_king.png b/source/core/assets/images/mobs/ghost_king.png similarity index 100% rename from source/core/assets/images/ghost_king.png rename to source/core/assets/images/mobs/ghost_king.png diff --git a/source/core/assets/images/rangeBossRight.atlas b/source/core/assets/images/mobs/rangeBossRight.atlas similarity index 100% rename from source/core/assets/images/rangeBossRight.atlas rename to source/core/assets/images/mobs/rangeBossRight.atlas diff --git a/source/core/assets/images/rangeBossRight.png b/source/core/assets/images/mobs/rangeBossRight.png similarity index 100% rename from source/core/assets/images/rangeBossRight.png rename to source/core/assets/images/mobs/rangeBossRight.png diff --git a/source/core/assets/images/robot.atlas b/source/core/assets/images/mobs/robot.atlas similarity index 100% rename from source/core/assets/images/robot.atlas rename to source/core/assets/images/mobs/robot.atlas diff --git a/source/core/assets/images/robot.png b/source/core/assets/images/mobs/robot.png similarity index 100% rename from source/core/assets/images/robot.png rename to source/core/assets/images/mobs/robot.png diff --git a/source/core/assets/images/satyr.png b/source/core/assets/images/mobs/satyr.png similarity index 100% rename from source/core/assets/images/satyr.png rename to source/core/assets/images/mobs/satyr.png diff --git a/source/core/assets/images/xeno-grunt-attack-1.png b/source/core/assets/images/mobs/xeno-grunt-attack-1.png similarity index 100% rename from source/core/assets/images/xeno-grunt-attack-1.png rename to source/core/assets/images/mobs/xeno-grunt-attack-1.png diff --git a/source/core/assets/images/xeno-grunt-attack-2.png b/source/core/assets/images/mobs/xeno-grunt-attack-2.png similarity index 100% rename from source/core/assets/images/xeno-grunt-attack-2.png rename to source/core/assets/images/mobs/xeno-grunt-attack-2.png diff --git a/source/core/assets/images/xeno-grunt-death-falling.png b/source/core/assets/images/mobs/xeno-grunt-death-falling.png similarity index 100% rename from source/core/assets/images/xeno-grunt-death-falling.png rename to source/core/assets/images/mobs/xeno-grunt-death-falling.png diff --git a/source/core/assets/images/xeno-grunt-death-grounded.png b/source/core/assets/images/mobs/xeno-grunt-death-grounded.png similarity index 100% rename from source/core/assets/images/xeno-grunt-death-grounded.png rename to source/core/assets/images/mobs/xeno-grunt-death-grounded.png diff --git a/source/core/assets/images/xeno-grunt-death.png b/source/core/assets/images/mobs/xeno-grunt-death.png similarity index 100% rename from source/core/assets/images/xeno-grunt-death.png rename to source/core/assets/images/mobs/xeno-grunt-death.png diff --git a/source/core/assets/images/xeno-grunt-falling.png b/source/core/assets/images/mobs/xeno-grunt-falling.png similarity index 100% rename from source/core/assets/images/xeno-grunt-falling.png rename to source/core/assets/images/mobs/xeno-grunt-falling.png diff --git a/source/core/assets/images/xeno-grunt-idle.png b/source/core/assets/images/mobs/xeno-grunt-idle.png similarity index 100% rename from source/core/assets/images/xeno-grunt-idle.png rename to source/core/assets/images/mobs/xeno-grunt-idle.png diff --git a/source/core/assets/images/xeno-grunt-jump-effect.png b/source/core/assets/images/mobs/xeno-grunt-jump-effect.png similarity index 100% rename from source/core/assets/images/xeno-grunt-jump-effect.png rename to source/core/assets/images/mobs/xeno-grunt-jump-effect.png diff --git a/source/core/assets/images/xeno-grunt-jumping.png b/source/core/assets/images/mobs/xeno-grunt-jumping.png similarity index 100% rename from source/core/assets/images/xeno-grunt-jumping.png rename to source/core/assets/images/mobs/xeno-grunt-jumping.png diff --git a/source/core/assets/images/xeno-grunt-knockback.png b/source/core/assets/images/mobs/xeno-grunt-knockback.png similarity index 100% rename from source/core/assets/images/xeno-grunt-knockback.png rename to source/core/assets/images/mobs/xeno-grunt-knockback.png diff --git a/source/core/assets/images/xeno-grunt-melee-attack.png b/source/core/assets/images/mobs/xeno-grunt-melee-attack.png similarity index 100% rename from source/core/assets/images/xeno-grunt-melee-attack.png rename to source/core/assets/images/mobs/xeno-grunt-melee-attack.png diff --git a/source/core/assets/images/xeno-grunt-prep-jump.png b/source/core/assets/images/mobs/xeno-grunt-prep-jump.png similarity index 100% rename from source/core/assets/images/xeno-grunt-prep-jump.png rename to source/core/assets/images/mobs/xeno-grunt-prep-jump.png diff --git a/source/core/assets/images/xeno-grunt-projectile-explosion.png b/source/core/assets/images/mobs/xeno-grunt-projectile-explosion.png similarity index 100% rename from source/core/assets/images/xeno-grunt-projectile-explosion.png rename to source/core/assets/images/mobs/xeno-grunt-projectile-explosion.png diff --git a/source/core/assets/images/xeno-grunt-range-attack.png b/source/core/assets/images/mobs/xeno-grunt-range-attack.png similarity index 100% rename from source/core/assets/images/xeno-grunt-range-attack.png rename to source/core/assets/images/mobs/xeno-grunt-range-attack.png diff --git a/source/core/assets/images/xeno-grunt-range-projectile.png b/source/core/assets/images/mobs/xeno-grunt-range-projectile.png similarity index 100% rename from source/core/assets/images/xeno-grunt-range-projectile.png rename to source/core/assets/images/mobs/xeno-grunt-range-projectile.png diff --git a/source/core/assets/images/xeno-grunt-run-damaged.png b/source/core/assets/images/mobs/xeno-grunt-run-damaged.png similarity index 100% rename from source/core/assets/images/xeno-grunt-run-damaged.png rename to source/core/assets/images/mobs/xeno-grunt-run-damaged.png diff --git a/source/core/assets/images/xeno-grunt-run.png b/source/core/assets/images/mobs/xeno-grunt-run.png similarity index 100% rename from source/core/assets/images/xeno-grunt-run.png rename to source/core/assets/images/mobs/xeno-grunt-run.png diff --git a/source/core/assets/images/xenoGruntDeath.atlas b/source/core/assets/images/mobs/xenoGruntDeath.atlas similarity index 100% rename from source/core/assets/images/xenoGruntDeath.atlas rename to source/core/assets/images/mobs/xenoGruntDeath.atlas diff --git a/source/core/assets/images/xenoGruntMeleeAttack.atlas b/source/core/assets/images/mobs/xenoGruntMeleeAttack.atlas similarity index 100% rename from source/core/assets/images/xenoGruntMeleeAttack.atlas rename to source/core/assets/images/mobs/xenoGruntMeleeAttack.atlas diff --git a/source/core/assets/images/xenoGruntRangedAttack.atlas b/source/core/assets/images/mobs/xenoGruntRangedAttack.atlas similarity index 100% rename from source/core/assets/images/xenoGruntRangedAttack.atlas rename to source/core/assets/images/mobs/xenoGruntRangedAttack.atlas diff --git a/source/core/assets/images/xenoGruntRunning.atlas b/source/core/assets/images/mobs/xenoGruntRunning.atlas similarity index 100% rename from source/core/assets/images/xenoGruntRunning.atlas rename to source/core/assets/images/mobs/xenoGruntRunning.atlas diff --git a/source/core/assets/images/xenoGruntRunningDamaged.atlas b/source/core/assets/images/mobs/xenoGruntRunningDamaged.atlas similarity index 100% rename from source/core/assets/images/xenoGruntRunningDamaged.atlas rename to source/core/assets/images/mobs/xenoGruntRunningDamaged.atlas diff --git a/source/core/assets/images/projectile.png b/source/core/assets/images/projectiles/projectile.png similarity index 100% rename from source/core/assets/images/projectile.png rename to source/core/assets/images/projectiles/projectile.png diff --git a/source/core/assets/images/towers/fire_tower_atlas.atlas b/source/core/assets/images/towers/fire_tower_atlas.atlas new file mode 100644 index 000000000..7c9ce2206 --- /dev/null +++ b/source/core/assets/images/towers/fire_tower_atlas.atlas @@ -0,0 +1,83 @@ + +fire_tower_atlas.png +size: 1024, 64 +format: RGBA8888 +filter: Nearest, Nearest +repeat: none +attack + rotate: false + xy: 122, 2 + size: 58, 58 + orig: 58, 58 + offset: 0, 0 + index: 1 +attack + rotate: false + xy: 302, 2 + size: 58, 58 + orig: 58, 58 + offset: 0, 0 + index: 3 +attack + rotate: false + xy: 422, 2 + size: 58, 58 + orig: 58, 58 + offset: 0, 0 + index: 0 +attack + rotate: false + xy: 602, 2 + size: 58, 58 + orig: 58, 58 + offset: 0, 0 + index: 2 +idle + rotate: false + xy: 62, 2 + size: 58, 58 + orig: 58, 58 + offset: 0, 0 + index: 1 +idle + rotate: false + xy: 182, 2 + size: 58, 58 + orig: 58, 58 + offset: 0, 0 + index: 3 +idle + rotate: false + xy: 362, 2 + size: 58, 58 + orig: 58, 58 + offset: 0, 0 + index: 0 +idle + rotate: false + xy: 542, 2 + size: 58, 58 + orig: 58, 58 + offset: 0, 0 + index: 2 +prep_attack + rotate: false + xy: 2, 2 + size: 58, 58 + orig: 58, 58 + offset: 0, 0 + index: 1 +prep_attack + rotate: false + xy: 242, 2 + size: 58, 58 + orig: 58, 58 + offset: 0, 0 + index: 0 +prep_attack + rotate: false + xy: 482, 2 + size: 58, 58 + orig: 58, 58 + offset: 0, 0 + index: 2 diff --git a/source/core/assets/images/towers/fire_tower_atlas.png b/source/core/assets/images/towers/fire_tower_atlas.png new file mode 100644 index 000000000..a8c5cc3ee Binary files /dev/null and b/source/core/assets/images/towers/fire_tower_atlas.png differ diff --git a/source/core/assets/images/mine_tower.png b/source/core/assets/images/towers/mine_tower.png similarity index 100% rename from source/core/assets/images/mine_tower.png rename to source/core/assets/images/towers/mine_tower.png diff --git a/source/core/assets/images/towers/stun_tower.atlas b/source/core/assets/images/towers/stun_tower.atlas new file mode 100644 index 000000000..f0033a197 --- /dev/null +++ b/source/core/assets/images/towers/stun_tower.atlas @@ -0,0 +1,118 @@ + +stun_tower.png +size: 1024, 64 +format: RGBA8888 +filter: Nearest, Nearest +repeat: none +attack + rotate: false + xy: 2, 2 + size: 55, 45 + orig: 55, 45 + offset: 0, 0 + index: 4 +attack + rotate: false + xy: 116, 2 + size: 55, 45 + orig: 55, 45 + offset: 0, 0 + index: 9 +attack + rotate: false + xy: 173, 2 + size: 55, 45 + orig: 55, 45 + offset: 0, 0 + index: 1 +attack + rotate: false + xy: 230, 2 + size: 55, 45 + orig: 55, 45 + offset: 0, 0 + index: 6 +attack + rotate: false + xy: 344, 2 + size: 55, 45 + orig: 55, 45 + offset: 0, 0 + index: 3 +attack + rotate: false + xy: 458, 2 + size: 55, 45 + orig: 55, 45 + offset: 0, 0 + index: 8 +attack + rotate: false + xy: 572, 2 + size: 55, 45 + orig: 55, 45 + offset: 0, 0 + index: 0 +attack + rotate: false + xy: 629, 2 + size: 55, 45 + orig: 55, 45 + offset: 0, 0 + index: 5 +attack + rotate: false + xy: 743, 2 + size: 55, 45 + orig: 55, 45 + offset: 0, 0 + index: 2 +attack + rotate: false + xy: 800, 2 + size: 55, 45 + orig: 55, 45 + offset: 0, 0 + index: 7 +idle + rotate: false + xy: 59, 2 + size: 55, 45 + orig: 55, 45 + offset: 0, 0 + index: 1 +idle + rotate: false + xy: 287, 2 + size: 55, 45 + orig: 55, 45 + offset: 0, 0 + index: 3 +idle + rotate: false + xy: 401, 2 + size: 55, 45 + orig: 55, 45 + offset: 0, 0 + index: 0 +idle + rotate: false + xy: 515, 2 + size: 55, 45 + orig: 55, 45 + offset: 0, 0 + index: 5 +idle + rotate: false + xy: 686, 2 + size: 55, 45 + orig: 55, 45 + offset: 0, 0 + index: 2 +idle + rotate: false + xy: 857, 2 + size: 55, 45 + orig: 55, 45 + offset: 0, 0 + index: 4 diff --git a/source/core/assets/images/towers/stun_tower.png b/source/core/assets/images/towers/stun_tower.png new file mode 100644 index 000000000..025b35a4c Binary files /dev/null and b/source/core/assets/images/towers/stun_tower.png differ diff --git a/source/core/assets/images/turret.atlas b/source/core/assets/images/towers/turret.atlas similarity index 100% rename from source/core/assets/images/turret.atlas rename to source/core/assets/images/towers/turret.atlas diff --git a/source/core/assets/images/turret.png b/source/core/assets/images/towers/turret.png similarity index 100% rename from source/core/assets/images/turret.png rename to source/core/assets/images/towers/turret.png diff --git a/source/core/assets/images/turret01.atlas b/source/core/assets/images/towers/turret01.atlas similarity index 100% rename from source/core/assets/images/turret01.atlas rename to source/core/assets/images/towers/turret01.atlas diff --git a/source/core/assets/images/turret01.png b/source/core/assets/images/towers/turret01.png similarity index 100% rename from source/core/assets/images/turret01.png rename to source/core/assets/images/towers/turret01.png diff --git a/source/core/assets/images/turret_deployed.png b/source/core/assets/images/towers/turret_deployed.png similarity index 100% rename from source/core/assets/images/turret_deployed.png rename to source/core/assets/images/towers/turret_deployed.png diff --git a/source/core/assets/images/wallTower.png b/source/core/assets/images/towers/wallTower.png similarity index 100% rename from source/core/assets/images/wallTower.png rename to source/core/assets/images/towers/wallTower.png diff --git a/source/core/assets/images/Logo2.png b/source/core/assets/images/ui/Logo2.png similarity index 100% rename from source/core/assets/images/Logo2.png rename to source/core/assets/images/ui/Logo2.png diff --git a/source/core/assets/images/MainLogo.png b/source/core/assets/images/ui/MainLogo.png similarity index 100% rename from source/core/assets/images/MainLogo.png rename to source/core/assets/images/ui/MainLogo.png diff --git a/source/core/assets/sounds/BGM_03_mp3.mp3 b/source/core/assets/sounds/BGM_03_mp3.mp3 deleted file mode 100644 index 25f08259b..000000000 Binary files a/source/core/assets/sounds/BGM_03_mp3.mp3 and /dev/null differ diff --git a/source/core/assets/sounds/Sci-Fi 1.ogg b/source/core/assets/sounds/Sci-Fi 1.ogg deleted file mode 100644 index eb13d0913..000000000 Binary files a/source/core/assets/sounds/Sci-Fi 1.ogg and /dev/null differ diff --git a/source/core/assets/sounds/Sci-Fi1.ogg b/source/core/assets/sounds/background/Sci-Fi1.ogg similarity index 100% rename from source/core/assets/sounds/Sci-Fi1.ogg rename to source/core/assets/sounds/background/Sci-Fi1.ogg diff --git a/source/core/assets/sounds/projectile firing.mp3 b/source/core/assets/sounds/projectiles/projectile firing.mp3 similarity index 100% rename from source/core/assets/sounds/projectile firing.mp3 rename to source/core/assets/sounds/projectiles/projectile firing.mp3 diff --git a/source/core/assets/sounds/deploy.mp3 b/source/core/assets/sounds/towers/deploy.mp3 similarity index 100% rename from source/core/assets/sounds/deploy.mp3 rename to source/core/assets/sounds/towers/deploy.mp3 diff --git a/source/core/assets/sounds/gun_shot_trimmed.mp3 b/source/core/assets/sounds/towers/gun_shot_trimmed.mp3 similarity index 100% rename from source/core/assets/sounds/gun_shot_trimmed.mp3 rename to source/core/assets/sounds/towers/gun_shot_trimmed.mp3 diff --git a/source/core/assets/sounds/stow.mp3 b/source/core/assets/sounds/towers/stow.mp3 similarity index 100% rename from source/core/assets/sounds/stow.mp3 rename to source/core/assets/sounds/towers/stow.mp3 diff --git a/source/core/src/main/com/csse3200/game/areas/ForestGameArea.java b/source/core/src/main/com/csse3200/game/areas/ForestGameArea.java index 67790531c..d6c24507d 100644 --- a/source/core/src/main/com/csse3200/game/areas/ForestGameArea.java +++ b/source/core/src/main/com/csse3200/game/areas/ForestGameArea.java @@ -17,6 +17,8 @@ import com.csse3200.game.components.gamearea.GameAreaDisplay; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + +import java.util.Random; import java.util.Timer; import java.util.TimerTask; @@ -48,14 +50,14 @@ public class ForestGameArea extends GameArea { // Required to load assets before using them private static final String[] forestTextures = { - "images/projectile.png", + "images/projectiles/projectile.png", "images/box_boy_leaf.png", - "images/building1.png", + "images/background/building1.png", "images/ghost_1.png", "images/grass_2.png", "images/grass_3.png", "images/hex_grass_1.png", - "images/mountain.png", + "images/background/mountain.png", "images/ghost_king.png", "images/ghost_1.png", "images/terrain 2 normal.png", @@ -65,41 +67,48 @@ public class ForestGameArea extends GameArea { "images/iso_grass_1.png", "images/iso_grass_2.png", "images/iso_grass_3.png", - "images/turret.png", - "images/turret01.png", - "images/turret_deployed.png", - "images/building2.png", - "images/wall.png", - "images/robot.png", - "images/Attack_1.png", - "images/Attack_2.png", - "images/Charge_1.png", - "images/Charge_2.png", - "images/Dead.png", - "images/Enabling-5.png", - "images/satyr.png", - "images/Hurt.png", - "images/Idle.png", - "images/rangeBossRight.png", - "images/wallTower.png", - "images/building2.png", + "images/towers/turret.png", + "images/towers/turret01.png", + "images/towers/turret_deployed.png", + "images/towers/fire_tower_atlas.png", + "images/towers/stun_tower.png", + "images/background/building2.png", + "images/mobs/robot.png", + "images/mobs/Attack_1.png", + "images/mobs/Attack_2.png", + "images/mobs/Charge_1.png", + "images/mobs/Charge_2.png", + "images/mobs/Dead.png", + "images/mobs/Enabling-5.png", + "images/mobs/satyr.png", + "images/mobs/Hurt.png", + "images/mobs/Idle.png", + "images/mobs/rangeBossRight.png", + "images/towers/wallTower.png", + "images/background/building2.png", "images/iso_grass_3.png", - "images/scrap.png", - "images/mine_tower.png" + "images/economy/scrap.png", + "images/towers/mine_tower.png" }; private static final String[] forestTextureAtlases = { - "images/terrain_iso_grass.atlas", "images/ghost.atlas", "images/ghostKing.atlas", "images/turret.atlas", - "images/turret01.atlas", "images/xenoGruntRunning.atlas", - "images/robot.atlas", - "images/rangeBossRight.atlas" + "images/terrain_iso_grass.atlas", + "images/ghost.atlas", + "images/ghostKing.atlas", + "images/towers/turret.atlas", + "images/towers/turret01.atlas", + "images/towers/fire_tower_atlas.atlas", + "images/towers/stun_tower.atlas", + "images/mobs/xenoGruntRunning.atlas", + "images/mobs/robot.atlas", + "images/mobs/rangeBossRight.atlas" }; private static final String[] forestSounds = { "sounds/Impact4.ogg", - "sounds/gun_shot_trimmed.mp3", - "sounds/deploy.mp3", - "sounds/stow.mp3" + "sounds/towers/gun_shot_trimmed.mp3", + "sounds/towers/deploy.mp3", + "sounds/towers/stow.mp3" }; - private static final String backgroundMusic = "sounds/Sci-Fi1.ogg"; + private static final String backgroundMusic = "sounds/background/Sci-Fi1.ogg"; private static final String[] forestMusic = {backgroundMusic}; private final TerrainFactory terrainFactory; @@ -131,9 +140,9 @@ public void create() { displayUI(); spawnTerrain(); - spawnBuilding1(); - spawnBuilding2(); - spawnMountains(); +// spawnBuilding1(); +// spawnBuilding2(); +// spawnMountains(); player = spawnPlayer(); playMusic(); @@ -141,16 +150,16 @@ public void create() { // Types of projectile spawnAoeProjectile(new Vector2(0, 10), player, towardsMobs, new Vector2(2f, 2f), 1); spawnProjectile(new Vector2(0, 10), player, towardsMobs, new Vector2(2f, 2f)); - spawnMultiProjectile(new Vector2(0, 10), player, towardsMobs, 20, new Vector2(2f, 2f), 7); +// spawnMultiProjectile(new Vector2(0, 10), player, towardsMobs, 20, new Vector2(2f, 2f), 7); spawnXenoGrunts(); spawnGhosts(); spawnWeaponTower(); spawnIncome(); - spawnScrap(); +// spawnScrap(); bossKing1 = spawnBossKing1(); - bossKing2 = spawnBossKing2(); +// bossKing2 = spawnBossKing2(); playMusic(); } @@ -191,40 +200,40 @@ private void spawnTerrain() { spawnEntityAt( ObstacleFactory.createWall(worldBounds.x, WALL_WIDTH), GridPoint2Utils.ZERO, false, false); } - private void spawnBuilding1() { - GridPoint2 minPos = new GridPoint2(0, 0); - GridPoint2 maxPos = terrain.getMapBounds(0).sub(2, 2); - - for (int i = 0; i < NUM_BUILDINGS; i++) { - GridPoint2 randomPos = RandomUtils.random(minPos, maxPos); - Entity building1 = ObstacleFactory.createBuilding1(); - spawnEntityAt(building1, randomPos, true, false); - } - } - private void spawnBuilding2() { - GridPoint2 minPos = new GridPoint2(0, 0); - GridPoint2 maxPos = terrain.getMapBounds(0).sub(2, 2); - - for (int i = 0; i < NUM_BUILDINGS; i++) { - GridPoint2 randomPos = RandomUtils.random(minPos, maxPos); - Entity building2 = ObstacleFactory.createBuilding2(); - spawnEntityAt(building2, randomPos, true, false); - } - } - - private void spawnMountains() { - ArrayList fixedPositions = new ArrayList<>(); //Generating ArrayList - - fixedPositions.add(new GridPoint2(5, 8)); - fixedPositions.add(new GridPoint2(12, 4)); - fixedPositions.add(new GridPoint2(20, 10)); - fixedPositions.add(new GridPoint2(33, 17)); - - for (GridPoint2 fixedPos : fixedPositions) { - Entity tree = ObstacleFactory.createMountain(); - spawnEntityAt(tree, fixedPos, true, false); - } - } +// private void spawnBuilding1() { +// GridPoint2 minPos = new GridPoint2(0, 0); +// GridPoint2 maxPos = terrain.getMapBounds(0).sub(2, 2); +// +// for (int i = 0; i < NUM_BUILDINGS; i++) { +// GridPoint2 randomPos = RandomUtils.random(minPos, maxPos); +// Entity building1 = ObstacleFactory.createBuilding1(); +// spawnEntityAt(building1, randomPos, true, false); +// } +// } +// private void spawnBuilding2() { +// GridPoint2 minPos = new GridPoint2(0, 0); +// GridPoint2 maxPos = terrain.getMapBounds(0).sub(2, 2); +// +// for (int i = 0; i < NUM_BUILDINGS; i++) { +// GridPoint2 randomPos = RandomUtils.random(minPos, maxPos); +// Entity building2 = ObstacleFactory.createBuilding2(); +// spawnEntityAt(building2, randomPos, true, false); +// } +// } + +// private void spawnMountains() { +// ArrayList fixedPositions = new ArrayList<>(); //Generating ArrayList +// +// fixedPositions.add(new GridPoint2(5, 8)); +// fixedPositions.add(new GridPoint2(12, 4)); +// fixedPositions.add(new GridPoint2(20, 10)); +// fixedPositions.add(new GridPoint2(33, 17)); +// +// for (GridPoint2 fixedPos : fixedPositions) { +// Entity tree = ObstacleFactory.createMountain(); +// spawnEntityAt(tree, fixedPos, true, false); +// } +// } private Entity spawnPlayer() { Entity newPlayer = PlayerFactory.createPlayer(); @@ -319,34 +328,34 @@ private void spawnXenoGrunts() { } } - private Entity spawnGhostKing() { - GridPoint2 minPos = new GridPoint2(0, 0); - GridPoint2 maxPos = terrain.getMapBounds(0).sub(0, 0); - GridPoint2 randomPos - = RandomUtils.random(minPos, maxPos); - // = new GridPoint2(26, 26); - Entity ghostKing = NPCFactory.createGhostKing(player); - spawnEntityAt(ghostKing, randomPos, true, true); - return ghostKing; - - } - - private Entity spawnBossKing2() { - GridPoint2 minPos = new GridPoint2(0, 0); - GridPoint2 maxPos = terrain.getMapBounds(0).sub(2, 2); - - for (int i = 0; i < NUM_BOSS; i++) { - int fixedX = terrain.getMapBounds(0).x - 1; // Rightmost x-coordinate - int randomY = MathUtils.random(0, maxPos.y); - GridPoint2 randomPos = new GridPoint2(fixedX, randomY); - bossKing2 = BossKingFactory.createBossKing2(player); - spawnEntityAt(bossKing2, - randomPos, - true, - false); - } - return bossKing2; - } +// private Entity spawnGhostKing() { +// GridPoint2 minPos = new GridPoint2(0, 0); +// GridPoint2 maxPos = terrain.getMapBounds(0).sub(0, 0); +// GridPoint2 randomPos +// = RandomUtils.random(minPos, maxPos); +// // = new GridPoint2(26, 26); +// Entity ghostKing = NPCFactory.createGhostKing(player); +// spawnEntityAt(ghostKing, randomPos, true, true); +// return ghostKing; +// +// } + +// private Entity spawnBossKing2() { +// GridPoint2 minPos = new GridPoint2(0, 0); +// GridPoint2 maxPos = terrain.getMapBounds(0).sub(2, 2); +// +// for (int i = 0; i < NUM_BOSS; i++) { +// int fixedX = terrain.getMapBounds(0).x - 1; // Rightmost x-coordinate +// int randomY = MathUtils.random(0, maxPos.y); +// GridPoint2 randomPos = new GridPoint2(fixedX, randomY); +// bossKing2 = BossKingFactory.createBossKing2(player); +// spawnEntityAt(bossKing2, +// randomPos, +// true, +// false); +// } +// return bossKing2; +// } /** * Creates multiple projectiles that travel simultaneous. They all have same @@ -359,13 +368,13 @@ private Entity spawnBossKing2() { * @param speed The speed of the projectiles. * @param quantity The amount of projectiles to spawn. */ - private void spawnMultiProjectile(Vector2 position, Entity target, int direction, int space, Vector2 speed, int quantity) { - int half = quantity / 2; - for (int i = 0; i < quantity; i++) { - spawnProjectile(position, target, space * half, direction, speed); - --half; - } - } +// private void spawnMultiProjectile(Vector2 position, Entity target, int direction, int space, Vector2 speed, int quantity) { +// int half = quantity / 2; +// for (int i = 0; i < quantity; i++) { +// spawnProjectile(position, target, space * half, direction, speed); +// --half; +// } +// } /** * Returns projectile that can do an area of effect damage @@ -387,11 +396,16 @@ private void spawnWeaponTower() { GridPoint2 maxPos = terrain.getMapBounds(0).sub(2, 2); for (int i = 0; i < NUM_WEAPON_TOWERS; i++) { - GridPoint2 randomPos = RandomUtils.random(minPos, maxPos); - Entity weaponTower = TowerFactory.createWeaponTower(); + GridPoint2 randomPos1 = RandomUtils.random(minPos, maxPos); + GridPoint2 randomPos2 = RandomUtils.random(minPos, maxPos); + //Entity weaponTower = TowerFactory.createWeaponTower(); Entity wallTower = TowerFactory.createWallTower(); - spawnEntityAt(weaponTower, randomPos, true, true); - spawnEntityAt(wallTower, new GridPoint2(randomPos.x + 3, randomPos.y), true, true); + Entity fireTower = TowerFactory.createFireTower(); + Entity stunTower = TowerFactory.createStunTower(); + //spawnEntityAt(weaponTower, randomPos, true, true); + spawnEntityAt(fireTower, randomPos1, true, true); + spawnEntityAt(stunTower, randomPos2, true, true); + //spawnEntityAt(wallTower, new GridPoint2(randomPos1.x + 3, randomPos1.y), true, true); } } @@ -433,16 +447,16 @@ public void dispose() { this.unloadAssets(); } - private void spawnScrap() { - GridPoint2 minPos = new GridPoint2(0, 0); - GridPoint2 maxPos = terrain.getMapBounds(0).sub(2, 2); - - for (int i = 0; i < 50; i++) { - GridPoint2 randomPos = RandomUtils.random(minPos, maxPos); - Entity scrap = DropFactory.createScrapDrop(); - spawnEntityAt(scrap, randomPos, true, false); - } - } +// private void spawnScrap() { +// GridPoint2 minPos = new GridPoint2(0, 0); +// GridPoint2 maxPos = terrain.getMapBounds(0).sub(2, 2); +// +// for (int i = 0; i < 50; i++) { +// GridPoint2 randomPos = RandomUtils.random(minPos, maxPos); +// Entity scrap = DropFactory.createScrapDrop(); +// spawnEntityAt(scrap, randomPos, true, false); +// } +// } private void spawnIncome() { GridPoint2 minPos = new GridPoint2(0, 0); diff --git a/source/core/src/main/com/csse3200/game/components/gamearea/CurrencyDisplay.java b/source/core/src/main/com/csse3200/game/components/gamearea/CurrencyDisplay.java index c6d3c8a47..2c784593c 100644 --- a/source/core/src/main/com/csse3200/game/components/gamearea/CurrencyDisplay.java +++ b/source/core/src/main/com/csse3200/game/components/gamearea/CurrencyDisplay.java @@ -43,7 +43,7 @@ private void addActors() { table.padTop(50f).padLeft(20f); // create text button style - Drawable drawable = new TextureRegionDrawable(new TextureRegion(new Texture("images/scrapsUI.png"))); + Drawable drawable = new TextureRegionDrawable(new TextureRegion(new Texture("images/economy/scrapsUI.png"))); TextButton.TextButtonStyle textButtonStyle = new TextButton.TextButtonStyle( drawable, drawable, drawable, new BitmapFont()); diff --git a/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuDisplay.java b/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuDisplay.java index da8a603c3..d15392b23 100644 --- a/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuDisplay.java +++ b/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuDisplay.java @@ -32,7 +32,7 @@ private void addActors() { Image title = new Image( ServiceLocator.getResourceService() - .getAsset("images/Logo2.png", Texture.class)); + .getAsset("images/ui/Logo2.png", Texture.class)); TextButton startBtn = new TextButton("Start", skin); TextButton loadBtn = new TextButton("Help", skin); diff --git a/source/core/src/main/com/csse3200/game/components/npc/BossStatsDisplay.java b/source/core/src/main/com/csse3200/game/components/npc/BossStatsDisplay.java index 2c5d56013..264f544fd 100644 --- a/source/core/src/main/com/csse3200/game/components/npc/BossStatsDisplay.java +++ b/source/core/src/main/com/csse3200/game/components/npc/BossStatsDisplay.java @@ -38,7 +38,7 @@ private void addActors() { // Heart image float bossSideLength = 30f; - bossImage = new Image(ServiceLocator.getResourceService().getAsset("images/boss_health.png", Texture.class)); + bossImage = new Image(ServiceLocator.getResourceService().getAsset("images/mobs/boss_health.png", Texture.class)); // Health text int health = entity.getComponent(CombatStatsComponent.class).getHealth(); diff --git a/source/core/src/main/com/csse3200/game/components/tasks/FireTowerCombatTask.java b/source/core/src/main/com/csse3200/game/components/tasks/FireTowerCombatTask.java new file mode 100644 index 000000000..eff97273f --- /dev/null +++ b/source/core/src/main/com/csse3200/game/components/tasks/FireTowerCombatTask.java @@ -0,0 +1,154 @@ +package com.csse3200.game.components.tasks; + +import com.badlogic.gdx.math.Vector2; +import com.csse3200.game.ai.tasks.DefaultTask; +import com.csse3200.game.ai.tasks.PriorityTask; +import com.csse3200.game.entities.Entity; +import com.csse3200.game.entities.factories.ProjectileFactory; +import com.csse3200.game.physics.PhysicsEngine; +import com.csse3200.game.physics.PhysicsLayer; +import com.csse3200.game.physics.raycast.RaycastHit; +import com.csse3200.game.services.GameTime; +import com.csse3200.game.services.ServiceLocator; + +/** + * The FireTowerCombatTask runs the AI for the FireTower class. The tower implementing this task will scan for enemies + * in a straight line from the current position to a maxRange, and change the state of the tower. + */ +public class FireTowerCombatTask extends DefaultTask implements PriorityTask { + //constants + private static final int INTERVAL = 1; //time interval to scan for enemies in seconds + private static final short TARGET = PhysicsLayer.NPC; //the type of targets this tower will detect + //The constants are names of events that will be triggered in the state machine + private static final String IDLE = "startIdle"; + private static final String PREP_ATTACK = "startAttackPrep"; + private static final String ATTACK = "startAttack"; + + //Class attributes + private final int priority; + private final float maxRange; + + private Vector2 towerPosition = new Vector2(10, 10); + private final Vector2 maxRangePosition = new Vector2(); + private PhysicsEngine physics; + private GameTime timeSource; + private long endTime; + private final RaycastHit hit = new RaycastHit(); + + private enum STATE { + IDLE, PREP_ATTACK, ATTACK + } + private STATE towerState = STATE.IDLE; + + /** + * Starts the task running, triggers the initial 'IDLE' event + */ + public FireTowerCombatTask(int priority, float maxRange) { + this.priority = priority; + this.maxRange = maxRange; + physics = ServiceLocator.getPhysicsService().getPhysics(); + timeSource = ServiceLocator.getTimeSource(); + } + + /** + * starts this task and triggers the IDLE animation + */ + @Override + public void start() { + super.start(); + // get the tower coordinates + this.towerPosition = owner.getEntity().getCenterPosition(); + this.maxRangePosition.set(towerPosition.x + maxRange, towerPosition.y); + //default to idle state + owner.getEntity().getEvents().trigger(IDLE); + + endTime = timeSource.getTime() + (INTERVAL * 500); + } + + /** + * this method is called everytime state of the tower needs to be changed. + */ + @Override + public void update() { + if (timeSource.getTime() >= endTime) { + updateTowerState(); + endTime = timeSource.getTime() + (INTERVAL * 1000); + } + } + + /** + * finite state machine for the FireTower. Detects mobs in a straight line and changes the state of the tower. + */ + public void updateTowerState() { + switch (towerState) { + case IDLE -> { + if (isTargetVisible()) { + owner.getEntity().getEvents().trigger(PREP_ATTACK); + towerState = STATE.PREP_ATTACK; + } + } + case PREP_ATTACK -> { + 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(IDLE); + towerState = STATE.IDLE; + } else { + owner.getEntity().getEvents().trigger(ATTACK); + Entity newProjectile = ProjectileFactory.createFireBall(owner.getEntity(), + 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); + } + } + } + } + + /** + * stops the current animation. + */ + public void stop() { + super.stop(); + owner.getEntity().getEvents().trigger(IDLE); + } + + /** + * gets the priority for the current task. + * @return (int) active priority if target is visible and inactive priority otherwise + */ + public int getPriority() { + return !isTargetVisible() ? 0 : priority; + } + + /** + * not currently used. + * @return the priority for this task + */ + private int getActivePriority() { + return !isTargetVisible() ? 0 : priority; + } + + /** + * not currently used. + * @return + */ + private int getInactivePriority() { + return isTargetVisible() ? priority : 0; + } + + /** + * detects targets from the centre of the tower to maxRange in a straight line. + * @return true if mobs are present and false otherwise. + */ + public boolean isTargetVisible() { + return physics.raycast(towerPosition, maxRangePosition, TARGET, hit); + } +} diff --git a/source/core/src/main/com/csse3200/game/components/tasks/StunTowerCombatTask.java b/source/core/src/main/com/csse3200/game/components/tasks/StunTowerCombatTask.java new file mode 100644 index 000000000..b4fb3d802 --- /dev/null +++ b/source/core/src/main/com/csse3200/game/components/tasks/StunTowerCombatTask.java @@ -0,0 +1,139 @@ +package com.csse3200.game.components.tasks; + +import com.badlogic.gdx.math.Vector2; +import com.csse3200.game.ai.tasks.DefaultTask; +import com.csse3200.game.ai.tasks.PriorityTask; +import com.csse3200.game.entities.Entity; +import com.csse3200.game.entities.factories.ProjectileFactory; +import com.csse3200.game.physics.PhysicsEngine; +import com.csse3200.game.physics.PhysicsLayer; +import com.csse3200.game.physics.raycast.RaycastHit; +import com.csse3200.game.services.GameTime; +import com.csse3200.game.services.ServiceLocator; + + +/** + * The StunTowerCombatTask runs the AI for the StunTower class. The tower scans for mobs and targets in a straight line + * from its centre coordinate and executes the trigger phrases for animations depending on the current state of tower. + */ +public class StunTowerCombatTask extends DefaultTask implements PriorityTask { + //constants + private static final int INTERVAL = 1; + private static final short TARGET = PhysicsLayer.NPC; + //Following constants are names of events that will be triggered in the state machine + public static final String IDLE = "startIdle"; + public static final String ATTACK = "startAttack"; + + //Following are the class constants + private final int priority; + private final float maxRange; + private Vector2 towerPosition = new Vector2(10, 10); + private final Vector2 maxRangePosition = new Vector2(); + private PhysicsEngine physics; + private GameTime timeSource; + private long endTime; + private final RaycastHit hit = new RaycastHit(); + + //enums for the state triggers + private enum STATE { + IDLE, ATTACK + } + private STATE towerState = STATE.IDLE; + + /** + * @param priority Task priority when targets are detected (0 when nothing is present) + * @param maxRange Maximum effective range of the StunTower. + */ + public StunTowerCombatTask(int priority, float maxRange) { + this.priority = priority; + this.maxRange = maxRange; + physics = ServiceLocator.getPhysicsService().getPhysics(); + timeSource = ServiceLocator.getTimeSource(); + } + + /** + * Starts the task running and starts the Idle animation + */ + @Override + public void start() { + super.start(); + //get the tower coordinates + this.towerPosition = owner.getEntity().getCenterPosition(); + this.maxRangePosition.set(towerPosition.x + maxRange, towerPosition.y); + //set the default state to IDLE state + owner.getEntity().getEvents().trigger(IDLE); + + endTime = timeSource.getTime() + (INTERVAL * 5000); + } + + /** + * updates the current state of the tower based on the current state of the game. If enemies are detected, attack + * state is activated and otherwise idle state remains. + */ + public void update() { + if (timeSource.getTime() >= endTime) { + updateTowerState(); + endTime = timeSource.getTime() + (INTERVAL * 1000); + } + } + + /** + * This method acts is the state machine for StunTower. Relevant animations are triggered based on relevant state + * of the game. If enemies are detected, state of the tower is changed to attack state. + */ + public void updateTowerState() { + switch (towerState) { + case IDLE -> { + if(isTargetVisible()) { + owner.getEntity().getEvents().trigger(ATTACK); + towerState = STATE.ATTACK; + } + } + case ATTACK -> { + if (!isTargetVisible()) { + owner.getEntity().getEvents().trigger(IDLE); + towerState = STATE.IDLE; + } else { + owner.getEntity().getEvents().trigger(ATTACK); + Entity newProjectile = ProjectileFactory.createFireBall(owner.getEntity(), + 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); + } + } + } + } + + /** + * stops the current animation and switches back the state of the tower to IDLE. + */ + public void stop() { + super.stop(); + owner.getEntity().getEvents().trigger(IDLE); + } + + /** + * returns the current priority of the task + * @return (int) active priority if target is visible and inactive priority otherwise + */ + public int getPriority() { + return !isTargetVisible() ? 0 : priority; + } + + public int getActivePriority() { + return !isTargetVisible() ? 0 : priority; + } + + public int getInactivePriority() { + return isTargetVisible() ? priority : 0; + } + + /** + * Searches for enemies/mobs in a straight line from the centre of the tower to maxRange in a straight line. + * @return true if targets are detected, false otherwise + */ + public boolean isTargetVisible() { + return physics.raycast(towerPosition, maxRangePosition, TARGET, hit); + } +} diff --git a/source/core/src/main/com/csse3200/game/components/tower/FireTowerAnimationController.java b/source/core/src/main/com/csse3200/game/components/tower/FireTowerAnimationController.java new file mode 100644 index 000000000..358d7a3a6 --- /dev/null +++ b/source/core/src/main/com/csse3200/game/components/tower/FireTowerAnimationController.java @@ -0,0 +1,58 @@ +package com.csse3200.game.components.tower; + +import com.badlogic.gdx.audio.Sound; +import com.csse3200.game.components.Component; +import com.csse3200.game.rendering.AnimationRenderComponent; +import com.csse3200.game.services.ServiceLocator; + +/** + * Listens for events relevant to a weapon tower state. + * Each event will have a trigger phrase and have a certain animation attached. + */ +public class FireTowerAnimationController extends Component{ + //Event name constants + private static final String IDLE = "startIdle"; + private static final String PREP_ATTACK = "startAttackPrep"; + private static final String ATTACK = "startAttack"; + + //animation name constants + private static final String IDLE_ANIM = "idle"; + private static final String PREP_ATTACK_ANIM = "prepAttack"; + private static final String ATTACK_ANIM = "attack"; + //here we can add the sounds for the implemented animations + + AnimationRenderComponent animator; + + /** + * Create method for FireTowerAnimationController. + */ + @Override + public void create() { + super.create(); + animator = this.entity.getComponent(AnimationRenderComponent.class); + entity.getEvents().addListener(IDLE, this::animateIdle); + entity.getEvents().addListener(PREP_ATTACK, this::animatePrepAttack); + entity.getEvents().addListener(ATTACK, this::animateAttack); + } + + /** + * Starts the idle animation + */ + void animateIdle() { + animator.startAnimation(IDLE_ANIM); + } + + /** + * starts the prep_attack animation + */ + void animatePrepAttack() { + animator.startAnimation(PREP_ATTACK_ANIM); + } + + /** + * starts the attack animation + */ + void animateAttack() { + animator.startAnimation(ATTACK_ANIM); + } +} diff --git a/source/core/src/main/com/csse3200/game/components/tower/StunTowerAnimationController.java b/source/core/src/main/com/csse3200/game/components/tower/StunTowerAnimationController.java new file mode 100644 index 000000000..fa4868c4c --- /dev/null +++ b/source/core/src/main/com/csse3200/game/components/tower/StunTowerAnimationController.java @@ -0,0 +1,48 @@ +package com.csse3200.game.components.tower; + +import com.badlogic.gdx.audio.Sound; +import com.csse3200.game.components.Component; +import com.csse3200.game.rendering.AnimationRenderComponent; +import com.csse3200.game.services.ServiceLocator; + +/** + * Listens to triggers phrases and executes the required animations. + */ +public class StunTowerAnimationController extends Component { + //Event name constants + private static final String IDLE = "startIdle"; + private static final String ATTACK = "startAttack"; + //animation name constants + private static final String IDLE_ANIM = "idle"; + private static final String ATTACK_ANIM = "attack"; + + //further sounds can be added for the tower attacks/movement + + AnimationRenderComponent animator; + + /** + * Creation method for StunTowerAnimationController, fetches the animationRenderComponent that this controller will + * be attached to and registers all the event listeners required to trigger the animations. + */ + @Override + public void create() { + super.create(); + animator = this.entity.getComponent(AnimationRenderComponent.class); + entity.getEvents().addListener(IDLE, this::animateIdle); + entity.getEvents().addListener(ATTACK, this::animateAttack); + } + + /** + * Starts the idle animation + */ + void animateIdle() { + animator.startAnimation(IDLE_ANIM); + } + + /** + * starts the attack animation + */ + void animateAttack() { + animator.startAnimation(ATTACK_ANIM); + } +} diff --git a/source/core/src/main/com/csse3200/game/components/tower/TowerAnimationController.java b/source/core/src/main/com/csse3200/game/components/tower/TowerAnimationController.java index 80855c894..a53084434 100644 --- a/source/core/src/main/com/csse3200/game/components/tower/TowerAnimationController.java +++ b/source/core/src/main/com/csse3200/game/components/tower/TowerAnimationController.java @@ -21,9 +21,9 @@ public class TowerAnimationController extends Component { private static final String FIRE_ANIM = "firing"; private static final String STOW_ANIM = "stow"; // Sound effects constants - private static final String DEPLOY_SFX = "sounds/deploy.mp3"; - private static final String FIRE_SFX = "sounds/gun_shot_trimmed.mp3"; - private static final String STOW_SFX = "sounds/stow.mp3"; + private static final String DEPLOY_SFX = "sounds/towers/deploy.mp3"; + private static final String FIRE_SFX = "sounds/towers/gun_shot_trimmed.mp3"; + private static final String STOW_SFX = "sounds/towers/stow.mp3"; AnimationRenderComponent animator; Sound deploySound = ServiceLocator.getResourceService().getAsset( @@ -33,6 +33,10 @@ public class TowerAnimationController extends Component { Sound stowSound = ServiceLocator.getResourceService().getAsset( STOW_SFX, Sound.class); + /** + * Creation call for a TowerAnimationController, 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(); @@ -43,6 +47,9 @@ public void create() { entity.getEvents().addListener(FIRING, this::animateFiring); } + /** + * Starts the + */ void animateIdle() { animator.startAnimation(IDLE_ANIM); } diff --git a/source/core/src/main/com/csse3200/game/currency/Scrap.java b/source/core/src/main/com/csse3200/game/currency/Scrap.java index 958babaa5..cc4ded817 100644 --- a/source/core/src/main/com/csse3200/game/currency/Scrap.java +++ b/source/core/src/main/com/csse3200/game/currency/Scrap.java @@ -4,7 +4,7 @@ public class Scrap extends Currency { private static final int STARTING_CURRENCY = 100; - private static final String LOGO_FILE_PATH = "images/scrap.png"; // The file path of the logo + private static final String LOGO_FILE_PATH = "images/economy/scrap.png"; // The file path of the logo /** * Constructor for the scrap currency object. diff --git a/source/core/src/main/com/csse3200/game/entities/configs/FireTowerConfig.java b/source/core/src/main/com/csse3200/game/entities/configs/FireTowerConfig.java new file mode 100644 index 000000000..7e697040b --- /dev/null +++ b/source/core/src/main/com/csse3200/game/entities/configs/FireTowerConfig.java @@ -0,0 +1,7 @@ +package com.csse3200.game.entities.configs; + +public class FireTowerConfig { + public int health = 1; + public int baseAttack = 0; + public int cost = 1; +} diff --git a/source/core/src/main/com/csse3200/game/entities/configs/StunTowerConfig.java b/source/core/src/main/com/csse3200/game/entities/configs/StunTowerConfig.java new file mode 100644 index 000000000..fc711e70f --- /dev/null +++ b/source/core/src/main/com/csse3200/game/entities/configs/StunTowerConfig.java @@ -0,0 +1,7 @@ +package com.csse3200.game.entities.configs; + +public class StunTowerConfig { + public int health = 1; + public int baseAttack = 0; + public int cost = 1; +} diff --git a/source/core/src/main/com/csse3200/game/entities/configs/baseTowerConfigs.java b/source/core/src/main/com/csse3200/game/entities/configs/baseTowerConfigs.java index 13c6fe19b..f7549d4f4 100644 --- a/source/core/src/main/com/csse3200/game/entities/configs/baseTowerConfigs.java +++ b/source/core/src/main/com/csse3200/game/entities/configs/baseTowerConfigs.java @@ -7,4 +7,6 @@ public class baseTowerConfigs { public WeaponTowerConfig weapon = new WeaponTowerConfig(); public WallTowerConfig wall = new WallTowerConfig(); public IncomeTowerConfig income = new IncomeTowerConfig(); + public FireTowerConfig fireTower = new FireTowerConfig(); + public StunTowerConfig stunTower = new StunTowerConfig(); } \ No newline at end of file diff --git a/source/core/src/main/com/csse3200/game/entities/factories/BossKingFactory.java b/source/core/src/main/com/csse3200/game/entities/factories/BossKingFactory.java index 11ea658ee..1bd29a628 100644 --- a/source/core/src/main/com/csse3200/game/entities/factories/BossKingFactory.java +++ b/source/core/src/main/com/csse3200/game/entities/factories/BossKingFactory.java @@ -50,7 +50,7 @@ public static Entity createBossKing1(Entity target) { AnimationRenderComponent animator1 = new AnimationRenderComponent( ServiceLocator.getResourceService() - .getAsset("images/rangeBossRight.atlas", TextureAtlas.class)); + .getAsset("images/mobs/rangeBossRight.atlas", TextureAtlas.class)); animator1.addAnimation("Walk", 0.3f, Animation.PlayMode.LOOP); @@ -78,7 +78,7 @@ public static Entity createBossKing2(Entity target) { AnimationRenderComponent animator2 = new AnimationRenderComponent( ServiceLocator.getResourceService() - .getAsset("images/robot.atlas", TextureAtlas.class)); + .getAsset("images/mobs/robot.atlas", TextureAtlas.class)); animator2.addAnimation("Walk", 0.3f, Animation.PlayMode.LOOP); bossKing2 diff --git a/source/core/src/main/com/csse3200/game/entities/factories/NPCFactory.java b/source/core/src/main/com/csse3200/game/entities/factories/NPCFactory.java index be12b14e4..dd7777f79 100644 --- a/source/core/src/main/com/csse3200/game/entities/factories/NPCFactory.java +++ b/source/core/src/main/com/csse3200/game/entities/factories/NPCFactory.java @@ -62,7 +62,7 @@ public static Entity createGhost(Entity target) { ghost .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) // .addComponent(animator) - .addComponent(new TextureRenderComponent("images/satyr.png")); + .addComponent(new TextureRenderComponent("images/mobs/satyr.png")); // .addComponent(new GhostAnimationController()); ghost.getComponent(TextureRenderComponent.class).scaleEntity(); @@ -111,7 +111,7 @@ public static Entity createXenoGrunt(Entity target) { AnimationRenderComponent animator = new AnimationRenderComponent( - ServiceLocator.getResourceService().getAsset("images/xenoGruntRunning.atlas", TextureAtlas.class)); + ServiceLocator.getResourceService().getAsset("images/mobs/xenoGruntRunning.atlas", TextureAtlas.class)); animator.addAnimation("xeno_run", 0.1f, Animation.PlayMode.LOOP); animator.addAnimation("xeno_shoot", 0.1f, Animation.PlayMode.NORMAL); animator.addAnimation("xeno_melee", 0.1f, Animation.PlayMode.NORMAL); diff --git a/source/core/src/main/com/csse3200/game/entities/factories/ObstacleFactory.java b/source/core/src/main/com/csse3200/game/entities/factories/ObstacleFactory.java index 913cf346a..f863cbfb2 100644 --- a/source/core/src/main/com/csse3200/game/entities/factories/ObstacleFactory.java +++ b/source/core/src/main/com/csse3200/game/entities/factories/ObstacleFactory.java @@ -22,7 +22,7 @@ public class ObstacleFactory { public static Entity createBuilding1() { Entity building1 = new Entity() - .addComponent(new TextureRenderComponent("images/building1.png")) + .addComponent(new TextureRenderComponent("images/background/building1.png")) .addComponent(new PhysicsComponent()) .addComponent(new ColliderComponent().setLayer(PhysicsLayer.OBSTACLE)); @@ -35,7 +35,7 @@ public static Entity createBuilding1() { public static Entity createBuilding2() { Entity building2 = new Entity() - .addComponent(new TextureRenderComponent("images/building2.png")) + .addComponent(new TextureRenderComponent("images/background/building2.png")) .addComponent(new PhysicsComponent()) .addComponent(new ColliderComponent().setLayer(PhysicsLayer.OBSTACLE)); @@ -49,7 +49,7 @@ public static Entity createBuilding2() { public static Entity createMountain() { Entity mountain = new Entity() - .addComponent(new TextureRenderComponent("images/mountain.png")) + .addComponent(new TextureRenderComponent("images/background/mountain.png")) .addComponent(new PhysicsComponent()) .addComponent(new ColliderComponent().setLayer(PhysicsLayer.OBSTACLE)); diff --git a/source/core/src/main/com/csse3200/game/entities/factories/ProjectileFactory.java b/source/core/src/main/com/csse3200/game/entities/factories/ProjectileFactory.java index 83f2093b9..33d596599 100644 --- a/source/core/src/main/com/csse3200/game/entities/factories/ProjectileFactory.java +++ b/source/core/src/main/com/csse3200/game/entities/factories/ProjectileFactory.java @@ -40,7 +40,7 @@ public static Entity createFireBall(Entity target, Vector2 destination, Vector2 Entity projectile = createBaseProjectile(target, destination); projectile - .addComponent(new TextureRenderComponent("images/projectile.png")) + .addComponent(new TextureRenderComponent("images/projectiles/projectile.png")) .addComponent(new ColliderComponent().setSensor(true)) // This is the component that allows the projectile to damage a specified target. diff --git a/source/core/src/main/com/csse3200/game/entities/factories/TowerFactory.java b/source/core/src/main/com/csse3200/game/entities/factories/TowerFactory.java index f2ce8f2e9..70b1f8b14 100644 --- a/source/core/src/main/com/csse3200/game/entities/factories/TowerFactory.java +++ b/source/core/src/main/com/csse3200/game/entities/factories/TowerFactory.java @@ -1,9 +1,11 @@ package com.csse3200.game.entities.factories; +import com.csse3200.game.components.tasks.FireTowerCombatTask; +import com.csse3200.game.components.tasks.StunTowerCombatTask; +import com.csse3200.game.components.tower.FireTowerAnimationController; +import com.csse3200.game.components.tower.StunTowerAnimationController; +import com.csse3200.game.entities.configs.*; import com.csse3200.game.components.tower.TowerUpgraderComponent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.Animation; import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.physics.box2d.BodyDef.BodyType; @@ -14,19 +16,18 @@ import com.csse3200.game.components.tower.TowerAnimationController; import com.csse3200.game.components.tasks.CurrencyTask; import com.csse3200.game.entities.Entity; -import com.csse3200.game.entities.configs.WallTowerConfig; import com.csse3200.game.physics.PhysicsLayer; +import com.csse3200.game.physics.PhysicsUtils; import com.csse3200.game.physics.components.ColliderComponent; import com.csse3200.game.physics.components.HitboxComponent; import com.csse3200.game.physics.components.PhysicsComponent; -import com.csse3200.game.entities.configs.WeaponTowerConfig; -import com.csse3200.game.entities.configs.IncomeTowerConfig; -import com.csse3200.game.entities.configs.baseTowerConfigs; import com.csse3200.game.files.FileLoader; import com.csse3200.game.rendering.AnimationRenderComponent; import com.csse3200.game.rendering.TextureRenderComponent; import com.csse3200.game.services.ServiceLocator; +import java.util.ServiceConfigurationError; + /** * Factory to create a tower entity. * @@ -37,8 +38,10 @@ public class TowerFactory { private static final int COMBAT_TASK_PRIORITY = 2; private static final int WEAPON_TOWER_MAX_RANGE = 40; - private static final String WALL_IMAGE = "images/wallTower.png"; - private static final String TURRET_ATLAS = "images/turret01.atlas"; + private static final String WALL_IMAGE = "images/towers/wallTower.png"; + 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 IDLE_ANIM = "idle"; private static final float IDLE_SPEED = 0.3f; private static final String DEPLOY_ANIM = "deploy"; @@ -47,6 +50,16 @@ public class TowerFactory { private static final float STOW_SPEED = 0.2f; private static final String FIRE_ANIM = "firing"; private static final float FIRE_SPEED = 0.25f; + private static final String FIRE_TOWER_IDLE_ANIM = "idle"; + private static final float FIRE_TOWER_IDLE_SPEED = 0.3f; + private static final String FIRE_TOWER_PREP_ATTACK_ANIM = "prepAttack"; + private static final float FIRE_TOWER_PREP_ATTACK_SPEED = 0.2f; + private static final String FIRE_TOWER_ATTACK_ANIM = "attack"; + private static final float FIRE_TOWER_ATTACK_SPEED = 0.25f; + private static final String STUN_TOWER_IDLE_ANIM = "idle"; + private static final float STUN_TOWER_IDLE_SPEED = 0.33f; + private static final String STUN_TOWER_ATTACK_ANIM = "attack"; + private static final float STUN_TOWER_ATTACK_SPEED = 0.12f; private static final int INCOME_INTERVAL = 300; private static final int INCOME_TASK_PRIORITY = 1; @@ -70,7 +83,7 @@ public static Entity createIncomeTower() { income .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) .addComponent(new CostComponent(config.cost)) - .addComponent(new TextureRenderComponent("images/mine_tower.png")) + .addComponent(new TextureRenderComponent("images/towers/mine_tower.png")) .addComponent(aiTaskComponent); @@ -122,6 +135,67 @@ public static Entity createWeaponTower() { return weapon; } + + /** + * Creates the FireTower entity which shoots at mobs traversing in a straight line. + * @return FireTower entity with relevant components. + */ + public static Entity createFireTower() { + Entity fireTower = createBaseTower(); + FireTowerConfig config = configs.fireTower; + + //Component that handles triggering events and animations + AITaskComponent aiTaskComponent = new AITaskComponent() + .addTask(new FireTowerCombatTask(COMBAT_TASK_PRIORITY, WEAPON_TOWER_MAX_RANGE)); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService() + .getAsset(FIRE_TOWER_ATLAS, TextureAtlas.class)); + animator.addAnimation(FIRE_TOWER_IDLE_ANIM, FIRE_TOWER_IDLE_SPEED, Animation.PlayMode.LOOP); + animator.addAnimation(FIRE_TOWER_PREP_ATTACK_ANIM, FIRE_TOWER_PREP_ATTACK_SPEED, Animation.PlayMode.NORMAL); + animator.addAnimation(FIRE_TOWER_ATTACK_ANIM, FIRE_TOWER_ATTACK_SPEED, Animation.PlayMode.LOOP); + + fireTower + .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) + .addComponent(new CostComponent(config.cost)) + .addComponent(aiTaskComponent) + .addComponent(animator) + .addComponent(new FireTowerAnimationController()); + fireTower.setScale(1.25f, 1.25f); + return fireTower; + } + + /** + * Creates the StunTower entity which shoots at mobs traversing in a straight line. + * @return StunTower entity with relevant components. + */ + public static Entity createStunTower() { + Entity stunTower = createBaseTower(); + StunTowerConfig config = configs.stunTower; + + AITaskComponent aiTaskComponent = new AITaskComponent() + .addTask(new StunTowerCombatTask(COMBAT_TASK_PRIORITY, WEAPON_TOWER_MAX_RANGE)); + + AnimationRenderComponent animator = + new AnimationRenderComponent( + ServiceLocator.getResourceService() + .getAsset(STUN_TOWER_ATLAS, TextureAtlas.class)); + animator.addAnimation(STUN_TOWER_IDLE_ANIM, STUN_TOWER_IDLE_SPEED, Animation.PlayMode.LOOP); + animator.addAnimation(STUN_TOWER_ATTACK_ANIM, STUN_TOWER_ATTACK_SPEED, Animation.PlayMode.LOOP); + + stunTower + .addComponent(new CombatStatsComponent(config.health, config.baseAttack)) + .addComponent((new CostComponent(config.cost))) + .addComponent(aiTaskComponent) + .addComponent(animator) + .addComponent(new StunTowerAnimationController()); + + stunTower.setScale(1.5f, 1.5f); + PhysicsUtils.setScaledCollider(stunTower, 0.5f, 0.5f); + return stunTower; + } + /** * Creates a generic tower entity to be used as a base entity by more specific tower creation methods. * @return entity diff --git a/source/core/src/main/com/csse3200/game/screens/MainGameScreen.java b/source/core/src/main/com/csse3200/game/screens/MainGameScreen.java index be9c88a21..651909937 100644 --- a/source/core/src/main/com/csse3200/game/screens/MainGameScreen.java +++ b/source/core/src/main/com/csse3200/game/screens/MainGameScreen.java @@ -185,7 +185,7 @@ private void loadAssets() { logger.debug("Loading assets"); ResourceService resourceService = ServiceLocator.getResourceService(); resourceService.loadTextures(mainGameTextures); - backgroundTexture = new Texture("images/background1.png"); // Load the background image + backgroundTexture = new Texture("images/background/background1.png"); // Load the background image ServiceLocator.getResourceService().loadAll(); } diff --git a/source/core/src/main/com/csse3200/game/screens/MainMenuScreen.java b/source/core/src/main/com/csse3200/game/screens/MainMenuScreen.java index dfe7ff2f7..a7bcc40f9 100644 --- a/source/core/src/main/com/csse3200/game/screens/MainMenuScreen.java +++ b/source/core/src/main/com/csse3200/game/screens/MainMenuScreen.java @@ -31,7 +31,7 @@ public class MainMenuScreen extends ScreenAdapter { private final Renderer renderer; private Texture backgroundTexture; private final SpriteBatch batch; - private static final String[] mainMenuTextures = {"images/Logo2.png"}; + private static final String[] mainMenuTextures = {"images/ui/Logo2.png"}; public MainMenuScreen(GdxGame game) { this.game = game; @@ -97,7 +97,7 @@ private void loadAssets() { logger.debug("Loading assets"); ResourceService resourceService = ServiceLocator.getResourceService(); resourceService.loadTextures(mainMenuTextures); - backgroundTexture = new Texture("images/background1.png"); // Load the background image + backgroundTexture = new Texture("images/background/background1.png"); // Load the background image ServiceLocator.getResourceService().loadAll(); } diff --git a/source/core/src/test/com/csse3200/game/currency/CurrencyTest.java b/source/core/src/test/com/csse3200/game/currency/CurrencyTest.java index 8fa375e4e..fff7d0c0a 100644 --- a/source/core/src/test/com/csse3200/game/currency/CurrencyTest.java +++ b/source/core/src/test/com/csse3200/game/currency/CurrencyTest.java @@ -21,7 +21,7 @@ @ExtendWith(GameExtension.class) class CurrencyTest { private Entity scrap; - private String[] texture = {"images/scrap.png"}; + private String[] texture = {"images/economy/scrap.png"}; @BeforeEach public void setUp() { diff --git a/source/core/src/test/com/csse3200/game/entities/factories/ProjectileFactoryTest.java b/source/core/src/test/com/csse3200/game/entities/factories/ProjectileFactoryTest.java index eba56f0ee..1e5c4fb27 100644 --- a/source/core/src/test/com/csse3200/game/entities/factories/ProjectileFactoryTest.java +++ b/source/core/src/test/com/csse3200/game/entities/factories/ProjectileFactoryTest.java @@ -30,7 +30,7 @@ @ExtendWith(GameExtension.class) class ProjectileFactoryTest { - private String[] texture = {"images/projectile.png"}; + private String[] texture = {"images/projectiles/projectile.png"}; private Entity projectile; @BeforeEach @@ -47,7 +47,7 @@ public void setUp() { resourceService.loadTextures(texture); resourceService.loadAll(); ServiceLocator.getResourceService() - .getAsset("images/projectile.png", Texture.class); + .getAsset("images/projectiles/projectile.png", Texture.class); Vector2 destination = new Vector2(0.1f, 0.1f); Vector2 speed = new Vector2(0.2f, 0.2f); diff --git a/source/core/src/test/com/csse3200/game/entities/factories/TowerFactoryTest.java b/source/core/src/test/com/csse3200/game/entities/factories/TowerFactoryTest.java index b25fcc1f2..0924d2667 100644 --- a/source/core/src/test/com/csse3200/game/entities/factories/TowerFactoryTest.java +++ b/source/core/src/test/com/csse3200/game/entities/factories/TowerFactoryTest.java @@ -40,15 +40,15 @@ public class TowerFactoryTest { private Entity weaponTower; private Entity wallTower; private String[] texture = { - "images/turret_deployed.png", - "images/turret01.png", - "images/wallTower.png" + "images/towers/turret_deployed.png", + "images/towers/turret01.png", + "images/towers/wallTower.png" }; - private String[] atlas = {"images/turret01.atlas"}; + private String[] atlas = {"images/towers/turret01.atlas"}; private static final String[] sounds = { - "sounds/gun_shot_trimmed.mp3", - "sounds/deploy.mp3", - "sounds/stow.mp3" + "sounds/towers/gun_shot_trimmed.mp3", + "sounds/towers/deploy.mp3", + "sounds/towers/stow.mp3" }; @BeforeEach @@ -67,7 +67,7 @@ public void setUp() { resourceService.loadSounds(sounds); resourceService.loadAll(); ServiceLocator.getResourceService() - .getAsset("images/turret01.atlas", TextureAtlas.class); + .getAsset("images/towers/turret01.atlas", TextureAtlas.class); baseTower = TowerFactory.createBaseTower(); weaponTower = TowerFactory.createWeaponTower(); wallTower = TowerFactory.createWallTower();