4141
4242import java .util .ArrayList ;
4343import java .util .List ;
44+ import java .util .Locale ;
4445
4546
4647import com .csse3200 .game .components .currencysystem .CurrencyManagerComponent ;
@@ -112,6 +113,10 @@ public class ForestGameArea extends GameArea {
112113 "sounds/place_soft_click.ogg" ,
113114 "sounds/place_metal_clunk.ogg" ,
114115 "sounds/place_energy_drop.ogg" ,
116+ "sounds/Impact4.ogg" ,
117+ "sounds/Explosion_sfx3.ogg" ,
118+ "sounds/sci-fi-effect-about-danger-alarm-sound.mp3" ,
119+ "sounds/explosion-in-the-cave.mp3" ,
115120 "sounds/Enemy Sounds/tank/Tank_Death.mp3" ,
116121 "sounds/Enemy Sounds/tank/Tank_Walk.mp3" ,
117122 "sounds/Enemy Sounds/tank/Tank_Attack.mp3" ,
@@ -139,6 +144,8 @@ public class ForestGameArea extends GameArea {
139144 "sounds/Enemy Sounds/speedster/Speedster_Attack.mp3" ,
140145 "sounds/Enemy Sounds/speedster/Speedster_Random_Noise.mp3"
141146 };
147+ private static final String PLASMA_WARNING_SOUND = "sounds/sci-fi-effect-about-danger-alarm-sound.mp3" ;
148+ private static final String PLASMA_IMPACT_SOUND = "sounds/explosion-in-the-cave.mp3" ;
142149 private static final String backgroundMusic = "sounds/new_menutheme.mp3" ;
143150 private static final String [] forestMusic = {backgroundMusic };
144151
@@ -611,7 +618,7 @@ public void update() {
611618 mapHighlighter .setTowerUpgradeMenu (towerUpgradeMenu );
612619
613620 if (!hasExistingPlayer ) {
614- spawnIntroDialogue ();
621+ showChapterIntro ();
615622 }
616623
617624 // Add hero placement system
@@ -730,7 +737,11 @@ private void handlePlasmaImpact(Vector2 position) {
730737 towerTargets .add (entity );
731738 continue ;
732739 }
733- if (entity .getComponent (EnemyTypeComponent .class ) != null ) {
740+ EnemyTypeComponent typeComponent = entity .getComponent (EnemyTypeComponent .class );
741+ if (typeComponent != null ) {
742+ if (isPlasmaImmune (typeComponent )) {
743+ continue ;
744+ }
734745 enemyTargets .add (entity );
735746 }
736747 }
@@ -769,6 +780,18 @@ private void dismantleTower(Entity tower) {
769780 ServiceLocator .getEntityService ().unregister (tower );
770781 }
771782
783+ private boolean isPlasmaImmune (EnemyTypeComponent typeComponent ) {
784+ if (typeComponent == null ) {
785+ return false ;
786+ }
787+ String type = typeComponent .getType ();
788+ if (type == null ) {
789+ return false ;
790+ }
791+ String normalised = type .trim ().toLowerCase (Locale .ROOT );
792+ return "tank" .equals (normalised ) || "boss" .equals (normalised );
793+ }
794+
772795 private void eliminateEnemy (Entity enemy ) {
773796 CombatStatsComponent stats = enemy .getComponent (CombatStatsComponent .class );
774797 if (stats != null ) {
@@ -1135,6 +1158,7 @@ private void spawnSamuraiAt(GridPoint2 cell) {
11351158 }
11361159
11371160 private void createHeroPlacementUI () {
1161+ // 先创建英雄放置实体,但初始隐藏
11381162 var gs = ServiceLocator .getGameStateService ();
11391163 GameStateService .HeroType chosen = gs .getSelectedHero ();
11401164 java .util .function .Consumer <com .badlogic .gdx .math .GridPoint2 > placeCb =
@@ -1147,6 +1171,45 @@ private void createHeroPlacementUI() {
11471171 .addComponent (new com .csse3200 .game .components .hero .HeroPlacementComponent (terrain , mapEditor , placeCb ))
11481172 .addComponent (new com .csse3200 .game .components .hero .HeroHotbarDisplay ());
11491173 spawnEntity (placementEntity );
1174+
1175+ // 立即隐藏英雄UI
1176+ hideHeroUI ();
1177+
1178+ // 2秒后显示英雄UI
1179+ com .badlogic .gdx .utils .Timer .schedule (new com .badlogic .gdx .utils .Timer .Task () {
1180+ @ Override
1181+ public void run () {
1182+ showHeroUI ();
1183+ }
1184+ }, 2.0f );
1185+ }
1186+
1187+ /**
1188+ * 隐藏英雄UI
1189+ */
1190+ private void hideHeroUI () {
1191+ for (Entity entity : ServiceLocator .getEntityService ().getEntities ()) {
1192+ com .csse3200 .game .components .hero .HeroHotbarDisplay heroUI = entity .getComponent (com .csse3200 .game .components .hero .HeroHotbarDisplay .class );
1193+ if (heroUI != null ) {
1194+ heroUI .setVisible (false );
1195+ logger .info ("英雄UI已隐藏" );
1196+ break ;
1197+ }
1198+ }
1199+ }
1200+
1201+ /**
1202+ * 显示英雄UI
1203+ */
1204+ private void showHeroUI () {
1205+ for (Entity entity : ServiceLocator .getEntityService ().getEntities ()) {
1206+ com .csse3200 .game .components .hero .HeroHotbarDisplay heroUI = entity .getComponent (com .csse3200 .game .components .hero .HeroHotbarDisplay .class );
1207+ if (heroUI != null ) {
1208+ heroUI .setVisible (true );
1209+ logger .info ("英雄UI已显示" );
1210+ break ;
1211+ }
1212+ }
11501213 }
11511214
11521215 private void spawnIntroDialogue () {
@@ -1173,6 +1236,27 @@ private void spawnIntroDialogue() {
11731236 );
11741237 spawnEntity (dialogueEntity );
11751238 }
1239+
1240+ /**
1241+ * 显示章节介绍
1242+ */
1243+ private void showChapterIntro () {
1244+ String [] storyTexts = {
1245+ "Chapter I : Icebox" ,
1246+ "This is Icebox, a former research outpost now buried beneath eternal night.\n The AI legions have ravaged this land beyond recognition,\n but now, it stands as the cradle of humanity's awakening." ,
1247+ "The sorcerers gathered here forming circles of frost and flame\n unleashed the first wave of pure human magic, untouched by machines.\n Glaciers shattered. Circuits failed.\n Across the frozen plains, the echoes of ancient power\n announced the dawn of rebellion.\n \n \" On the coldest land, the oldest flame burns once more.\" "
1248+ };
1249+
1250+ Entity chapterEntity = new Entity ().addComponent (
1251+ new com .csse3200 .game .components .maingame .ChapterIntroComponent (
1252+ storyTexts ,
1253+ () -> {
1254+ // 章节介绍结束后开始对话
1255+ spawnIntroDialogue ();
1256+ })
1257+ );
1258+ spawnEntity (chapterEntity );
1259+ }
11761260
11771261 /**
11781262 * Spawn the wave tracker UI
@@ -1187,15 +1271,30 @@ private void spawnWaveTracker() {
11871271 * 显示防御塔UI(在对话结束后调用)
11881272 */
11891273 private void showTowerUI () {
1190- // 找到主UI实体并显示防御塔列表组件
1274+ // 先隐藏塔防UI
11911275 for (Entity entity : ServiceLocator .getEntityService ().getEntities ()) {
11921276 TowerHotbarDisplay towerUI = entity .getComponent (TowerHotbarDisplay .class );
11931277 if (towerUI != null ) {
1194- towerUI .setVisible (true );
1195- logger .info ("防御塔列表已显示 " );
1278+ towerUI .setVisible (false );
1279+ logger .info ("防御塔列表已隐藏 " );
11961280 break ;
11971281 }
11981282 }
1283+
1284+ // 3.3秒后显示塔防UI
1285+ com .badlogic .gdx .utils .Timer .schedule (new com .badlogic .gdx .utils .Timer .Task () {
1286+ @ Override
1287+ public void run () {
1288+ for (Entity entity : ServiceLocator .getEntityService ().getEntities ()) {
1289+ TowerHotbarDisplay towerUI = entity .getComponent (TowerHotbarDisplay .class );
1290+ if (towerUI != null ) {
1291+ towerUI .setVisible (true );
1292+ logger .info ("防御塔列表已显示" );
1293+ break ;
1294+ }
1295+ }
1296+ }
1297+ }, 2.0f );
11991298 }
12001299
12011300 private void playMusic () {
@@ -1219,9 +1318,13 @@ private void loadAssets() {
12191318 resourceService .loadSounds (forestSounds );
12201319 resourceService .loadMusic (forestMusic );
12211320
1222- while (!resourceService .loadForMillis (10 )) {
1223- logger .info ("Loading... {}%" , resourceService .getProgress ());
1224- }
1321+ while (!resourceService .loadForMillis (10 )) {
1322+ logger .info ("Loading... {}%" , resourceService .getProgress ());
1323+ }
1324+ if (ServiceLocator .getAudioService () != null ) {
1325+ ServiceLocator .getAudioService ().registerSound ("plasma_warning" , PLASMA_WARNING_SOUND );
1326+ ServiceLocator .getAudioService ().registerSound ("plasma_impact" , PLASMA_IMPACT_SOUND );
1327+ }
12251328// try {
12261329// com.badlogic.gdx.audio.Sound s =
12271330// resourceService.getAsset("sounds/Explosion_sfx.ogg", com.badlogic.gdx.audio.Sound.class);
0 commit comments