From 4b582f6ac800f73780b842f7089bef8d5cd35360 Mon Sep 17 00:00:00 2001 From: Kevin <104761532+Hasakev@users.noreply.github.com> Date: Tue, 3 Oct 2023 11:23:58 +1000 Subject: [PATCH 1/7] Added observer such that when a turret is destroyed (disposed), the menu automatically closes --- .../csse3200/game/entities/EntityService.java | 14 ++++++++ .../game/input/UpgradeUIComponent.java | 33 ++++++++++++++++--- .../csse3200/game/screens/MainGameScreen.java | 18 ++++++---- 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/source/core/src/main/com/csse3200/game/entities/EntityService.java b/source/core/src/main/com/csse3200/game/entities/EntityService.java index 3511d598b..1804670e3 100644 --- a/source/core/src/main/com/csse3200/game/entities/EntityService.java +++ b/source/core/src/main/com/csse3200/game/entities/EntityService.java @@ -69,6 +69,20 @@ public void dispose() { } } + /** + * Find an entity by its ID, if it exists return true, else return false + * @param id id of entity to find + * @return boolean true if entity exists, false if not + */ + public boolean findEntityExistence(int id) { + for (Entity entity : entities) { + if (entity.getId() == id) { + return true; + } + } + return false; + } + /** * Get all entities */ diff --git a/source/core/src/main/com/csse3200/game/input/UpgradeUIComponent.java b/source/core/src/main/com/csse3200/game/input/UpgradeUIComponent.java index cffd36cc6..1d2052c14 100644 --- a/source/core/src/main/com/csse3200/game/input/UpgradeUIComponent.java +++ b/source/core/src/main/com/csse3200/game/input/UpgradeUIComponent.java @@ -33,6 +33,7 @@ import org.slf4j.LoggerFactory; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; public class UpgradeUIComponent extends InputComponent { @@ -71,16 +72,14 @@ public Stage getStage() { @Override public boolean touchDown(int screenX, int screenY, int pointer, int button) { - // Clear all existing upgrade tables - - Vector3 worldCoordinates = new Vector3((float) screenX, (float) screenY, 0); getCamera().unproject(worldCoordinates); Vector2 cursorPosition = new Vector2(worldCoordinates.x, worldCoordinates.y); Entity clickedEntity = entityService.getEntityAtPosition(cursorPosition.x, cursorPosition.y); if (clickedEntity != null && clickedEntity.getComponent(TowerUpgraderComponent.class) != null && clickedEntity.getComponent(TNTDamageComponent.class) == null) { -// logger.info("clicked a turret that is upgradable!"); +// // Clear all existing upgrade tables + logger.info("clickedEntity: " + clickedEntity); clearUpgradeTables(); // Check if there is an existing upgrade table for this turret entity Table existingUpgradeTable = upgradeTables.get(clickedEntity); @@ -97,6 +96,7 @@ public boolean touchDown(int screenX, int screenY, int pointer, int button) { // Store the new upgrade table in the map upgradeTables.put(clickedEntity, newUpgradeTable); + } return true; @@ -371,4 +371,29 @@ private LabelStyle createLabelStyle() { style.fontColor = Color.WHITE; return style; } + + + /** + * Update method for the UpgradeUIComponent, checks if the entity is disposed and removes the upgrade table + */ + public void checkForDispose() { + if (!upgradeTables.isEmpty()) { + // Iterate over the entries in the upgradeTables map + Iterator> iterator = upgradeTables.entrySet().iterator(); +// logger.info("upgradeTables size: " + upgradeTables.size()); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + Entity entity = entry.getKey(); +// logger.info("entity: " + entity); + // Check if the entity is disposed (use your own disposal condition) + if (!ServiceLocator.getEntityService().findEntityExistence(entity.getId())) { + Table upgradeTable = entry.getValue(); + upgradeTable.remove(); // Remove the upgrade table + iterator.remove(); // Remove the entry from the map + } + } + } + } + + } 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 dc7f8d293..083a8874b 100644 --- a/source/core/src/main/com/csse3200/game/screens/MainGameScreen.java +++ b/source/core/src/main/com/csse3200/game/screens/MainGameScreen.java @@ -11,7 +11,6 @@ import com.badlogic.gdx.utils.viewport.ScreenViewport; import com.csse3200.game.GdxGame; import com.csse3200.game.areas.ForestGameArea; -import com.csse3200.game.areas.terrain.TerrainFactory; import com.csse3200.game.components.gamearea.PerformanceDisplay; import com.csse3200.game.components.maingame.MainGameActions; import com.csse3200.game.components.maingame.MainGameLoseDisplay; @@ -44,6 +43,7 @@ public class MainGameScreen extends ScreenAdapter { private final Renderer renderer; private final PhysicsEngine physicsEngine; + private InputComponent upgradedInputHandler; private final Stage stage; static int screenWidth = Gdx.graphics.getWidth(); static int screenHeight = Gdx.graphics.getHeight(); @@ -92,12 +92,11 @@ public MainGameScreen(GdxGame game) { renderer.getCamera().getEntity().setPosition(CAMERA_POSITION); renderer.getDebug().renderPhysicsWorld(physicsEngine.getWorld()); InputComponent inputHandler = new DropInputComponent(renderer.getCamera().getCamera()); - InputComponent UpgradedInputHandler = new UpgradeUIComponent(renderer.getCamera().getCamera(), renderer.getStage()); - - InputComponent engineerInputHnadler = new EngineerInputComponent(game, renderer.getCamera().getCamera()); + upgradedInputHandler = new UpgradeUIComponent(renderer.getCamera().getCamera(), renderer.getStage()); + InputComponent engineerInputHandler = new EngineerInputComponent(game, renderer.getCamera().getCamera()); ServiceLocator.getInputService().register(inputHandler); - ServiceLocator.getInputService().register(engineerInputHnadler); - ServiceLocator.getInputService().register(UpgradedInputHandler); + ServiceLocator.getInputService().register(engineerInputHandler); + ServiceLocator.getInputService().register(upgradedInputHandler); ServiceLocator.getCurrencyService().getDisplay().setCamera(renderer.getCamera().getCamera()); loadAssets(); @@ -162,6 +161,9 @@ public void render(float delta) { physicsEngine.update(); ServiceLocator.getEntityService().update(); + // Checks if tower selected is dead + this.getUpgradedInputHandler().checkForDispose(); + // Check if the game has ended if (ServiceLocator.getGameEndService().hasGameEnded()) { ui.getEvents().trigger("lose"); @@ -236,4 +238,8 @@ private void createUI() { ServiceLocator.getEntityService().register(ui); } + + private UpgradeUIComponent getUpgradedInputHandler() { + return (UpgradeUIComponent) upgradedInputHandler; + } } \ No newline at end of file From a49a4fab52f1e38a6ae0e28dca71d7d7f0f6e272 Mon Sep 17 00:00:00 2001 From: Kevin <104761532+Hasakev@users.noreply.github.com> Date: Tue, 3 Oct 2023 12:03:14 +1000 Subject: [PATCH 2/7] Added some important comments to files --- .../game/input/UpgradeUIComponent.java | 59 ++++++++++++++++--- .../game/screens/TurretSelectionScreen.java | 26 ++++++++ 2 files changed, 76 insertions(+), 9 deletions(-) diff --git a/source/core/src/main/com/csse3200/game/input/UpgradeUIComponent.java b/source/core/src/main/com/csse3200/game/input/UpgradeUIComponent.java index 1d2052c14..8e0c3f4a1 100644 --- a/source/core/src/main/com/csse3200/game/input/UpgradeUIComponent.java +++ b/source/core/src/main/com/csse3200/game/input/UpgradeUIComponent.java @@ -66,10 +66,21 @@ public Camera getCamera() { return camera; } + /** + * Getter for the stage + * @return the stage + */ public Stage getStage() { return stage; } + /** + * Method to handle the touch down event + * @param screenX the x coordinate of the touch + * @param screenY the y coordinate of the touch + * @param pointer the pointer + * @param button the button + */ @Override public boolean touchDown(int screenX, int screenY, int pointer, int button) { Vector3 worldCoordinates = new Vector3((float) screenX, (float) screenY, 0); @@ -77,8 +88,11 @@ public boolean touchDown(int screenX, int screenY, int pointer, int button) { Vector2 cursorPosition = new Vector2(worldCoordinates.x, worldCoordinates.y); Entity clickedEntity = entityService.getEntityAtPosition(cursorPosition.x, cursorPosition.y); - if (clickedEntity != null && clickedEntity.getComponent(TowerUpgraderComponent.class) != null && clickedEntity.getComponent(TNTDamageComponent.class) == null) { -// // Clear all existing upgrade tables + // If the clicked position contains a turret, and the turret is upgradable and not a TNT tower + if (clickedEntity != null && clickedEntity.getComponent(TowerUpgraderComponent.class) != null + && clickedEntity.getComponent(TNTDamageComponent.class) == null) { + // TNT TowerUpgraderComponent can be removed later, but possibly useful for future sprint. + // Clear all existing upgrade tables logger.info("clickedEntity: " + clickedEntity); clearUpgradeTables(); // Check if there is an existing upgrade table for this turret entity @@ -112,28 +126,43 @@ private void clearUpgradeTables() { upgradeTables.clear(); } + /** + * Creates the upgrade table for the associated turret entity + *

+ * Each button has a listener that will upgrade the turret entity when clicked + * if the player has enough scrap. Additionally when the player hovers over a button + * the cost of the upgrade will be displayed in the cost display + *

+ * + * Currently, the cost of each upgrade is hardcoded to 10 scrap, this can be changed to global + * variables to make balancing easier (contact @Hasakev (Kevin) if confused) + * + * @param turretEntity the turret entity to create the upgrade table for (the entity that was clicked) + * @return the upgrade table for the turret entity + */ private Table createUpgradeTable(Entity turretEntity) { + // This is the overarching table that contains the close button, the inner table, and the cost display Table upgradeTable = new Table(); upgradeTable.top(); upgradeTable.defaults().pad(0).space(0); upgradeTable.setSize(60, 60); + + // The inner table contains the upgrade buttons and the stats display Table innerUpgradeTable = new Table(); innerUpgradeTable.top(); innerUpgradeTable.defaults().pad(10).space(0).padBottom(1); innerUpgradeTable.setSize(60, 60); // set table background String imageFilePath = "images/ui/Sprites/UI_Glass_Frame_Standard_01a.png"; - String upgradeButtonFilePath = "images/economy/scrapBanner.png"; Drawable drawableBackground = new TextureRegionDrawable(new TextureRegion(new Texture(imageFilePath))); innerUpgradeTable.setBackground(drawableBackground); + // Stying for all the buttons Drawable drawable = new TextureRegionDrawable(new TextureRegion(new Texture("images/ui/Sprites/UI_Glass_Button_Small_Lock_01a2.png"))); - Drawable econDrawable = new TextureRegionDrawable(new TextureRegion(new Texture(upgradeButtonFilePath))); TextButton.TextButtonStyle style = new TextButton.TextButtonStyle( drawable, drawable, drawable, new BitmapFont()); - TextButton.TextButtonStyle econStyle = new TextButton.TextButtonStyle( - econDrawable, econDrawable, econDrawable, new BitmapFont()); - // create button + + // Default values for the stats int maxHealth = turretEntity.getComponent(CombatStatsComponent.class).getMaxHealth(); int currentHealth = turretEntity.getComponent(CombatStatsComponent.class).getHealth(); turretEntity.getComponent(CombatStatsComponent.class).setHealth(5); // for testing @@ -173,9 +202,12 @@ public void clicked(InputEvent event, float x, float y) { Drawable fireRateDrawable = new TextureRegionDrawable(new TextureRegion(new Texture("images/hourglass.png"))); Image fireRateImage = new Image(fireRateDrawable); - Drawable healthStyle = new TextureRegionDrawable(new TextureRegion(new Texture("images/heart_upgrade.png"))); ImageButton upgradeHealth = new ImageButton(healthStyle); + + //// UPGRADE BUTTONS //// + + // Health upgrade button upgradeHealth.setScale(0.8f); upgradeHealth.addListener(new ClickListener() { @Override @@ -204,6 +236,7 @@ public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) } }); + // Attack upgrade button Drawable attackStyle = new TextureRegionDrawable(new TextureRegion(new Texture("images/damage_upgrade.png"))); ImageButton upgradeAttack = new ImageButton(attackStyle); upgradeAttack.addListener(new ClickListener() { @@ -232,7 +265,7 @@ public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) }); - + // Fire rate upgrade button Drawable asStyle = new TextureRegionDrawable(new TextureRegion(new Texture("images/hourglass_upgrade.png"))); ImageButton upgradeFireRate = new ImageButton(asStyle); upgradeFireRate.addListener(new ClickListener() { @@ -265,6 +298,7 @@ public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) } }); + // Repair button Drawable repair = new TextureRegionDrawable(new TextureRegion(new Texture("images/hammer.png"))); ImageButton repairButton = new ImageButton(repair); repairButton.addListener(new ClickListener() { @@ -299,7 +333,10 @@ public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) innerUpgradeTable.add(healthLabel).expandX().left(); innerUpgradeTable.row(); TextButton upgradeIncome = null; + // if the turret has an income upgrade component, add the income upgrade button if (turretEntity.getComponent(IncomeUpgradeComponent.class) != null) { + + // Income label and upgrade button Drawable incomeDrawable = new TextureRegionDrawable(new TextureRegion(new Texture("images/economy/scrap.png"))); Image incomeImage = new Image(incomeDrawable); Label incomeLabel = new Label(String.format("%.2f", turretEntity.getComponent(IncomeUpgradeComponent.class).getIncomeRate()), createLabelStyle()); @@ -365,6 +402,10 @@ public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) return upgradeTable; } + /** + * Creates a label style for the upgrade table + * @return the label style + */ private LabelStyle createLabelStyle() { LabelStyle style = new LabelStyle(); style.font = new BitmapFont(); diff --git a/source/core/src/main/com/csse3200/game/screens/TurretSelectionScreen.java b/source/core/src/main/com/csse3200/game/screens/TurretSelectionScreen.java index a679dd30c..7bfe77121 100644 --- a/source/core/src/main/com/csse3200/game/screens/TurretSelectionScreen.java +++ b/source/core/src/main/com/csse3200/game/screens/TurretSelectionScreen.java @@ -59,6 +59,10 @@ public class TurretSelectionScreen extends ScreenAdapter { private static final Logger logger = LoggerFactory.getLogger(MainMenuScreen.class); + /** + * Constructor for the TurretSelectionScreen + * @param game The game object + */ public TurretSelectionScreen(GdxGame game) { this.game = game; stage = new Stage(new ScreenViewport()); @@ -219,10 +223,23 @@ public void render(float delta) { stage.draw(); // Draw the stage } + /** + * Returns the list of selected turrets + * @return The list of selected turrets + */ public List getTurretList() { return turretList; } + /** + * Creates a button with the specified images and text + * @param defaultImageFilePath The file path to the default image + * @param alternateImageFilePath The file path to the alternate image + * @param cost The cost of the turret + * @param towerName The name of the turret + * @param turretDesc The description of the turret + * @return The created button + */ private TextButton createButton(String defaultImageFilePath, String alternateImageFilePath, String cost, String towerName, String turretDesc) { Drawable defaultDrawable = new TextureRegionDrawable(new TextureRegion(new Texture(defaultImageFilePath))); @@ -280,14 +297,23 @@ public void exit(InputEvent event, float x, float y, int pointer, com.badlogic.g return tb; } + /** + * Updates the description label + */ private void updateDescriptionLabel() { descriptionLabel.setText("Description: " + turretDescription); } + /** + * Updates the description text + */ private void updateDescriptionText() { descText.setText(turretDescriptionText); } + /** + * Disposes of the stage + */ @Override public void dispose() { stage.dispose(); From 8a3c206466421891b573b2b9149f5c2bed2b735a Mon Sep 17 00:00:00 2001 From: Kevin <104761532+Hasakev@users.noreply.github.com> Date: Tue, 3 Oct 2023 12:34:27 +1000 Subject: [PATCH 3/7] Added component test for income Rate --- .../game/components/tasks/CurrencyTask.java | 4 ++++ .../tower/TowerUpgraderComponentTest.java | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/source/core/src/main/com/csse3200/game/components/tasks/CurrencyTask.java b/source/core/src/main/com/csse3200/game/components/tasks/CurrencyTask.java index c280db0bd..1793115c6 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/CurrencyTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/CurrencyTask.java @@ -99,4 +99,8 @@ public void changeInterval(int newInterval) { public void setInterval(int interval) { this.interval = interval; } + + public int getInterval() { + return interval; + } } diff --git a/source/core/src/test/com/csse3200/game/components/tower/TowerUpgraderComponentTest.java b/source/core/src/test/com/csse3200/game/components/tower/TowerUpgraderComponentTest.java index 973937fb1..8f11df426 100644 --- a/source/core/src/test/com/csse3200/game/components/tower/TowerUpgraderComponentTest.java +++ b/source/core/src/test/com/csse3200/game/components/tower/TowerUpgraderComponentTest.java @@ -2,6 +2,7 @@ import com.csse3200.game.ai.tasks.AITaskComponent; import com.csse3200.game.components.CombatStatsComponent; +import com.csse3200.game.components.tasks.CurrencyTask; import com.csse3200.game.components.tasks.TowerCombatTask; import com.csse3200.game.entities.Entity; import com.csse3200.game.extensions.GameExtension; @@ -78,4 +79,19 @@ void divideByZeroDefaultToIgnore() { verify(towerUpgraderComponent).upgradeTower(TowerUpgraderComponent.UPGRADE.FIRERATE, 60); assertEquals((1/12f), towerCombatTask.getFireRateInterval()); } + + @Test + void incomeRate() { + entity.addComponent(towerUpgraderComponent); + AITaskComponent aiTaskComponent = new AITaskComponent(); + ServiceLocator.registerTimeSource(mock(GameTime.class)); + CurrencyTask currencyTask = new CurrencyTask(10, 10); + aiTaskComponent.addTask(currencyTask); + entity.addComponent(aiTaskComponent); + currencyTask.start(); + entity.create(); + entity.getEvents().trigger("upgradeTower", TowerUpgraderComponent.UPGRADE.INCOME, 60); + verify(towerUpgraderComponent).upgradeTower(TowerUpgraderComponent.UPGRADE.INCOME, 60); + assertEquals(60, currencyTask.getInterval()); + } } From cc0f6b215db487da22754b24373acb5cc5c2abd7 Mon Sep 17 00:00:00 2001 From: Kevin <104761532+Hasakev@users.noreply.github.com> Date: Tue, 3 Oct 2023 13:06:23 +1000 Subject: [PATCH 4/7] Reimplemented upgrade button for income turret --- .../main/com/csse3200/game/input/UpgradeUIComponent.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/core/src/main/com/csse3200/game/input/UpgradeUIComponent.java b/source/core/src/main/com/csse3200/game/input/UpgradeUIComponent.java index 8e0c3f4a1..19e4d2641 100644 --- a/source/core/src/main/com/csse3200/game/input/UpgradeUIComponent.java +++ b/source/core/src/main/com/csse3200/game/input/UpgradeUIComponent.java @@ -332,7 +332,7 @@ public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) innerUpgradeTable.add(healthIconImage).padRight(5).width(32).height(32); // Add health icon innerUpgradeTable.add(healthLabel).expandX().left(); innerUpgradeTable.row(); - TextButton upgradeIncome = null; + ImageButton upgradeIncome = null; // if the turret has an income upgrade component, add the income upgrade button if (turretEntity.getComponent(IncomeUpgradeComponent.class) != null) { @@ -345,8 +345,8 @@ public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) innerUpgradeTable.row(); Drawable income = new TextureRegionDrawable(new TextureRegion(new Texture("images/scrap_upgrade.png"))); - ImageButton attackStyleButton = new ImageButton(asStyle); - attackStyleButton.addListener(new ClickListener() { + upgradeIncome = new ImageButton(income); + upgradeIncome.addListener(new ClickListener() { @Override public void clicked(InputEvent event, float x, float y) { value = ServiceLocator.getCurrencyService().getScrap().getAmount(); From 4507c494968cb7fd0e672e8466bf6e099d841c5e Mon Sep 17 00:00:00 2001 From: Kevin <104761532+Hasakev@users.noreply.github.com> Date: Tue, 3 Oct 2023 13:19:46 +1000 Subject: [PATCH 5/7] Reimplemented income tower upgrade (previously removed) also reimplemneted build handler (accidentally removed) --- .../core/src/main/com/csse3200/game/screens/MainGameScreen.java | 2 ++ 1 file changed, 2 insertions(+) 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 111cd5aa1..55623b881 100644 --- a/source/core/src/main/com/csse3200/game/screens/MainGameScreen.java +++ b/source/core/src/main/com/csse3200/game/screens/MainGameScreen.java @@ -136,9 +136,11 @@ public MainGameScreen(GdxGame game) { renderer.getCamera().getEntity().setPosition(CAMERA_POSITION); renderer.getDebug().renderPhysicsWorld(physicsEngine.getWorld()); InputComponent inputHandler = new DropInputComponent(renderer.getCamera().getCamera()); + InputComponent buildHandler = new BuildInputComponent(renderer.getCamera().getCamera()); upgradedInputHandler = new UpgradeUIComponent(renderer.getCamera().getCamera(), renderer.getStage()); InputComponent engineerInputHandler = new EngineerInputComponent(game, renderer.getCamera().getCamera()); ServiceLocator.getInputService().register(inputHandler); + ServiceLocator.getInputService().register(buildHandler); ServiceLocator.getInputService().register(engineerInputHandler); ServiceLocator.getInputService().register(upgradedInputHandler); ServiceLocator.getCurrencyService().getDisplay().setCamera(renderer.getCamera().getCamera()); From aa253c4af037ddebf7c8c47eb4990c614afd71d4 Mon Sep 17 00:00:00 2001 From: Ahmad Abu-Aysha <111224176+The-AhmadAA@users.noreply.github.com> Date: Tue, 3 Oct 2023 14:09:31 +1000 Subject: [PATCH 6/7] added music to story screen --- .../csse3200/game/screens/StoryScreen.java | 15 + .../game/input/BuildInputComponentTest.java | 307 +++++++++--------- 2 files changed, 174 insertions(+), 148 deletions(-) diff --git a/source/core/src/main/com/csse3200/game/screens/StoryScreen.java b/source/core/src/main/com/csse3200/game/screens/StoryScreen.java index d294730be..398a9b352 100644 --- a/source/core/src/main/com/csse3200/game/screens/StoryScreen.java +++ b/source/core/src/main/com/csse3200/game/screens/StoryScreen.java @@ -2,6 +2,7 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.ScreenAdapter; +import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.BitmapFont; @@ -17,6 +18,8 @@ import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.utils.viewport.FitViewport; import com.csse3200.game.GdxGame; +import com.csse3200.game.services.ResourceService; +import com.csse3200.game.services.ServiceLocator; /** * Screen that displays a story with images and text. @@ -67,6 +70,10 @@ public class StoryScreen extends ScreenAdapter { "all seems perfect until we picked up on a looming threat that maybe we aren't alone......", // Add more text as needed }; + private String[] bgm = { + "sounds/background/pre_game/Sci-Fi8Loop_story.ogg" + }; + private Music music; /** * Creates a new StoryScreen. * @@ -83,6 +90,10 @@ public StoryScreen(GdxGame game) { for (int i = 0; i < IMAGE_PATHS.length; i++) { images[i] = new Texture(IMAGE_PATHS[i]); } + ServiceLocator.registerResourceService(new ResourceService()); + ServiceLocator.getResourceService().loadMusic(bgm); + ServiceLocator.getResourceService().loadAll(); + music = ServiceLocator.getResourceService().getAsset(bgm[0], Music.class); } @Override @@ -128,6 +139,9 @@ public void clicked(com.badlogic.gdx.scenes.scene2d.InputEvent event, float x, f table.pad(20); // Add padding to the top-right corner table.add(buttonTable).row(); // Add button table and move to the next row stage.addActor(table); + music.setVolume(0.4f); + music.setLooping(true); + music.play(); } @Override @@ -201,5 +215,6 @@ public void dispose() { boldFont.dispose(); stage.dispose(); shapeRenderer.dispose(); + music.dispose(); } } diff --git a/source/core/src/test/com/csse3200/game/input/BuildInputComponentTest.java b/source/core/src/test/com/csse3200/game/input/BuildInputComponentTest.java index f5f7fe1cc..3cd427659 100644 --- a/source/core/src/test/com/csse3200/game/input/BuildInputComponentTest.java +++ b/source/core/src/test/com/csse3200/game/input/BuildInputComponentTest.java @@ -1,148 +1,159 @@ -package com.csse3200.game.input; - -import com.badlogic.gdx.math.Vector2; -import com.csse3200.game.extensions.GameExtension; -import com.csse3200.game.services.ServiceLocator; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; - -@ExtendWith(GameExtension.class) -class BuildInputComponentTest { - - @BeforeEach - void setup() { - - } - - @AfterEach - void tearDown() { - - } - - @Test - void shouldUpdatePriority() { - int newPriority = 100; - InputComponent inputComponent = spy(InputComponent.class); - - inputComponent.setPriority(newPriority); - verify(inputComponent).setPriority(newPriority); - - int priority = inputComponent.getPriority(); - verify(inputComponent).getPriority(); - - assertEquals(newPriority, priority); - } - - @Test - void shouldRegisterOnCreate() { - InputService inputService = spy(InputService.class); - ServiceLocator.registerInputService(inputService); - - InputComponent inputComponent = spy(InputComponent.class); - inputComponent.create(); - verify(inputService).register(inputComponent); - } - - @Test - void shouldHandleKeyDown(){ - InputComponent inputComponent = spy(InputComponent.class); - assertFalse(inputComponent.keyDown(1)); - } - - @Test - void shouldHandleKeyTyped() { - InputComponent inputComponent = spy(InputComponent.class); - assertFalse(inputComponent.keyTyped('a')); - } - - @Test - void shouldHandleKeyUp() { - InputComponent inputComponent = spy(InputComponent.class); - assertFalse(inputComponent.keyUp(1)); - } - - @Test - void shouldHandleMouseMoved() { - InputComponent inputComponent = spy(InputComponent.class); - assertFalse(inputComponent.mouseMoved( 5, 6)); - } - - @Test - void shouldHandleScrolled() { - InputComponent inputComponent = spy(InputComponent.class); - assertFalse(inputComponent.scrolled( 5f, 6f)); - } - - @Test - void shouldHandleTouchDown() { - InputComponent inputComponent = spy(InputComponent.class); - assertFalse(inputComponent.touchDown( 5, 6, 7, 8)); - } - - @Test - void shouldHandleTouchDragged() { - InputComponent inputComponent = spy(InputComponent.class); - assertFalse(inputComponent.touchDragged(5, 6, 7)); - } - - @Test - void shouldHandleTouchUp() { - InputComponent inputComponent = spy(InputComponent.class); - assertFalse(inputComponent.touchUp( 5, 6, 7, 8)); - } - - @Test - void shouldHandleFling(){ - InputComponent inputComponent = spy(InputComponent.class); - assertFalse(inputComponent.fling( 5f, 6f, 7)); - } - - @Test - void shouldHandleLongPress(){ - InputComponent inputComponent = spy(InputComponent.class); - assertFalse(inputComponent.longPress(5f, 6f)); - } - - @Test - void shouldHandlePan(){ - InputComponent inputComponent = spy(InputComponent.class); - assertFalse(inputComponent.pan( 5f, 6f, 7f, 8f)); - } - - @Test - void shouldHandlePanStop(){ - InputComponent inputComponent = spy(InputComponent.class); - assertFalse(inputComponent.panStop( 5f, 6f, 7, 8)); - } - - @Test - void shouldHandlePinch(){ - InputComponent inputComponent = spy(InputComponent.class); - assertFalse(inputComponent.pinch(Vector2.Zero, Vector2.Zero, Vector2.Zero, Vector2.Zero)); - } - - @Test - void shouldHandleTap() { - InputComponent inputComponent = spy(InputComponent.class); - assertFalse(inputComponent.tap(5f, 6f, 7, 8)); - } - - @Test - void shouldHandleTouchDownGesture(){ - InputComponent inputComponent = spy(InputComponent.class); - assertFalse(inputComponent.touchDown(5f, 6f, 7, 8)); - } - - @Test - void shouldHandleZoom(){ - InputComponent inputComponent = spy(InputComponent.class); - assertFalse(inputComponent.zoom(5f, 6f)); - } -} +//package com.csse3200.game.input; +// +//import com.badlogic.gdx.graphics.g2d.TextureAtlas; +//import com.badlogic.gdx.maps.tiled.TiledMap; +//import com.badlogic.gdx.math.Vector2; +//import com.csse3200.game.components.CameraComponent; +//import com.csse3200.game.currency.Currency; +//import com.csse3200.game.entities.Entity; +//import com.csse3200.game.entities.EntityService; +//import com.csse3200.game.entities.factories.TowerFactory; +//import com.csse3200.game.extensions.GameExtension; +//import com.csse3200.game.physics.PhysicsService; +//import com.csse3200.game.rendering.DebugRenderer; +//import com.csse3200.game.rendering.RenderService; +//import com.csse3200.game.services.*; +//import org.junit.jupiter.api.AfterEach; +//import org.junit.jupiter.api.BeforeEach; +//import org.junit.jupiter.api.Test; +//import org.junit.jupiter.api.extension.ExtendWith; +// +//import static org.junit.jupiter.api.Assertions.assertEquals; +//import static org.junit.jupiter.api.Assertions.assertFalse; +//import static org.mockito.Mockito.*; +// +//@ExtendWith(GameExtension.class) +//class BuildInputComponentTest { +// +// private BuildInputComponent buildInputComponent; +// private Entity baseTower; +// private Entity weaponTower; +// private Entity wallTower; +// private Entity stunTower; +// private Entity fireTower; +// private Entity tntTower; +// private Entity droidTower; +// private String[] texture = { +// "images/towers/turret_deployed.png", +// "images/towers/turret01.png", +// "images/towers/wall_tower.png", +// "images/towers/fire_tower_atlas.png", +// "images/towers/stun_tower.png", +// "images/towers/DroidTower.png", +// "images/towers/TNTTower.png" +// }; +// private String[] atlas = { +// "images/towers/turret01.atlas", +// "images/towers/stun_tower.atlas", +// "images/towers/fire_tower_atlas.atlas", +// "images/towers/DroidTower.atlas", +// "images/towers/TNTTower.atlas", +// "images/towers/barrier.atlas" +// }; +// private static final String[] sounds = { +// "sounds/towers/gun_shot_trimmed.mp3", +// "sounds/towers/deploy.mp3", +// "sounds/towers/stow.mp3" +// }; +// +// @BeforeEach +// void setup() { +// GameTime gameTime = mock(GameTime.class); +// CameraComponent camera = mock(CameraComponent.class); +// when(gameTime.getDeltaTime()).thenReturn(0.02f); +// ServiceLocator.registerTimeSource(gameTime); +// ServiceLocator.registerPhysicsService(new PhysicsService()); +// RenderService render = new RenderService(); +// render.setDebug(mock(DebugRenderer.class)); +// ServiceLocator.registerRenderService(render); +// +// CurrencyService currencyService = new CurrencyService(); +// ResourceService resourceService = new ResourceService(); +// MapService mapService = new MapService(camera); +// EntityService entityService = new EntityService(); +// +// ServiceLocator.registerResourceService(resourceService); +// ServiceLocator.registerCurrencyService(currencyService); +// ServiceLocator.registerMapService(mapService); +// ServiceLocator.registerEntityService(entityService); +// +// resourceService.loadTextures(texture); +// resourceService.loadTextureAtlases(atlas); +// resourceService.loadSounds(sounds); +// resourceService.loadAll(); +// +// ServiceLocator.getResourceService() +// .getAsset("images/towers/turret01.atlas", TextureAtlas.class); +// baseTower = TowerFactory.createBaseTower(); +// weaponTower = TowerFactory.createWeaponTower(); +// wallTower = TowerFactory.createWallTower(); +// fireTower = TowerFactory.createFireTower(); +// stunTower = TowerFactory.createFireTower(); +// tntTower = TowerFactory.createTNTTower(); +// droidTower = TowerFactory.createDroidTower(); +// +// buildInputComponent = new BuildInputComponent(camera.getCamera()); +// } +// +// @Test +// void shouldUpdatePriority() { +// int newPriority = 100; +// InputComponent inputComponent = spy(InputComponent.class); +// +// inputComponent.setPriority(newPriority); +// verify(inputComponent).setPriority(newPriority); +// +// int priority = inputComponent.getPriority(); +// verify(inputComponent).getPriority(); +// +// assertEquals(newPriority, priority); +// } +// +// @Test +// void shouldRegisterOnCreate() { +// InputService inputService = spy(InputService.class); +// ServiceLocator.registerInputService(inputService); +// +// InputComponent inputComponent = spy(InputComponent.class); +// inputComponent.create(); +// verify(inputService).register(inputComponent); +// } +// +// @Test +// void shouldHandleTouchDown() { +// BuildInputComponent inputComponent = spy(BuildInputComponent.class); +// assertFalse(inputComponent.touchDown( 5, 6, 7, 8)); +// } +// +// @Test +// void shouldRejectOccupiedTile() { +// Vector2 tile = ServiceLocator.getMapService().getComponent().tileToWorldPosition(0, 0); +// tntTower.setPosition(0,0); +// assertFalse(buildInputComponent.touchDown(0,0, 7,8)); +// } +// +// @Test +// void shouldRejectInvalidTile() { +// +// } +// +// @Test +// void shouldHandleMissingMapService() { +// +// } +// +// @Test +// void shouldHandleMissingCurrencyService() { +// +// } +// +// @Test +// void shouldHandleInvalidTower() { +// +// } +// +// @Test +// void shouldHandleMissingEntityService() { +// +// } +//} From bb5a7f8a59c303b4fed26d33375ef12701671781 Mon Sep 17 00:00:00 2001 From: Ahmad Abu-Aysha <111224176+The-AhmadAA@users.noreply.github.com> Date: Tue, 3 Oct 2023 14:18:56 +1000 Subject: [PATCH 7/7] added music to level select and turret select screens --- .../game/screens/LevelSelectScreen.java | 17 +++++++++++++++++ .../game/screens/TurretSelectionScreen.java | 16 ++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/source/core/src/main/com/csse3200/game/screens/LevelSelectScreen.java b/source/core/src/main/com/csse3200/game/screens/LevelSelectScreen.java index 4db4580f7..a14208b54 100644 --- a/source/core/src/main/com/csse3200/game/screens/LevelSelectScreen.java +++ b/source/core/src/main/com/csse3200/game/screens/LevelSelectScreen.java @@ -2,6 +2,7 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.ScreenAdapter; +import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.BitmapFont; @@ -23,6 +24,7 @@ import com.csse3200.game.screens.text.AnimatedText; import com.csse3200.game.screens.Planets; import com.csse3200.game.services.GameEndService; +import com.csse3200.game.services.ResourceService; import com.csse3200.game.services.ServiceLocator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,6 +47,10 @@ public class LevelSelectScreen extends ScreenAdapter { private BitmapFont font; private Sprite background; + private String[] bgm = { + "sounds/background/pre_game/Sci-Fi8Loop_story.ogg" + }; + private Music music; // Stores a time to determine the frame of the planet // TODO: Account for integer overflow @@ -77,6 +83,12 @@ public void clicked(com.badlogic.gdx.scenes.scene2d.InputEvent event, float x, f table1.pad(20); // Add padding to the top-right corner table1.add(buttonTable).row(); // Add button table and move to the next row stage.addActor(table1); + + ServiceLocator.registerResourceService(new ResourceService()); + ServiceLocator.getResourceService().loadMusic(bgm); + ServiceLocator.getResourceService().loadAll(); + music = ServiceLocator.getResourceService().getAsset(bgm[0], Music.class); + } @Override @@ -85,6 +97,10 @@ public void show() { background = new Sprite(new Texture(BG_PATH)); ServiceLocator.registerGameEndService(new GameEndService()); Gdx.input.setInputProcessor(stage); + + music.setVolume(0.4f); + music.setLooping(true); + music.play(); } /** @@ -174,5 +190,6 @@ public void resize(int width, int height) { public void dispose() { stage.dispose(); batch.dispose(); + music.dispose(); } } \ No newline at end of file diff --git a/source/core/src/main/com/csse3200/game/screens/TurretSelectionScreen.java b/source/core/src/main/com/csse3200/game/screens/TurretSelectionScreen.java index 357ab0fd6..eb3df9e70 100644 --- a/source/core/src/main/com/csse3200/game/screens/TurretSelectionScreen.java +++ b/source/core/src/main/com/csse3200/game/screens/TurretSelectionScreen.java @@ -2,6 +2,7 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.ScreenAdapter; +import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.audio.Sound; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.Texture; @@ -21,6 +22,7 @@ import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; import com.badlogic.gdx.utils.viewport.ScreenViewport; import com.csse3200.game.GdxGame; +import com.csse3200.game.services.ResourceService; import com.csse3200.game.services.ServiceLocator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,6 +54,10 @@ public class TurretSelectionScreen extends ScreenAdapter { private static final String TEXTURE = "planets/background.png"; private Set selectedTurrets = new HashSet<>(); private TextButton backButton; + private String[] bgm = { + "sounds/background/pre_game/Sci-Fi7Loop.ogg" + }; + private Music music; private static final Logger logger = LoggerFactory.getLogger(MainMenuScreen.class); public TurretSelectionScreen(GdxGame game) { @@ -59,6 +65,11 @@ public TurretSelectionScreen(GdxGame game) { stage = new Stage(new ScreenViewport()); table = new Table(); + ServiceLocator.registerResourceService(new ResourceService()); + ServiceLocator.getResourceService().loadMusic(bgm); + ServiceLocator.getResourceService().loadAll(); + music = ServiceLocator.getResourceService().getAsset(bgm[0], Music.class); + // Set up the background batch = new SpriteBatch(); Texture backgroundImage = new Texture(TEXTURE); @@ -218,6 +229,10 @@ public void clicked(InputEvent event, float x, float y) { table.setFillParent(true); Gdx.input.setInputProcessor(stage); + music.setVolume(0.4f); + music.setLooping(true); + music.play(); + } @Override public void render(float delta) { @@ -304,6 +319,7 @@ private void updateDescriptionText() { @Override public void dispose() { stage.dispose(); + music.dispose(); } }