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 a887ed896..a2c348b74 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 @@ -2,6 +2,7 @@ import com.badlogic.gdx.audio.Sound; import com.badlogic.gdx.graphics.Camera; +import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.badlogic.gdx.graphics.g2d.SpriteBatch; @@ -15,6 +16,7 @@ import com.badlogic.gdx.scenes.scene2d.utils.Drawable; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; import com.badlogic.gdx.utils.Align; +import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ServiceLocator; import com.csse3200.game.ui.UIComponent; import com.badlogic.gdx.scenes.scene2d.actions.Actions; @@ -89,6 +91,15 @@ public void updateScrapsStats() { scrapsTb.getLabel().setText(text); } + /** + * Displays a warning animation of the scraps display if the player tries to + * build something that costs more than the balance + */ + public void scrapBalanceFlash() { + // TODO: IMPLEMENT THIS + scrapsTb.setText("Insufficient!"); + } + /** * Updates the currency (Crystals) value on the UI component */ diff --git a/source/core/src/main/com/csse3200/game/input/BuildInputComponent.java b/source/core/src/main/com/csse3200/game/input/BuildInputComponent.java index 5c87099d3..11fed6a5e 100644 --- a/source/core/src/main/com/csse3200/game/input/BuildInputComponent.java +++ b/source/core/src/main/com/csse3200/game/input/BuildInputComponent.java @@ -13,7 +13,6 @@ import com.csse3200.game.entities.factories.TowerFactory; import com.csse3200.game.screens.TowerType; import com.csse3200.game.services.ServiceLocator; -import com.csse3200.game.utils.math.Vector2Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,6 +32,7 @@ public class BuildInputComponent extends InputComponent { private Sound buildSound; private Sound errorSound; private Array towers = new Array<>(); + private Array defaultTowers = new Array<>(); /** * Constructor for the BuildInputComponent @@ -43,6 +43,21 @@ public BuildInputComponent(Camera camera) { this.camera = camera; loadSounds(); towers.addAll(ServiceLocator.getTowerTypes()); + +// logger.info("selected towers in buildInputComponent are " + towers); + TowerType[] defaultTowerTypes = { + TowerType.TNT, + TowerType.DROID, + TowerType.INCOME, + TowerType.WALL, + TowerType.WEAPON + }; + defaultTowers.addAll(defaultTowerTypes); + + if (towers.isEmpty()) { + ServiceLocator.setTowerTypes(defaultTowers); + towers = defaultTowers; + } } /** @@ -74,12 +89,12 @@ public boolean touchDown(int screenX, int screenY, int pointer, int button) { // determine if the tile is unoccupied boolean tileOccupied = entityService.entitiesInTile((int)cursorPosition.x, (int)cursorPosition.y); - logger.debug("Tile is occupied: " + tileOccupied ); +// logger.debug("Tile is occupied: " + tileOccupied ); // check that no entities are occupying the tile if (!tileOccupied) { buildTower((int)cursorPosition.x, (int)cursorPosition.y); - logger.debug("spawning a tower at {}, {}", cursorPosition.x, cursorPosition.y); +// logger.debug("spawning a tower at {}, {}", cursorPosition.x, cursorPosition.y); return true; } else { // TODO: Create a tile indication of invalid placement here?? @@ -95,7 +110,7 @@ public boolean touchDown(int screenX, int screenY, int pointer, int button) { * @see InputProcessor#keyDown(int) */ @Override - public boolean keyDown(int keycode) { + public boolean keyUp(int keycode) { switch (keycode) { case Input.Keys.NUM_1: ServiceLocator.getCurrencyService().setTowerType(towers.get(0)); @@ -126,6 +141,7 @@ public boolean keyDown(int keycode) { */ public void buildTower(int x, int y) { // fetch the currently set TowerType in the currency service, and its associated build cost. + TowerType tower = ServiceLocator.getCurrencyService().getTower(); if (tower != null) { // fetch the price of the selected tower and attempt to instantiate @@ -159,6 +175,7 @@ public void buildTower(int x, int y) { // play a sound to indicate an invalid action long soundId = errorSound.play(); errorSound.setVolume(soundId, 1f); + ServiceLocator.getCurrencyService().getDisplay().scrapBalanceFlash(); // TODO: add a visual indication of the build fail, through // currency display flash } @@ -169,9 +186,14 @@ public void buildTower(int x, int y) { * Load the sound assets related to in-game tower building activity */ private void loadSounds() { - ServiceLocator.getResourceService().loadSounds(sounds); - ServiceLocator.getResourceService().loadAll(); - buildSound = ServiceLocator.getResourceService().getAsset("sounds/economy/buildSound.ogg", Sound.class); - errorSound = ServiceLocator.getResourceService().getAsset("sounds/ui/Switch/NA_SFUI_Vol1_switch_01.ogg", Sound.class); + try { + ServiceLocator.getResourceService().loadSounds(sounds); + ServiceLocator.getResourceService().loadAll(); + buildSound = ServiceLocator.getResourceService().getAsset("sounds/economy/buildSound.ogg", Sound.class); + errorSound = ServiceLocator.getResourceService().getAsset("sounds/ui/Switch/NA_SFUI_Vol1_switch_01.ogg", Sound.class); + + } catch (NullPointerException e) { + logger.error("BuildInputComponent line 173: Couldn't load sounds for build menu"); + } } } diff --git a/source/core/src/main/com/csse3200/game/services/ServiceLocator.java b/source/core/src/main/com/csse3200/game/services/ServiceLocator.java index 1df468c8f..7c16fc03f 100644 --- a/source/core/src/main/com/csse3200/game/services/ServiceLocator.java +++ b/source/core/src/main/com/csse3200/game/services/ServiceLocator.java @@ -121,20 +121,9 @@ public static void registerMapService(MapService source) { } public static void setTowerTypes(Array selectedTowers) { - if (towerTypes.isEmpty()) { - // set default towers - TowerType[] defaultTowers = { - TowerType.TNT, - TowerType.DROID, - TowerType.INCOME, - TowerType.WALL, - TowerType.WEAPON - }; - towerTypes.addAll(defaultTowers); - } else{ - towerTypes.clear(); - towerTypes.addAll(selectedTowers); - } + + towerTypes.clear(); + towerTypes.addAll(selectedTowers); } public static Array getTowerTypes() { @@ -151,6 +140,7 @@ public static void clear() { gameEndService = null; waveService = null; mapService = null; + towerTypes.clear(); } private ServiceLocator() { diff --git a/source/core/src/main/com/csse3200/game/ui/UIComponent.java b/source/core/src/main/com/csse3200/game/ui/UIComponent.java index 60cfe7009..025282e70 100644 --- a/source/core/src/main/com/csse3200/game/ui/UIComponent.java +++ b/source/core/src/main/com/csse3200/game/ui/UIComponent.java @@ -32,4 +32,8 @@ public int getLayer() { public float getZIndex() { return 1f; } + + public static Skin getSkin() { + return skin; + } } 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 fc48e2e3c..61f2d1935 100644 --- a/source/core/src/test/com/csse3200/game/input/BuildInputComponentTest.java +++ b/source/core/src/test/com/csse3200/game/input/BuildInputComponentTest.java @@ -3,17 +3,14 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Graphics; import com.badlogic.gdx.graphics.Camera; -import com.badlogic.gdx.graphics.g2d.TextureAtlas; -import com.badlogic.gdx.math.Vector2; import com.csse3200.game.areas.terrain.TerrainComponent; import com.csse3200.game.components.CameraComponent; -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.screens.TowerType; import com.csse3200.game.services.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -98,21 +95,47 @@ void shouldRejectOccupiedOrInvalidTile() { @Test void shouldHandleMissingMapService() { - + when(ServiceLocator.getMapService()).thenReturn(null); + assertFalse(buildInputComponent.touchDown(5,5,7,8)); } @Test void shouldHandleMissingCurrencyService() { + when(ServiceLocator.getCurrencyService()).thenReturn(null); + assertFalse(buildInputComponent.touchDown(5,5,7,8)); + } + @Test + void shouldHandleNullTowerName() { + TowerType towerType = mock(TowerType.class); + when(towerType.getTowerName()).thenReturn(null); + ServiceLocator.getCurrencyService().setTowerType(towerType); } @Test - void shouldHandleInvalidTower() { + void shouldHandleNullTowerDesc() { + TowerType towerType = mock(TowerType.class); + when(towerType.getDescription()).thenReturn(null); + ServiceLocator.getCurrencyService().setTowerType(towerType); + } + @Test + void shouldHandleNullTowerCost() { + TowerType towerType = mock(TowerType.class); + when(towerType.getPrice()).thenReturn(null); + ServiceLocator.getCurrencyService().setTowerType(towerType); } @Test - void shouldHandleMissingEntityService() { + void shouldHandleInvalidTowerName() { + TowerType towerType = mock(TowerType.class); + when(towerType.getTowerName()).thenReturn(null); + ServiceLocator.getCurrencyService().setTowerType(towerType); + } + @Test + void shouldHandleMissingEntityService() { + when(ServiceLocator.getEntityService()).thenReturn(null); + assertFalse(buildInputComponent.touchDown(5,5,7,8)); } }