diff --git a/.github/workflows/javadoc_publish.yaml b/.github/workflows/javadoc_publish.yaml index b7b44ac1b..37c6f0ab2 100644 --- a/.github/workflows/javadoc_publish.yaml +++ b/.github/workflows/javadoc_publish.yaml @@ -1,32 +1,32 @@ -name: Publish Javadoc to web +# name: Publish Javadoc to web -on: - push: - # Sequence of patterns matched against refs/heads - branches: - # Push events on main branch - - main +# on: +# push: +# # Sequence of patterns matched against refs/heads +# branches: +# # Push events on main branch +# - main -jobs: - build_and_publish_jdoc: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 # Checkout repo to remote machine - - name: Set up OpenJDK17 - uses: actions/setup-java@v1 - with: - java-version: '17' +# jobs: +# build_and_publish_jdoc: +# runs-on: ubuntu-latest +# steps: +# - uses: actions/checkout@v3 # Checkout repo to remote machine +# - name: Set up OpenJDK17 +# uses: actions/setup-java@v1 +# with: +# java-version: '17' - - name: Build Javadoc - run: | - cd $GRADLE_DIR - chmod +x ./gradlew - ./gradlew javadoc - env: - GRADLE_DIR: 'source' # Modify this to wherever './gradlew' is +# - name: Build Javadoc +# run: | +# cd $GRADLE_DIR +# chmod +x ./gradlew +# ./gradlew javadoc +# env: +# GRADLE_DIR: 'source' # Modify this to wherever './gradlew' is - - name: Deploy docs to GH Pages - uses: JamesIves/github-pages-deploy-action@v4.3.4 - with: - branch: gh-pages # The branch the action should deploy to. - folder: source/core/build/docs/javadoc/ # The folder the action should deploy. \ No newline at end of file +# - name: Deploy docs to GH Pages +# uses: JamesIves/github-pages-deploy-action@v4.3.4 +# with: +# branch: gh-pages # The branch the action should deploy to. +# folder: source/core/build/docs/javadoc/ # The folder the action should deploy. diff --git a/README.md b/README.md index d5253bfaf..f61503c71 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# UQ 2023 Studio 3 +# UQ 2023 Studio 3 ## Description diff --git a/source/core/src/main/com/csse3200/game/components/maingame/UIElementsDisplay.java b/source/core/src/main/com/csse3200/game/components/maingame/UIElementsDisplay.java index 280cc7197..b84b24fe3 100644 --- a/source/core/src/main/com/csse3200/game/components/maingame/UIElementsDisplay.java +++ b/source/core/src/main/com/csse3200/game/components/maingame/UIElementsDisplay.java @@ -80,13 +80,22 @@ private void addActors() { // Fetch the selected tower types if set Array towers = new Array<>(); + for (TowerType tower : ServiceLocator.getTowerTypes()) { towers.add(tower); } // If no towers set, populate with default towers - if (towers.isEmpty()) { - towers.addAll(defaultTowers); + if (towers.isEmpty() || towers.size < 5) { + if (towers.isEmpty()) { + towers.addAll(defaultTowers); + } else { + for (TowerType tower : defaultTowers) { + if (towers.size < 5 && !towers.contains(tower, false)) { + towers.add(tower); + } + } + } } TextButton tower1 = new TextButton(towers.get(0).getTowerName(), skin); 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/main/com/csse3200/game/components/tasks/waves/LevelWaves.java b/source/core/src/main/com/csse3200/game/components/tasks/waves/LevelWaves.java index 3d4a30111..41b15a844 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/waves/LevelWaves.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/waves/LevelWaves.java @@ -36,9 +36,8 @@ public LevelWaves(int spawnDelay) { long currentTime = ServiceLocator.getTimeSource().getTime(); // Setting the timestamp for when the next mobs will spawn. - // Currently, the delay of mobs spawning after wave start - // is hardcoded but will fix in the next push. - ServiceLocator.getWaveService().setNextWaveTime(currentTime + 10000); + // Currently, the delay of mobs spawning after wave start. + ServiceLocator.getWaveService().setNextWaveTime(currentTime + (spawnDelay * 1000)); } /** diff --git a/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveClass.java b/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveClass.java index 68946aeb2..41f031858 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveClass.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveClass.java @@ -29,7 +29,8 @@ public WaveClass(HashMap entities) { * Get the entities that are part of this wave and randomise the order they are spawned * @return mobs for the wave in form of (mob name, mob health) */ - private List entitiesToWave() { + + public List entitiesToWave() { List enemies = new ArrayList<>(); for (Map.Entry set : entities.entrySet()) { for (int i = 0; i < set.getValue()[0]; i++) { diff --git a/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveTask.java b/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveTask.java index 360509c73..4be3210de 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/waves/WaveTask.java @@ -18,6 +18,7 @@ public class WaveTask extends DefaultTask implements PriorityTask { private LevelWaves level; private WaveClass currentWave; private final GameTime globalTime; + private long nextWaveAt = 0; private int currentWaveIndex = 0; private boolean waveInProgress; private float startTime = 0; @@ -93,13 +94,13 @@ public void start() { @Override public void update() { if (ServiceLocator.getWaveService().getEnemyCount() == 0) { - currentWaveIndex++; +// currentWaveIndex++; long currentTime = ServiceLocator.getTimeSource().getTime(); // Setting the timestamp for when the next mobs will spawn. // Currently, the delay of mobs spawning after wave start - // is hardcoded but will fix in the next push. - ServiceLocator.getWaveService().setNextWaveTime(currentTime + 10000); + int spawnDelay = ServiceLocator.getWaveService().getSpawnDelay(); + ServiceLocator.getWaveService().setNextWaveTime(currentTime + (spawnDelay * 1000)); // Check if level has been completed - no more waves remaining if (currentWaveIndex == this.level.getNumWaves()) { @@ -108,22 +109,35 @@ public void update() { } else { // Spawn the next wave - logger.info("No enemies remaining, begin next wave"); - this.waveEnd.play(); - this.waveInProgress = true; - this.level.setWaveIndex(currentWaveIndex); - // Set the service wave count to the current wave index. - ServiceLocator.getWaveService().setWaveCount(currentWaveIndex); - this.currentWave = this.level.getWave(currentWaveIndex); - ServiceLocator.getWaveService().setEnemyCount(currentWave.getSize()); - //endTime = globalTime.getTime() + (SPAWNING_INTERVAL * 1000L); // reset end time +// logger.info("No enemies remaining, begin next wave"); + if (nextWaveAt == 0) { + logger.info("Next wave in 10 seconds"); + nextWaveAt = globalTime.getTime() + 10000; + ServiceLocator.getWaveService().setNextWaveTime(nextWaveAt); + } else { + if (globalTime.getTime() >= nextWaveAt || ServiceLocator.getWaveService().shouldSkip()) { + logger.info("Next wave starting"); + ServiceLocator.getWaveService().toggleDelay(); + currentWaveIndex++; + ServiceLocator.getWaveService().setNextWaveTime(0); + nextWaveAt = 0; + this.waveEnd.play(); + this.waveInProgress = true; + this.level.setWaveIndex(currentWaveIndex); + // Set the service wave count to the current wave index. + ServiceLocator.getWaveService().setWaveCount(currentWaveIndex); + this.currentWave = this.level.getWave(currentWaveIndex); + ServiceLocator.getWaveService().setEnemyCount(currentWave.getSize()); + //endTime = globalTime.getTime() + (SPAWNING_INTERVAL * 1000L); // reset end time + } + } } } else { -// logger.info("{} enemies remaining in wave {}", ServiceLocator.getWaveService().getEnemyCount(), currentWaveIndex); -// logger.info("WAVE SERVICE NUMBER: Wave Number {}",ServiceLocator.getWaveService().getWaveCount()); -// logger.info("NEXT WAVE AT {}", ServiceLocator.getWaveService().getNextWaveTime()); -// logger.info("TIME IS {}", ServiceLocator.getTimeSource().getTime()); + //logger.info("{} enemies remaining in wave {}", ServiceLocator.getWaveService().getEnemyCount(), currentWaveIndex); + //logger.info("WAVE SERVICE NUMBER: Wave Number {}",ServiceLocator.getWaveService().getWaveCount()); + //logger.info("NEXT WAVE AT {}", ServiceLocator.getWaveService().getNextWaveTime()); + //logger.info("TIME IS {}", ServiceLocator.getTimeSource().getTime()); if (waveInProgress) { this.level.spawnWave(); } @@ -137,4 +151,12 @@ public void update() { public boolean isWaveInProgress() { return waveInProgress; } + + /** + * Gets the current wave index + * @return current wave index + */ + public int getCurrentWaveIndex() { + return currentWaveIndex; + } } 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 e73d595a1..d7dc5631e 100644 --- a/source/core/src/main/com/csse3200/game/entities/EntityService.java +++ b/source/core/src/main/com/csse3200/game/entities/EntityService.java @@ -78,6 +78,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 */ @@ -174,6 +188,24 @@ public Entity getEntityAtPosition(float x, float y) { return null; } + /** + * Checks for the presence of an Entity at a specified position (x, y). + * + * @param x The x-coordinate of the position to check. + * @param y The y-coordinate of the position to check. + * @return The Entity found at the specified position, or null if no Entity is present. + */ + public Entity checkEntityAtPosition(int x, int y) { + entities.sort(Comparator.comparingInt(Entity::getLayer)); + for (Entity entity : entities) { + if (entity.getPosition().x == x && entity.getPosition().y == y) { + return entity; + } + } + return null; + } + + private boolean entityContainsPosition(Entity entity, float x, float y) { float entityX = entity.getPosition().x; float entityY = entity.getPosition().y; @@ -198,7 +230,7 @@ public boolean entitiesInTile(int x_coord, int y_coord) { return true; } if (mp.getCell(x_coord, y_coord) != null) { - Entity entity = getEntityAtPosition(x_coord, y_coord); + Entity entity = checkEntityAtPosition(x_coord, y_coord); return entity != null; } return true; diff --git a/source/core/src/main/com/csse3200/game/entities/factories/WaveFactory.java b/source/core/src/main/com/csse3200/game/entities/factories/WaveFactory.java index 1875ee6e0..9a1269d1a 100644 --- a/source/core/src/main/com/csse3200/game/entities/factories/WaveFactory.java +++ b/source/core/src/main/com/csse3200/game/entities/factories/WaveFactory.java @@ -6,6 +6,7 @@ import com.csse3200.game.components.tasks.waves.WaveTask; import com.csse3200.game.entities.Entity; import com.csse3200.game.screens.GameLevelData; +import com.csse3200.game.services.ServiceLocator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -97,10 +98,16 @@ public static LevelWaves createLevel(int maxDiff, int maxWaves, int chosenLevel) String boss1 = "IceBoss"; // String boss1 = "PatrickBoss"; String boss2 = "PatrickBoss"; - // String boss3 = "IceBoss"; - //TODO change this to a fire boss in sprint 4 - String boss3 = "FireBoss"; - LevelWaves level = new LevelWaves(5); + //String boss3 = "IceBoss"; + + String boss3 = "FireBoss"; + + int spawnDelay = 5; + + // Create new level entity with spawn delay of 5 seconds + LevelWaves level = new LevelWaves(spawnDelay); + // Tell the waveService what the spawn delay for levels will be (for UI team). + ServiceLocator.getWaveService().setSpawnDelay(spawnDelay); ArrayList possibleMobs; 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 f9d4ca67e..b06134cb6 100644 --- a/source/core/src/main/com/csse3200/game/input/UpgradeUIComponent.java +++ b/source/core/src/main/com/csse3200/game/input/UpgradeUIComponent.java @@ -30,6 +30,7 @@ import org.slf4j.LoggerFactory; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; public class UpgradeUIComponent extends InputComponent { @@ -62,15 +63,23 @@ 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) { - // 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); @@ -84,9 +93,13 @@ public boolean touchDown(int screenX, int screenY, int pointer, int button) { } // + // 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); - if (clickedEntity != null && clickedEntity.getComponent(TowerUpgraderComponent.class) != null && clickedEntity.getComponent(TNTDamageComponent.class) == null) { -// logger.info("clicked a turret that is upgradable!"); clearUpgradeTables(); // Check if there is an existing upgrade table for this turret entity Table existingUpgradeTable = upgradeTables.get(clickedEntity); @@ -103,6 +116,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; @@ -118,28 +132,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 @@ -179,9 +208,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 @@ -210,6 +242,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() { @@ -238,7 +271,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() { @@ -271,6 +304,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() { @@ -304,8 +338,11 @@ 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) { + + // 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()); @@ -314,8 +351,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(); @@ -371,10 +408,39 @@ 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(); 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/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/MainGameScreen.java b/source/core/src/main/com/csse3200/game/screens/MainGameScreen.java index 05d47629a..55623b881 100644 --- a/source/core/src/main/com/csse3200/game/screens/MainGameScreen.java +++ b/source/core/src/main/com/csse3200/game/screens/MainGameScreen.java @@ -87,6 +87,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(); @@ -134,17 +135,14 @@ public MainGameScreen(GdxGame game) { renderer = RenderFactory.createRenderer(); 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()); - InputComponent UpgradedInputHandler = new UpgradeUIComponent(renderer.getCamera().getCamera(), renderer.getStage()); + 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.getInputService().register(upgradedInputHandler); ServiceLocator.getCurrencyService().getDisplay().setCamera(renderer.getCamera().getCamera()); loadAssets(); @@ -214,6 +212,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"); @@ -317,4 +318,8 @@ private void playAmbientSound() { ServiceLocator.getResourceService().getAsset(ambientSounds.random(), Sound.class).play(0.2f); } + + private UpgradeUIComponent getUpgradedInputHandler() { + return (UpgradeUIComponent) upgradedInputHandler; + } } \ No newline at end of file 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/main/com/csse3200/game/screens/TurretSelectionScreen.java b/source/core/src/main/com/csse3200/game/screens/TurretSelectionScreen.java index 357ab0fd6..e27598388 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,13 +54,26 @@ 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); + /** + * Constructor for the TurretSelectionScreen + * @param game The game object + */ public TurretSelectionScreen(GdxGame game) { this.game = 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 +233,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) { @@ -232,10 +251,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))); @@ -293,17 +325,27 @@ 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(); + music.dispose(); } } diff --git a/source/core/src/main/com/csse3200/game/services/WaveService.java b/source/core/src/main/com/csse3200/game/services/WaveService.java index 0e50a7fc1..c7ddacdef 100644 --- a/source/core/src/main/com/csse3200/game/services/WaveService.java +++ b/source/core/src/main/com/csse3200/game/services/WaveService.java @@ -17,6 +17,10 @@ public class WaveService { private long nextWaveTime; private final UIElementsDisplay display; + private int spawnDelay; + + private boolean skipDelay = false; + /** * Constructor for the Wave Service @@ -121,6 +125,19 @@ public void setNextWaveTime(long nextWaveTime) { this.nextWaveTime = nextWaveTime; } + /** + * Sets the spawn delay between levels + * @param spawnDelay representing the spawnDelay between levels. + */ + public void setSpawnDelay(int spawnDelay) {this.spawnDelay = spawnDelay;} + + /** + * Returns the spawn delay between levels + * @return (int) The spawn delay between levels. + */ + public int getSpawnDelay() {return this.spawnDelay;} + + /** * Used for adding this instance of UIElementsDisplay to the mainGameScreen. This is needed as update is performed * for this instance of the display. @@ -129,4 +146,18 @@ public void setNextWaveTime(long nextWaveTime) { public UIElementsDisplay getDisplay() { return this.display; } + + /** + * This will invert the value of the skipDelay boolean + * */ + public void toggleDelay() { + this.skipDelay = !this.skipDelay; + } + + /** + * retrieve the skipDelay condition + * */ + public boolean shouldSkip() { + return this.skipDelay; + } } diff --git a/source/core/src/test/com/csse3200/game/components/tasks/waves/LevelWavesTest.java b/source/core/src/test/com/csse3200/game/components/tasks/waves/LevelWavesTest.java index 39ddd78ec..abf459c8f 100644 --- a/source/core/src/test/com/csse3200/game/components/tasks/waves/LevelWavesTest.java +++ b/source/core/src/test/com/csse3200/game/components/tasks/waves/LevelWavesTest.java @@ -1,7 +1,10 @@ package com.csse3200.game.components.tasks.waves; +import com.csse3200.game.components.tasks.waves.LevelWaves; +import com.csse3200.game.components.tasks.waves.WaveClass; import com.csse3200.game.entities.factories.WaveFactory; import com.csse3200.game.extensions.GameExtension; +import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ServiceLocator; import org.junit.Test; import org.junit.jupiter.api.BeforeEach; @@ -10,8 +13,13 @@ import org.mockito.junit.jupiter.MockitoExtension; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; + +import static org.mockito.Mockito.when; + @Disabled + @ExtendWith(GameExtension.class) @ExtendWith(MockitoExtension.class) class LevelWavesTest { @@ -19,21 +27,36 @@ class LevelWavesTest { LevelWaves levelWaves; WaveClass wave; ServiceLocator serviceLocator; + GameTime gameTime; @BeforeEach void setUp() { - levelWaves = (LevelWaves) WaveFactory.createWaves(); + levelWaves = mock(LevelWaves.class); wave = mock(WaveClass.class); + gameTime = mock(GameTime.class); } @Test public void testAddWave() { + when(levelWaves.getNumWaves()).thenReturn(1); + int size = levelWaves.getNumWaves(); levelWaves.addWave(wave); - assertEquals(3, levelWaves.waves.size()); + assertEquals(size + 1, levelWaves.getNumWaves()); } @Test - public void testSpawnWaveStart() { + public void testSpawnWave() { + levelWaves.setWaveIndex(1); + levelWaves.spawnWave(); + WaveClass thisWave = levelWaves.getWave(levelWaves.getWaveIndex()); + assertTrue(thisWave.getSize() > 0); + assertTrue(!thisWave.getMobs().isEmpty()); + } + @Test + public void testGetStartTime() { + when(levelWaves.getStartTime()).thenReturn(1000L); + assertEquals(1000L, levelWaves.getStartTime()); } + } diff --git a/source/core/src/test/com/csse3200/game/components/tasks/waves/WaveClassTest.java b/source/core/src/test/com/csse3200/game/components/tasks/waves/WaveClassTest.java index aa054e325..abc70a3a2 100644 --- a/source/core/src/test/com/csse3200/game/components/tasks/waves/WaveClassTest.java +++ b/source/core/src/test/com/csse3200/game/components/tasks/waves/WaveClassTest.java @@ -1,7 +1,51 @@ package com.csse3200.game.components.tasks.waves; + +import com.csse3200.game.components.tasks.waves.WaveClass; +import com.csse3200.game.extensions.GameExtension; +import org.junit.Assert; +import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.HashMap; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Disabled; +@ExtendWith(GameExtension.class) +@ExtendWith(MockitoExtension.class) + @Disabled class WaveClassTest { + + HashMap waveContents; + WaveClass waveClass; + @BeforeEach + void setUp() { + waveContents = new HashMap<>(); + waveContents.put("Xeno", new int[]{2, 20}); + waveContents.put("DodgingDragon", new int[]{3, 40}); + waveContents.put("SplittingXeno", new int[]{5, 60}); + waveContents.put("DeflectXeno", new int[]{7, 80}); + waveClass = new WaveClass(waveContents); + } + + @Test + public void testGetMobs() { + List enemies = waveClass.getMobs(); + assertTrue(enemies.contains("Xeno") + && enemies.contains("DodgingDragon") + && enemies.contains("SplittingXeno") + && enemies.contains("DeflectXeno")); + } + + @Test + public void testGetSize() { + int size = waveClass.getSize(); + assertEquals(17, size); + } } diff --git a/source/core/src/test/com/csse3200/game/components/tasks/waves/WaveTaskTest.java b/source/core/src/test/com/csse3200/game/components/tasks/waves/WaveTaskTest.java index 7b95dedae..a47359ffc 100644 --- a/source/core/src/test/com/csse3200/game/components/tasks/waves/WaveTaskTest.java +++ b/source/core/src/test/com/csse3200/game/components/tasks/waves/WaveTaskTest.java @@ -1,9 +1,13 @@ package com.csse3200.game.components.tasks.waves; import com.badlogic.gdx.audio.Sound; +import com.csse3200.game.ai.tasks.PriorityTask; +import com.csse3200.game.ai.tasks.Task; import com.csse3200.game.areas.ForestGameArea; import com.csse3200.game.areas.terrain.TerrainFactory; import com.csse3200.game.components.tasks.DroidCombatTask; +import com.csse3200.game.components.tasks.waves.LevelWaves; +import com.csse3200.game.components.tasks.waves.WaveTask; import com.csse3200.game.extensions.GameExtension; import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ResourceService; @@ -52,10 +56,34 @@ public void testGetPriority() { } @Test - public void testStartWave() { + public void testStartFirstWave() { waveTask.start(); - assertEquals(1, waveTask.getPriority()); + assertEquals(10, waveTask.getPriority()); assertTrue(waveTask.isWaveInProgress()); + assertEquals(1, waveTask.getCurrentWaveIndex()); + } + + @Test + public void testIsWaveInProgress() { + waveTask.start(); + assertTrue(waveTask.isWaveInProgress()); + } + + @Test + public void testUpdateOnEmptyWaveAndNoNextWave() { + waveTask.start(); + ServiceLocator.getWaveService().setEnemyCount(0); + waveTask.update(); + assertTrue(ServiceLocator.getWaveService().isLevelCompleted()); + } + + @Test + public void testUpdateOnEmptyWaveAndNextWave() { + waveTask.start(); + int waveNumber = waveTask.getCurrentWaveIndex(); + ServiceLocator.getWaveService().setEnemyCount(0); + waveTask.update(); + assertTrue(waveNumber + 1 == waveTask.getCurrentWaveIndex()); } } 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()); + } } diff --git a/source/core/src/test/com/csse3200/game/entities/factories/WaveFactoryTest.java b/source/core/src/test/com/csse3200/game/entities/factories/WaveFactoryTest.java index 3e4cfd845..b21daceed 100644 --- a/source/core/src/test/com/csse3200/game/entities/factories/WaveFactoryTest.java +++ b/source/core/src/test/com/csse3200/game/entities/factories/WaveFactoryTest.java @@ -1,5 +1,6 @@ package com.csse3200.game.entities.factories; +import com.csse3200.game.components.tasks.waves.LevelWaves; import com.badlogic.gdx.assets.AssetManager; import com.csse3200.game.components.tasks.waves.LevelWaves; import com.csse3200.game.components.tasks.waves.WaveClass; 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() { +// +// } +//} diff --git a/source/core/src/test/com/csse3200/game/services/WaveServiceTest.java b/source/core/src/test/com/csse3200/game/services/WaveServiceTest.java new file mode 100644 index 000000000..6f33702c1 --- /dev/null +++ b/source/core/src/test/com/csse3200/game/services/WaveServiceTest.java @@ -0,0 +1,56 @@ +package com.csse3200.game.services; + +import com.badlogic.gdx.audio.Sound; +import com.csse3200.game.areas.ForestGameArea; +import com.csse3200.game.components.tasks.waves.LevelWaves; +import com.csse3200.game.components.tasks.waves.WaveTask; +import com.csse3200.game.extensions.GameExtension; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.extension.ExtendWith; + +import com.csse3200.game.entities.EntityService; +import com.csse3200.game.extensions.GameExtension; +import com.csse3200.game.physics.PhysicsService; +import com.csse3200.game.rendering.RenderService; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.Mockito.mock; + +@Disabled +@ExtendWith(GameExtension.class) +public class WaveServiceTest { + + WaveTask waveTask; + ResourceService resourceService; + LevelWaves level; + + WaveService waveService; + @BeforeEach + void setUp() { + resourceService = ServiceLocator.getResourceService(); + waveService = ServiceLocator.getWaveService(); + GameTime globalTime = mock(GameTime.class); + level = mock(LevelWaves.class); + ServiceLocator.registerTimeSource(globalTime); + waveTask = new WaveTask(); + String[] sounds = waveTask.getSounds(); + resourceService.getAsset(sounds[0], Sound.class); + resourceService.getAsset(sounds[1], Sound.class); + } + + @Test + void shouldSetNextWaveTime() { + + waveTask.start(); + ServiceLocator.getWaveService().setEnemyCount(0); + waveTask.update(); + + assertTrue(ServiceLocator.getWaveService().getNextWaveTime() > 0); + + } + +}