diff --git a/source/core/assets/images/GrassTile/grass_tile_1.png b/source/core/assets/images/GrassTile/grass_tile_1.png new file mode 100644 index 000000000..770193053 Binary files /dev/null and b/source/core/assets/images/GrassTile/grass_tile_1.png differ diff --git a/source/core/assets/images/GrassTile/grass_tile_2.png b/source/core/assets/images/GrassTile/grass_tile_2.png new file mode 100644 index 000000000..261cd8ad8 Binary files /dev/null and b/source/core/assets/images/GrassTile/grass_tile_2.png differ diff --git a/source/core/assets/images/GrassTile/grass_tile_3.png b/source/core/assets/images/GrassTile/grass_tile_3.png new file mode 100644 index 000000000..3c18bce32 Binary files /dev/null and b/source/core/assets/images/GrassTile/grass_tile_3.png differ diff --git a/source/core/assets/images/GrassTile/grass_tile_4.png b/source/core/assets/images/GrassTile/grass_tile_4.png new file mode 100644 index 000000000..846fbc184 Binary files /dev/null and b/source/core/assets/images/GrassTile/grass_tile_4.png differ diff --git a/source/core/assets/images/GrassTile/grass_tile_5.png b/source/core/assets/images/GrassTile/grass_tile_5.png new file mode 100644 index 000000000..7efc7788c Binary files /dev/null and b/source/core/assets/images/GrassTile/grass_tile_5.png differ diff --git a/source/core/assets/images/GrassTile/grass_tile_6.png b/source/core/assets/images/GrassTile/grass_tile_6.png new file mode 100644 index 000000000..ac27e6981 Binary files /dev/null and b/source/core/assets/images/GrassTile/grass_tile_6.png differ diff --git a/source/core/assets/images/GrassTile/grass_tile_7.png b/source/core/assets/images/GrassTile/grass_tile_7.png new file mode 100644 index 000000000..8f7fb2f76 Binary files /dev/null and b/source/core/assets/images/GrassTile/grass_tile_7.png differ diff --git a/source/core/assets/images/grass_2.png b/source/core/assets/images/grass_2.png index 81dbc6ef7..bc1ab9447 100644 Binary files a/source/core/assets/images/grass_2.png and b/source/core/assets/images/grass_2.png differ diff --git a/source/core/assets/images/highlight_tile.png b/source/core/assets/images/highlight_tile.png new file mode 100644 index 000000000..4c6883788 Binary files /dev/null and b/source/core/assets/images/highlight_tile.png differ diff --git a/source/core/src/main/com/csse3200/game/areas/ForestGameArea.java b/source/core/src/main/com/csse3200/game/areas/ForestGameArea.java index 6ef7f52bd..358f615bd 100644 --- a/source/core/src/main/com/csse3200/game/areas/ForestGameArea.java +++ b/source/core/src/main/com/csse3200/game/areas/ForestGameArea.java @@ -3,6 +3,9 @@ import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.math.GridPoint2; import com.badlogic.gdx.math.Vector2; + +import com.csse3200.game.areas.terrain.TerrainComponent; +import com.csse3200.game.components.ProjectileEffects; import com.csse3200.game.areas.terrain.TerrainFactory; import com.csse3200.game.areas.terrain.TerrainFactory.TerrainType; import com.csse3200.game.components.ProjectileEffects; @@ -15,6 +18,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.security.SecureRandom; +import java.util.Random; import java.util.Timer; import java.util.TimerTask; @@ -86,7 +90,6 @@ public class ForestGameArea extends GameArea { "images/towers/wallTower.png", "images/background/building2.png", "images/iso_grass_3.png", - "images/terrain_use.png", "images/Dusty_MoonBG.png", "images/economy/scrap.png", "images/economy/crystal.png", @@ -109,7 +112,16 @@ public class ForestGameArea extends GameArea { "images/mobboss/demon2.png", "images/mobs/fire_worm.png", "images/mobboss/patrick.png", + "images/GrassTile/grass_tile_1.png", + "images/GrassTile/grass_tile_2.png", + "images/GrassTile/grass_tile_3.png", + "images/GrassTile/grass_tile_4.png", + "images/GrassTile/grass_tile_5.png", + "images/GrassTile/grass_tile_6.png", + "images/GrassTile/grass_tile_7.png", + "images/highlight_tile.png", "images/mobboss/iceBaby.png" + }; private static final String[] forestTextureAtlases = { "images/economy/econ-tower.atlas", @@ -196,7 +208,7 @@ public class ForestGameArea extends GameArea { private static final String backgroundMusic = "sounds/background/Sci-Fi1.ogg"; private static final String[] forestMusic = {backgroundMusic}; - private final TerrainFactory terrainFactory; +// private final TerrainFactory terrainFactory; private Entity player; private Entity waves; @@ -210,12 +222,10 @@ public class ForestGameArea extends GameArea { /** * Initialise this ForestGameArea to use the provided TerrainFactory. * - * @param terrainFactory TerrainFactory used to create the terrain for the GameArea. * @requires terrainFactory != null */ - public ForestGameArea(TerrainFactory terrainFactory) { + public ForestGameArea() { super(); - this.terrainFactory = terrainFactory; } /** @@ -293,21 +303,16 @@ public void create() { logger.info("Lol"); // Set up infrastructure for end game tracking - player = spawnPlayer(); +// player = spawnPlayer(); waves = WaveFactory.createWaves(); spawnEntity(waves); waves.getEvents().addListener("spawnWave", this::spawnMob); playMusic(); - //spawnXenoGrunts(); - //startWaveTimer(); - spawnScrap(); - //spawnDeflectXenoGrunt(15, 5); - //spawnSplittingXenoGrunt(15, 4); spawnScrap(); spawnTNTTower(); - // spawnWeaponTower(); + //spawnWeaponTower(); spawnGapScanners(); spawnDroidTower(); @@ -323,8 +328,8 @@ private void displayUI() { private void spawnTerrain() { - terrain = terrainFactory.createTerrain(TerrainType.ALL_DEMO); - spawnEntity(new Entity().addComponent(terrain)); + terrain = ServiceLocator.getMapService().getComponent(); + spawnEntity(ServiceLocator.getMapService().getEntity()); // Terrain walls float tileSize = terrain.getTileSize(); @@ -357,47 +362,6 @@ private void spawnTerrain() { false); } - -// private void spawnBuilding1() { -// GridPoint2 minPos = new GridPoint2(0, 0); -// GridPoint2 maxPos = terrain.getMapBounds(0).sub(2, 2); -// -// for (int i = 0; i < NUM_BUILDINGS; i++) { -// GridPoint2 randomPos = RandomUtils.random(minPos, maxPos); -// Entity building1 = ObstacleFactory.createBuilding1(); -// spawnEntityAt(building1, randomPos, true, false); -// } -// } -// private void spawnBuilding2() { -// GridPoint2 minPos = new GridPoint2(0, 0); -// GridPoint2 maxPos = terrain.getMapBounds(0).sub(2, 2); -// -// for (int i = 0; i < NUM_BUILDINGS; i++) { -// GridPoint2 randomPos = RandomUtils.random(minPos, maxPos); -// Entity building2 = ObstacleFactory.createBuilding2(); -// spawnEntityAt(building2, randomPos, true, false); -// } -// } - - -// private void spawnMountains() { -// ArrayList fixedPositions = new ArrayList<>(); //Generating ArrayList -// -// fixedPositions.add(new GridPoint2(5, 8)); -// fixedPositions.add(new GridPoint2(12, 4)); -// fixedPositions.add(new GridPoint2(20, 10)); -// fixedPositions.add(new GridPoint2(33, 17)); -// -// for (GridPoint2 fixedPos : fixedPositions) { -// Entity tree = ObstacleFactory.createMountain(); -// spawnEntityAt(tree, fixedPos, true, false); -// } -// for (int i = 0; i < NUM_BUILDINGS; i++) { -// GridPoint2 randomPos = RandomUtils.random(minPos, maxPos); -// Entity building1 = ObstacleFactory.createBuilding1(); -// spawnEntityAt(building1, randomPos, true, false); -// } -// } private void spawnBuilding2() { GridPoint2 minPos = new GridPoint2(0, 0); @@ -423,28 +387,6 @@ private Entity spawnPlayer(GridPoint2 position) { return newPlayer; } -// private void spawnGhosts() { -// GridPoint2 minPos = new GridPoint2(0, 0); -// GridPoint2 maxPos = terrain.getMapBounds(0).sub(0, 2); -// -// for (int i = 0; i < NUM_GHOSTS; i++) { -// int fixedX = terrain.getMapBounds(0).x - 1; // Rightmost x-coordinate -// int randomY = MathUtils.random(0, maxPos.y); -// GridPoint2 randomPos = new GridPoint2(fixedX, randomY); -// Entity ghost = createGhost(player); -// spawnEntityAt(ghost, randomPos, true, true); -// } -// } - -// private Entity spawnMobBoss1() { -// GridPoint2 minPos = new GridPoint2(0, 0); -// GridPoint2 maxPos = terrain.getMapBounds(0).sub(2, 2); -// GridPoint2 randomPos -// = new GridPoint2(0, 0); -// Entity ghostKing = NPCFactory.createGhostKing(player); -// spawnEntityAt(ghostKing, randomPos, true, true); -// return ghostKing; -// } private void spawnDemonBoss() { Entity demon = MobBossFactory.createDemonBoss(); @@ -584,7 +526,9 @@ private void spawnDeflectWizard(int x, int y) { } private void spawnFireWorm() { - int[] pickedLanes = rand.ints(1, 7) + + int[] pickedLanes = rand.ints(0, ServiceLocator.getMapService().getHeight() ) + .distinct().limit(5).toArray(); for (int i = 0; i < NUM_GRUNTS; i++) { GridPoint2 randomPos = new GridPoint2(19, pickedLanes[i]); @@ -595,7 +539,8 @@ private void spawnFireWorm() { } private void spawnSkeleton() { - int[] pickedLanes = rand.ints(1, 7) + + int[] pickedLanes = new Random().ints(0, ServiceLocator.getMapService().getHeight() ) .distinct().limit(5).toArray(); for (int i = 0; i < NUM_GRUNTS; i++) { GridPoint2 randomPos = new GridPoint2(19, pickedLanes[i]); @@ -606,7 +551,9 @@ private void spawnSkeleton() { } private void spawnDragonKnight() { - int[] pickedLanes = rand.ints(1, 7) + + int[] pickedLanes = rand.ints(0, ServiceLocator.getMapService().getHeight() ) + .distinct().limit(5).toArray(); for (int i = 0; i < NUM_GRUNTS; i++) { GridPoint2 randomPos = new GridPoint2(19, pickedLanes[i]); @@ -617,7 +564,9 @@ private void spawnDragonKnight() { } private void spawnWizard() { - int[] pickedLanes = rand.ints(1, 7) + + int[] pickedLanes = rand.ints(0, ServiceLocator.getMapService().getHeight() ) + .distinct().limit(5).toArray(); for (int i = 0; i < NUM_GRUNTS; i++) { GridPoint2 randomPos = new GridPoint2(19, pickedLanes[i]); @@ -628,7 +577,9 @@ private void spawnWizard() { } private void spawnWaterQueen() { - int[] pickedLanes = rand.ints(1, 7) + + int[] pickedLanes = new Random().ints(0, ServiceLocator.getMapService().getHeight() ) + .distinct().limit(5).toArray(); for (int i = 0; i < NUM_GRUNTS; i++) { GridPoint2 randomPos = new GridPoint2(19, pickedLanes[i]); @@ -639,7 +590,9 @@ private void spawnWaterQueen() { } private void spawnWaterSlime() { - int[] pickedLanes = rand.ints(1, 7) + + int[] pickedLanes = new Random().ints(0, ServiceLocator.getMapService().getHeight() ) + .distinct().limit(5).toArray(); for (int i = 0; i < NUM_GRUNTS; i++) { GridPoint2 randomPos = new GridPoint2(19, pickedLanes[i]); @@ -649,6 +602,7 @@ private void spawnWaterSlime() { } } + // private Entity spawnGhostKing() { // GridPoint2 minPos = new GridPoint2(0, 0); // GridPoint2 maxPos = terrain.getMapBounds(0).sub(0, 0); @@ -745,12 +699,13 @@ private void spawnSplitFireWorksFireBall(Vector2 position, short targetLayer, in projectile.setPosition(position); spawnEntity(projectile); } + private void spawnWeaponTower() { - GridPoint2 minPos = new GridPoint2(0, 2); - GridPoint2 maxPos = terrain.getMapBounds(0).sub(2, 2); + GridPoint2 minPos = new GridPoint2(0, 0); + GridPoint2 maxPos = terrain.getMapBounds(0).sub(5, 1); - for (int i = 0; i < NUM_WEAPON_TOWERS + 3; i++) { + for (int i = 0; i < NUM_WEAPON_TOWERS + 7 ; i++) { GridPoint2 randomPos1 = RandomUtils.random(minPos, maxPos); GridPoint2 randomPos2 = RandomUtils.random(minPos, maxPos); Entity wallTower = TowerFactory.createWallTower(); @@ -776,10 +731,10 @@ private void spawnDroidTowerAt(int x, int y) { } private void spawnTNTTower() { - GridPoint2 minPos = new GridPoint2(0, 2); - GridPoint2 maxPos = terrain.getMapBounds(0).sub(2, 2); + GridPoint2 minPos = new GridPoint2(0, 0); + GridPoint2 maxPos = terrain.getMapBounds(0).sub(5, 1); - for (int i = 0; i < NUM_WEAPON_TOWERS; i++) { + for (int i = 0; i < NUM_WEAPON_TOWERS + 5; i++) { GridPoint2 randomPos = RandomUtils.random(minPos, maxPos); Entity weaponTower = TowerFactory.createTNTTower(); spawnEntityAt(weaponTower, randomPos, true, true); @@ -788,13 +743,13 @@ private void spawnTNTTower() { } private void spawnDroidTower() { - GridPoint2 minPos = new GridPoint2(0, 2); - GridPoint2 maxPos = terrain.getMapBounds(0).sub(2, 2); + GridPoint2 minPos = new GridPoint2(0, 0); + GridPoint2 maxPos = terrain.getMapBounds(0).sub(5, 1); - for (int i = 0; i < NUM_WEAPON_TOWERS; i++) { + for (int i = 0; i < NUM_WEAPON_TOWERS + 5; i++) { GridPoint2 randomPos = RandomUtils.random(minPos, maxPos); Entity weaponTower = TowerFactory.createDroidTower(); - spawnEntityAt(weaponTower, randomPos, true, true); + spawnEntityAt(weaponTower, randomPos, true, false); } } diff --git a/source/core/src/main/com/csse3200/game/areas/terrain/TerrainComponent.java b/source/core/src/main/com/csse3200/game/areas/terrain/TerrainComponent.java index 4e9f2f8ed..3b56b4ab5 100644 --- a/source/core/src/main/com/csse3200/game/areas/terrain/TerrainComponent.java +++ b/source/core/src/main/com/csse3200/game/areas/terrain/TerrainComponent.java @@ -1,19 +1,29 @@ package com.csse3200.game.areas.terrain; -import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.*; import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.maps.tiled.TiledMap; import com.badlogic.gdx.maps.tiled.TiledMapRenderer; +import com.badlogic.gdx.maps.tiled.TiledMapTile; import com.badlogic.gdx.maps.tiled.TiledMapTileLayer; import com.badlogic.gdx.math.GridPoint2; import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.utils.Timer; import com.csse3200.game.rendering.RenderComponent; +import com.csse3200.game.services.ResourceService; +import com.csse3200.game.services.ServiceLocator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Render a tiled terrain for a given tiled map and orientation. A terrain is a map of tiles that * shows the 'ground' in the game. Enabling/disabling this component will show/hide the terrain. */ public class TerrainComponent extends RenderComponent { + private static final Logger logger = LoggerFactory.getLogger(TerrainComponent.class); private static final int TERRAIN_LAYER = 0; private final TiledMap tiledMap; @@ -21,6 +31,11 @@ public class TerrainComponent extends RenderComponent { private final OrthographicCamera camera; private final TerrainOrientation orientation; private final float tileSize; + private TiledMapTileLayer.Cell lastHoveredCell = null; + private TiledMapTile originalTile = null; + private TextureRegion originalRegion = null; + + public TerrainComponent( OrthographicCamera camera, @@ -33,6 +48,7 @@ public TerrainComponent( this.orientation = orientation; this.tileSize = tileSize; this.tiledMapRenderer = renderer; + } public Vector2 tileToWorldPosition(GridPoint2 tilePos) { @@ -70,6 +86,7 @@ public TiledMap getMap() { @Override public void draw(SpriteBatch batch) { tiledMapRenderer.setView(camera); + hoverHighlight(); tiledMapRenderer.render(); } @@ -89,6 +106,88 @@ public int getLayer() { return TERRAIN_LAYER; } + // TODO : This is just a visual effect that we might not need in the end but just keeping it here for now + public void colorTile(final int x, final int y) { + final TiledMapTileLayer tileLayer = (TiledMapTileLayer) tiledMap.getLayers().get(0); + final TiledMapTile originalTile = tileLayer.getCell(x, y).getTile(); + + ResourceService resourceService = ServiceLocator.getResourceService(); + + // Load all the tiles into an array + final TerrainTile[] terrainTiles = new TerrainTile[7]; + for (int i = 0; i < 7; i++) { + Texture texture = resourceService.getAsset("images/GrassTile/grass_tile_" + (i + 1) + ".png", Texture.class); + terrainTiles[i] = new TerrainTile(new TextureRegion(texture)); + } + + final float interval = 0.2f; // Switch every 0.2 seconds + final float duration = 1.4f; // 7 images * 0.2 seconds each + + Timer.schedule(new Timer.Task() { + float timeElapsed = 0.0f; + + @Override + public void run() { + timeElapsed += interval; + + if (timeElapsed >= duration) { + tileLayer.getCell(x, y).setTile(originalTile); // Reset to original tile after the total duration + this.cancel(); // End the timer task + } else { + int index = (int) (timeElapsed / interval); + tileLayer.getCell(x, y).setTile(terrainTiles[index]); + } + } + }, 0, interval, (int) (duration / interval) - 1); // Scheduling the task + } + + /** + * Highlights the tile under the mouse cursor by changing its texture region. + * + *

When hovering over a tile on the terrain, this method performs the following: + *

    + *
  1. Unprojects the mouse's screen position to the world position using the camera.
  2. + *
  3. Calculates the tile's coordinates based on the world position and tile size.
  4. + *
  5. If there was a previously highlighted tile, it restores its original texture region.
  6. + *
  7. If the current tile under the mouse is different from the last hovered tile, it updates + * the tile's texture region to a highlight texture.
  8. + *
  9. Updates the reference to the last hovered tile.
  10. + *
+ *

+ * + * @see TiledMapTileLayer + * @see TiledMapTileLayer.Cell + * @see TextureRegion + */ + + public void hoverHighlight() { + Vector3 mousePos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0); + camera.unproject(mousePos); + + + int tileX = (int) (mousePos.x / tileSize); + int tileY = (int) (mousePos.y / tileSize); + + final TiledMapTileLayer tileLayer = (TiledMapTileLayer) tiledMap.getLayers().get(0); + TiledMapTileLayer.Cell currentCell = tileLayer.getCell(tileX, tileY); + + + if (lastHoveredCell != null && lastHoveredCell != currentCell && originalRegion != null) { + lastHoveredCell.getTile().setTextureRegion(originalRegion); + } + + + if (currentCell != null && currentCell != lastHoveredCell) { + originalRegion = currentCell.getTile().getTextureRegion(); + + ResourceService resourceService = ServiceLocator.getResourceService(); + Texture texture = resourceService.getAsset("images/highlight_tile.png", Texture.class); + currentCell.getTile().setTextureRegion(new TextureRegion(texture)); + } + + lastHoveredCell = currentCell; + } + public enum TerrainOrientation { ORTHOGONAL, ISOMETRIC, diff --git a/source/core/src/main/com/csse3200/game/areas/terrain/TerrainFactory.java b/source/core/src/main/com/csse3200/game/areas/terrain/TerrainFactory.java index d6377e4a1..dfbd4f782 100644 --- a/source/core/src/main/com/csse3200/game/areas/terrain/TerrainFactory.java +++ b/source/core/src/main/com/csse3200/game/areas/terrain/TerrainFactory.java @@ -1,6 +1,7 @@ package com.csse3200.game.areas.terrain; import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.maps.tiled.TiledMap; @@ -8,6 +9,7 @@ import com.badlogic.gdx.maps.tiled.TiledMapTileLayer; import com.badlogic.gdx.maps.tiled.TiledMapTileLayer.Cell; import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer; +import com.badlogic.gdx.maps.tiled.tiles.StaticTiledMapTile; import com.badlogic.gdx.math.GridPoint2; import com.csse3200.game.components.CameraComponent; import com.csse3200.game.services.ResourceService; @@ -81,7 +83,7 @@ private TerrainComponent createTerrain(float tileWorldSize, TextureRegion terrai * @return A TiledMapRenderer instance suitable for the given map and scale. */ - private TiledMapRenderer createRenderer(TiledMap tiledMap, float tileScale) { + public TiledMapRenderer createRenderer(TiledMap tiledMap, float tileScale) { switch (orientation) { case ORTHOGONAL: return new OrthogonalTiledMapRenderer(tiledMap, tileScale); @@ -100,9 +102,8 @@ private TiledMapRenderer createRenderer(TiledMap tiledMap, float tileScale) { private TiledMap createTiles(GridPoint2 tileSize, TextureRegion terrain) { TiledMap tiledMap = new TiledMap(); - TerrainTile Tile = new TerrainTile(terrain); - TiledMapTileLayer Layer = new TiledMapTileLayer(20, 8, tileSize.x, tileSize.y); - fillInvisibleTiles(Layer, new GridPoint2(20, 8), Tile); + TiledMapTileLayer Layer = new TiledMapTileLayer(20, 6, tileSize.x, tileSize.y); + fillInvisibleTiles(Layer, new GridPoint2(20, 6), terrain); tiledMap.getLayers().add(Layer); return tiledMap; @@ -114,11 +115,12 @@ private TiledMap createTiles(GridPoint2 tileSize, TextureRegion terrain) { * * @param layer The tile layer to fill. * @param mapSize The size of the map in tiles. - * @param tile The tile used to fill the layer. + * @param terrain The tile used to fill the layer. */ - private void fillInvisibleTiles(TiledMapTileLayer layer, GridPoint2 mapSize, TerrainTile tile) { + private void fillInvisibleTiles(TiledMapTileLayer layer, GridPoint2 mapSize, TextureRegion terrain) { for (int x = 0; x < mapSize.x; x++) { - for (int y = 2; y < mapSize.y; y++) { + for (int y = 0; y < mapSize.y; y++) { + TerrainTile tile = new TerrainTile(terrain); Cell cell = new Cell(); cell.setTile(tile); layer.setCell(x, y, cell); 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 0c59b6c59..54010fb54 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 @@ -65,7 +65,7 @@ public WaveClass getWave(int index) { public void spawnWave() { if (gameTime.getTime() >= startTime + spawnDelay * 1000) { do { - currentRandom = rand.nextInt(1, 7); + currentRandom = rand.nextInt(0, ServiceLocator.getMapService().getHeight()); } while (currentRandom == previousRandom); ServiceLocator.getWaveService().setNextLane(currentRandom); GridPoint2 randomPos = new GridPoint2(19, currentRandom); diff --git a/source/core/src/main/com/csse3200/game/components/tower/TNTDamageComponent.java b/source/core/src/main/com/csse3200/game/components/tower/TNTDamageComponent.java index 775653651..e7ba86ef6 100644 --- a/source/core/src/main/com/csse3200/game/components/tower/TNTDamageComponent.java +++ b/source/core/src/main/com/csse3200/game/components/tower/TNTDamageComponent.java @@ -124,6 +124,7 @@ private void applyDamage(Fixture me, Fixture other) { Body targetBody = physicsComponent.getBody(); Vector2 direction = target.getCenterPosition().sub(entity.getCenterPosition()).nor(); + direction.y = 0; Vector2 impulse = direction.scl(knockbackForce); targetBody.applyLinearImpulse(impulse, targetBody.getWorldCenter(), true); } diff --git a/source/core/src/main/com/csse3200/game/entities/factories/TowerFactory.java b/source/core/src/main/com/csse3200/game/entities/factories/TowerFactory.java index 1341746fd..6302c0d8c 100644 --- a/source/core/src/main/com/csse3200/game/entities/factories/TowerFactory.java +++ b/source/core/src/main/com/csse3200/game/entities/factories/TowerFactory.java @@ -260,7 +260,7 @@ public static Entity createFireTower() { .getAsset(FIRE_TOWER_ATLAS, TextureAtlas.class)); animator.addAnimation(FIRE_TOWER_IDLE_ANIM, FIRE_TOWER_IDLE_SPEED, Animation.PlayMode.LOOP); animator.addAnimation(FIRE_TOWER_PREP_ATTACK_ANIM, FIRE_TOWER_PREP_ATTACK_SPEED, Animation.PlayMode.NORMAL); - animator.addAnimation(FIRE_TOWER_ATTACK_ANIM, FIRE_TOWER_ATTACK_SPEED, Animation.PlayMode.LOOP); + animator.addAnimation(FIRE_TOWER_ATTACK_ANIM, FIRE_TOWER_ATTACK_SPEED+ 0.25f, Animation.PlayMode.LOOP); animator.addAnimation(FIRE_TOWER_DEATH_ANIM, FIRE_TOWER_DEATH_SPEED, Animation.PlayMode.NORMAL); fireTower @@ -289,7 +289,7 @@ public static Entity createStunTower() { ServiceLocator.getResourceService() .getAsset(STUN_TOWER_ATLAS, TextureAtlas.class)); animator.addAnimation(STUN_TOWER_IDLE_ANIM, STUN_TOWER_IDLE_SPEED, Animation.PlayMode.LOOP); - animator.addAnimation(STUN_TOWER_ATTACK_ANIM, STUN_TOWER_ATTACK_SPEED, Animation.PlayMode.LOOP); + animator.addAnimation(STUN_TOWER_ATTACK_ANIM, STUN_TOWER_ATTACK_SPEED+ 0.25f, Animation.PlayMode.LOOP); animator.addAnimation(STUN_TOWER_DEATH_ANIM, STUN_TOWER_DEATH_SPEED, Animation.PlayMode.NORMAL); stunTower diff --git a/source/core/src/main/com/csse3200/game/screens/DesertGameScreen.java b/source/core/src/main/com/csse3200/game/screens/DesertGameScreen.java deleted file mode 100644 index fee0b0280..000000000 --- a/source/core/src/main/com/csse3200/game/screens/DesertGameScreen.java +++ /dev/null @@ -1,196 +0,0 @@ -package com.csse3200.game.screens; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.ScreenAdapter; -import com.badlogic.gdx.graphics.OrthographicCamera; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.scenes.scene2d.Stage; -import com.badlogic.gdx.utils.viewport.ScreenViewport; -import com.badlogic.gdx.utils.viewport.Viewport; -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.entities.Entity; -import com.csse3200.game.entities.EntityService; -import com.csse3200.game.entities.factories.RenderFactory; -import com.csse3200.game.input.DropInputComponent; -import com.csse3200.game.input.InputComponent; -import com.csse3200.game.input.InputDecorator; -import com.csse3200.game.input.InputService; -import com.csse3200.game.physics.PhysicsEngine; -import com.csse3200.game.physics.PhysicsService; -import com.csse3200.game.rendering.RenderService; -import com.csse3200.game.rendering.Renderer; -import com.csse3200.game.services.*; -import com.csse3200.game.ui.terminal.Terminal; -import com.csse3200.game.ui.terminal.TerminalDisplay; -import com.csse3200.game.components.maingame.MainGameExitDisplay; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DesertGameScreen extends ScreenAdapter { - private static final Logger logger = LoggerFactory.getLogger(DesertGameScreen.class); - private static final String[] mainGameTextures = {"images/heart.png"}; - private static final Vector2 CAMERA_POSITION = new Vector2(10f, 5.64f); - - private final GdxGame game; - private final Renderer renderer; - private final PhysicsEngine physicsEngine; - - private final Stage stage; - static int screenWidth = Gdx.graphics.getWidth(); - static int screenHeight = Gdx.graphics.getHeight(); - - private Entity ui; - - - public static int viewportWidth = screenWidth; - public static int viewportHeight= screenHeight; - - - - private OrthographicCamera camera; - private SpriteBatch batch; - - private Texture backgroundTexture; - - public DesertGameScreen(GdxGame game) { - this.game = game; - camera = new OrthographicCamera(); - camera.setToOrtho(false, viewportWidth, viewportHeight); - camera.position.set((float) (viewportWidth) / 2, (float) (viewportHeight) / 2, 0); - - batch = new SpriteBatch(); - - Viewport viewport = new ScreenViewport(camera); - stage = new Stage(viewport, new SpriteBatch()); - - - - logger.debug("Initialising main game screen services"); - ServiceLocator.registerTimeSource(new GameTime()); - - PhysicsService physicsService = new PhysicsService(); - ServiceLocator.registerPhysicsService(physicsService); - physicsEngine = physicsService.getPhysics(); - - ServiceLocator.registerInputService(new InputService()); - ServiceLocator.registerResourceService(new ResourceService()); - - ServiceLocator.registerCurrencyService(new CurrencyService()); - - ServiceLocator.registerEntityService(new EntityService()); - ServiceLocator.registerRenderService(new RenderService()); - ServiceLocator.registerGameEndService(new GameEndService()); - - renderer = RenderFactory.createRenderer(); - renderer.getCamera().getEntity().setPosition(CAMERA_POSITION); - renderer.getDebug().renderPhysicsWorld(physicsEngine.getWorld()); - InputComponent inputHandler = new DropInputComponent(renderer.getCamera().getCamera()); - ServiceLocator.getInputService().register(inputHandler); - - ServiceLocator.getCurrencyService().getDisplay().setCamera(renderer.getCamera().getCamera()); - - loadAssets(); - createUI(); - - logger.debug("Initialising main game screen entities"); - TerrainFactory terrainFactory = new TerrainFactory(renderer.getCamera()); - ForestGameArea forestGameArea = new ForestGameArea(terrainFactory); - forestGameArea.create(); - } - - @Override - public void render(float delta) { - physicsEngine.update(); - ServiceLocator.getEntityService().update(); - - // Check if the game has ended - if (ServiceLocator.getGameEndService().hasGameEnded()) { - ui.getEvents().trigger("lose"); - } - - batch.setProjectionMatrix(camera.combined); - batch.begin(); - batch.draw(backgroundTexture, 0, 0, viewportWidth, viewportHeight); - batch.end(); - - - renderer.render(); - stage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f)); - stage.draw(); - } - - - - - @Override - public void resize(int width, int height) { - renderer.resize(width, height); - logger.trace("Resized renderer: ({} x {})", width, height); - } - - @Override - public void pause() { - logger.info("Game paused"); - } - - @Override - public void resume() { - logger.info("Game resumed"); - } - - @Override - public void dispose() { - logger.debug("Disposing main game screen"); - - renderer.dispose(); - unloadAssets(); - - ServiceLocator.getEntityService().dispose(); - ServiceLocator.getRenderService().dispose(); - ServiceLocator.getResourceService().dispose(); - - ServiceLocator.clear(); - } - - private void loadAssets() { - logger.debug("Loading assets"); - ResourceService resourceService = ServiceLocator.getResourceService(); - resourceService.loadTextures(mainGameTextures); - backgroundTexture = new Texture("images/Dusty_MoonBG.png"); // Load the background image - ServiceLocator.getResourceService().loadAll(); - } - - private void unloadAssets() { - logger.debug("Unloading assets"); - ResourceService resourceService = ServiceLocator.getResourceService(); - resourceService.unloadAssets(mainGameTextures); - } - - /** - * Creates the main game's ui including components for rendering ui elements to the screen and - * capturing and handling ui input. - */ - private void createUI() { - logger.debug("Creating ui"); - Stage stage = ServiceLocator.getRenderService().getStage(); - InputComponent inputComponent = - ServiceLocator.getInputService().getInputFactory().createForTerminal(); - - Entity ui = new Entity(); - ui.addComponent(new InputDecorator(stage, 10)) - .addComponent(new PerformanceDisplay()) - .addComponent(new MainGameActions(this.game)) - .addComponent(new MainGameExitDisplay()) - .addComponent(new Terminal()) - .addComponent(inputComponent) - .addComponent(new TerminalDisplay()); - - ServiceLocator.getEntityService().register(ui); - } -} \ No newline at end of file diff --git a/source/core/src/main/com/csse3200/game/screens/IceGameScreen.java b/source/core/src/main/com/csse3200/game/screens/IceGameScreen.java deleted file mode 100644 index dc825de39..000000000 --- a/source/core/src/main/com/csse3200/game/screens/IceGameScreen.java +++ /dev/null @@ -1,196 +0,0 @@ -package com.csse3200.game.screens; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.ScreenAdapter; -import com.badlogic.gdx.graphics.OrthographicCamera; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.scenes.scene2d.Stage; -import com.badlogic.gdx.utils.viewport.ScreenViewport; -import com.badlogic.gdx.utils.viewport.Viewport; -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.entities.Entity; -import com.csse3200.game.entities.EntityService; -import com.csse3200.game.entities.factories.RenderFactory; -import com.csse3200.game.input.DropInputComponent; -import com.csse3200.game.input.InputComponent; -import com.csse3200.game.input.InputDecorator; -import com.csse3200.game.input.InputService; -import com.csse3200.game.physics.PhysicsEngine; -import com.csse3200.game.physics.PhysicsService; -import com.csse3200.game.rendering.RenderService; -import com.csse3200.game.rendering.Renderer; -import com.csse3200.game.services.*; -import com.csse3200.game.ui.terminal.Terminal; -import com.csse3200.game.ui.terminal.TerminalDisplay; -import com.csse3200.game.components.maingame.MainGameExitDisplay; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class IceGameScreen extends ScreenAdapter { - private static final Logger logger = LoggerFactory.getLogger(IceGameScreen.class); - private static final String[] mainGameTextures = {"images/heart.png"}; - private static final Vector2 CAMERA_POSITION = new Vector2(10f, 5.64f); - - private final GdxGame game; - private final Renderer renderer; - private final PhysicsEngine physicsEngine; - - private final Stage stage; - static int screenWidth = Gdx.graphics.getWidth(); - static int screenHeight = Gdx.graphics.getHeight(); - - private Entity ui; - - - public static int viewportWidth = screenWidth; - public static int viewportHeight= screenHeight; - - - - private OrthographicCamera camera; - private SpriteBatch batch; - - private Texture backgroundTexture; - - public IceGameScreen(GdxGame game) { - this.game = game; - camera = new OrthographicCamera(); - camera.setToOrtho(false, viewportWidth, viewportHeight); - camera.position.set((float) (viewportWidth) / 2, (float) (viewportHeight) / 2, 0); - - batch = new SpriteBatch(); - - Viewport viewport = new ScreenViewport(camera); - stage = new Stage(viewport, new SpriteBatch()); - - - - logger.debug("Initialising main game screen services"); - ServiceLocator.registerTimeSource(new GameTime()); - - PhysicsService physicsService = new PhysicsService(); - ServiceLocator.registerPhysicsService(physicsService); - physicsEngine = physicsService.getPhysics(); - - ServiceLocator.registerInputService(new InputService()); - ServiceLocator.registerResourceService(new ResourceService()); - - ServiceLocator.registerCurrencyService(new CurrencyService()); - - ServiceLocator.registerEntityService(new EntityService()); - ServiceLocator.registerRenderService(new RenderService()); - ServiceLocator.registerGameEndService(new GameEndService()); - - renderer = RenderFactory.createRenderer(); - renderer.getCamera().getEntity().setPosition(CAMERA_POSITION); - renderer.getDebug().renderPhysicsWorld(physicsEngine.getWorld()); - InputComponent inputHandler = new DropInputComponent(renderer.getCamera().getCamera()); - ServiceLocator.getInputService().register(inputHandler); - - ServiceLocator.getCurrencyService().getDisplay().setCamera(renderer.getCamera().getCamera()); - - loadAssets(); - createUI(); - - logger.debug("Initialising main game screen entities"); - TerrainFactory terrainFactory = new TerrainFactory(renderer.getCamera()); - ForestGameArea forestGameArea = new ForestGameArea(terrainFactory); - forestGameArea.create(); - } - - @Override - public void render(float delta) { - physicsEngine.update(); - ServiceLocator.getEntityService().update(); - - // Check if the game has ended - if (ServiceLocator.getGameEndService().hasGameEnded()) { - ui.getEvents().trigger("lose"); - } - - batch.setProjectionMatrix(camera.combined); - batch.begin(); - batch.draw(backgroundTexture, 0, 0, viewportWidth, viewportHeight); - batch.end(); - - - renderer.render(); - stage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f)); - stage.draw(); - } - - - - - @Override - public void resize(int width, int height) { - renderer.resize(width, height); - logger.trace("Resized renderer: ({} x {})", width, height); - } - - @Override - public void pause() { - logger.info("Game paused"); - } - - @Override - public void resume() { - logger.info("Game resumed"); - } - - @Override - public void dispose() { - logger.debug("Disposing main game screen"); - - renderer.dispose(); - unloadAssets(); - - ServiceLocator.getEntityService().dispose(); - ServiceLocator.getRenderService().dispose(); - ServiceLocator.getResourceService().dispose(); - - ServiceLocator.clear(); - } - - private void loadAssets() { - logger.debug("Loading assets"); - ResourceService resourceService = ServiceLocator.getResourceService(); - resourceService.loadTextures(mainGameTextures); - backgroundTexture = new Texture("images/Dusty_MoonBG.png"); // Load the background image - ServiceLocator.getResourceService().loadAll(); - } - - private void unloadAssets() { - logger.debug("Unloading assets"); - ResourceService resourceService = ServiceLocator.getResourceService(); - resourceService.unloadAssets(mainGameTextures); - } - - /** - * Creates the main game's ui including components for rendering ui elements to the screen and - * capturing and handling ui input. - */ - private void createUI() { - logger.debug("Creating ui"); - Stage stage = ServiceLocator.getRenderService().getStage(); - InputComponent inputComponent = - ServiceLocator.getInputService().getInputFactory().createForTerminal(); - - Entity ui = new Entity(); - ui.addComponent(new InputDecorator(stage, 10)) - .addComponent(new PerformanceDisplay()) - .addComponent(new MainGameActions(this.game)) - .addComponent(new MainGameExitDisplay()) - .addComponent(new Terminal()) - .addComponent(inputComponent) - .addComponent(new TerminalDisplay()); - - ServiceLocator.getEntityService().register(ui); - } -} \ No newline at end of file diff --git a/source/core/src/main/com/csse3200/game/screens/LavaGameScreen.java b/source/core/src/main/com/csse3200/game/screens/LavaGameScreen.java deleted file mode 100644 index a2c641168..000000000 --- a/source/core/src/main/com/csse3200/game/screens/LavaGameScreen.java +++ /dev/null @@ -1,196 +0,0 @@ -package com.csse3200.game.screens; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.ScreenAdapter; -import com.badlogic.gdx.graphics.OrthographicCamera; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.scenes.scene2d.Stage; -import com.badlogic.gdx.utils.viewport.ScreenViewport; -import com.badlogic.gdx.utils.viewport.Viewport; -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.entities.Entity; -import com.csse3200.game.entities.EntityService; -import com.csse3200.game.entities.factories.RenderFactory; -import com.csse3200.game.input.DropInputComponent; -import com.csse3200.game.input.InputComponent; -import com.csse3200.game.input.InputDecorator; -import com.csse3200.game.input.InputService; -import com.csse3200.game.physics.PhysicsEngine; -import com.csse3200.game.physics.PhysicsService; -import com.csse3200.game.rendering.RenderService; -import com.csse3200.game.rendering.Renderer; -import com.csse3200.game.services.*; -import com.csse3200.game.ui.terminal.Terminal; -import com.csse3200.game.ui.terminal.TerminalDisplay; -import com.csse3200.game.components.maingame.MainGameExitDisplay; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class LavaGameScreen extends ScreenAdapter { - private static final Logger logger = LoggerFactory.getLogger(LavaGameScreen.class); - private static final String[] mainGameTextures = {"images/heart.png"}; - private static final Vector2 CAMERA_POSITION = new Vector2(10f, 5.64f); - - private final GdxGame game; - private final Renderer renderer; - private final PhysicsEngine physicsEngine; - - private final Stage stage; - static int screenWidth = Gdx.graphics.getWidth(); - static int screenHeight = Gdx.graphics.getHeight(); - - private Entity ui; - - - public static int viewportWidth = screenWidth; - public static int viewportHeight= screenHeight; - - - - private OrthographicCamera camera; - private SpriteBatch batch; - - private Texture backgroundTexture; - - public LavaGameScreen(GdxGame game) { - this.game = game; - camera = new OrthographicCamera(); - camera.setToOrtho(false, viewportWidth, viewportHeight); - camera.position.set((float) (viewportWidth) / 2, (float) (viewportHeight) / 2, 0); - - batch = new SpriteBatch(); - - Viewport viewport = new ScreenViewport(camera); - stage = new Stage(viewport, new SpriteBatch()); - - - - logger.debug("Initialising main game screen services"); - ServiceLocator.registerTimeSource(new GameTime()); - - PhysicsService physicsService = new PhysicsService(); - ServiceLocator.registerPhysicsService(physicsService); - physicsEngine = physicsService.getPhysics(); - - ServiceLocator.registerInputService(new InputService()); - ServiceLocator.registerResourceService(new ResourceService()); - - ServiceLocator.registerCurrencyService(new CurrencyService()); - - ServiceLocator.registerEntityService(new EntityService()); - ServiceLocator.registerRenderService(new RenderService()); - ServiceLocator.registerGameEndService(new GameEndService()); - - renderer = RenderFactory.createRenderer(); - renderer.getCamera().getEntity().setPosition(CAMERA_POSITION); - renderer.getDebug().renderPhysicsWorld(physicsEngine.getWorld()); - InputComponent inputHandler = new DropInputComponent(renderer.getCamera().getCamera()); - ServiceLocator.getInputService().register(inputHandler); - - ServiceLocator.getCurrencyService().getDisplay().setCamera(renderer.getCamera().getCamera()); - - loadAssets(); - createUI(); - - logger.debug("Initialising main game screen entities"); - TerrainFactory terrainFactory = new TerrainFactory(renderer.getCamera()); - ForestGameArea forestGameArea = new ForestGameArea(terrainFactory); - forestGameArea.create(); - } - - @Override - public void render(float delta) { - physicsEngine.update(); - ServiceLocator.getEntityService().update(); - - // Check if the game has ended - if (ServiceLocator.getGameEndService().hasGameEnded()) { - ui.getEvents().trigger("lose"); - } - - batch.setProjectionMatrix(camera.combined); - batch.begin(); - batch.draw(backgroundTexture, 0, 0, viewportWidth, viewportHeight); - batch.end(); - - - renderer.render(); - stage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f)); - stage.draw(); - } - - - - - @Override - public void resize(int width, int height) { - renderer.resize(width, height); - logger.trace("Resized renderer: ({} x {})", width, height); - } - - @Override - public void pause() { - logger.info("Game paused"); - } - - @Override - public void resume() { - logger.info("Game resumed"); - } - - @Override - public void dispose() { - logger.debug("Disposing main game screen"); - - renderer.dispose(); - unloadAssets(); - - ServiceLocator.getEntityService().dispose(); - ServiceLocator.getRenderService().dispose(); - ServiceLocator.getResourceService().dispose(); - - ServiceLocator.clear(); - } - - private void loadAssets() { - logger.debug("Loading assets"); - ResourceService resourceService = ServiceLocator.getResourceService(); - resourceService.loadTextures(mainGameTextures); - backgroundTexture = new Texture("images/Dusty_MoonBG.png"); // Load the background image - ServiceLocator.getResourceService().loadAll(); - } - - private void unloadAssets() { - logger.debug("Unloading assets"); - ResourceService resourceService = ServiceLocator.getResourceService(); - resourceService.unloadAssets(mainGameTextures); - } - - /** - * Creates the main game's ui including components for rendering ui elements to the screen and - * capturing and handling ui input. - */ - private void createUI() { - logger.debug("Creating ui"); - Stage stage = ServiceLocator.getRenderService().getStage(); - InputComponent inputComponent = - ServiceLocator.getInputService().getInputFactory().createForTerminal(); - - Entity ui = new Entity(); - ui.addComponent(new InputDecorator(stage, 10)) - .addComponent(new PerformanceDisplay()) - .addComponent(new MainGameActions(this.game)) - .addComponent(new MainGameExitDisplay()) - .addComponent(new Terminal()) - .addComponent(inputComponent) - .addComponent(new TerminalDisplay()); - - ServiceLocator.getEntityService().register(ui); - } -} \ No newline at end of file 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 93a78401c..bf2de6a5c 100644 --- a/source/core/src/main/com/csse3200/game/screens/LevelSelectScreen.java +++ b/source/core/src/main/com/csse3200/game/screens/LevelSelectScreen.java @@ -104,38 +104,11 @@ private void spawnPlanetBorders() { logger.info("Loading level {}", planet[4]); GameLevelData.setSelectedLevel(planet[4]); game.setScreen(new TurretSelectionScreen(game)); -// if (planet[4] == 0) { -// handleDesertPlanetClick(); -// game.setScreen(new TurretSelectionScreen(game)); -// } else if (planet[4] == 1) { -// handleIcePlanetClick(); -// game.setScreen(new TurretSelectionScreen(game)); -// } else if (planet[4] == 2) { -// handleLavaPlanetClick(); -// game.setScreen(new TurretSelectionScreen(game)); -// } } } } } - private void handleDesertPlanetClick() { - // Implement logic for when the desert planet is clicked - logger.info("Desert planet clicked."); - game.setScreen(new DesertGameScreen(game)); // Load the DesertGameScreen - } - - private void handleIcePlanetClick() { - // Implement logic for when the ice planet is clicked - logger.info("Ice planet clicked."); - game.setScreen(new IceGameScreen(game)); // Load the IceGameScreen - } - - private void handleLavaPlanetClick() { - // Implement logic for when the lava planet is clicked - logger.info("Lava planet clicked."); - game.setScreen(new LavaGameScreen(game)); // Load the LavaGameScreen - } // TODO: Make it display information about the planet @Override 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 05b5eaf58..a86e63e09 100644 --- a/source/core/src/main/com/csse3200/game/screens/MainGameScreen.java +++ b/source/core/src/main/com/csse3200/game/screens/MainGameScreen.java @@ -40,7 +40,7 @@ */ public class MainGameScreen extends ScreenAdapter { private static final Logger logger = LoggerFactory.getLogger(MainGameScreen.class); - private static final String[] mainGameTextures = {"images/heart.png","images/ice_bg.png","images/lava_bg.png","images/desert_bg.png"}; + private static final String[] mainGameTextures = {"images/heart.png","images/ice_bg.png","images/lava_bg.png","images/desert_bg.png","images/terrain_use.png"}; private static final Vector2 CAMERA_POSITION = new Vector2(10f, 5.64f); private final GdxGame game; @@ -96,15 +96,14 @@ public MainGameScreen(GdxGame game) { renderer.getDebug().renderPhysicsWorld(physicsEngine.getWorld()); InputComponent inputHandler = new DropInputComponent(renderer.getCamera().getCamera()); ServiceLocator.getInputService().register(inputHandler); - ServiceLocator.getCurrencyService().getDisplay().setCamera(renderer.getCamera().getCamera()); loadAssets(); createUI(); - + ServiceLocator.registerMapService(new MapService(renderer.getCamera())); logger.debug("Initialising main game screen entities"); - TerrainFactory terrainFactory = new TerrainFactory(renderer.getCamera()); - ForestGameArea forestGameArea = new ForestGameArea(terrainFactory); +// TerrainFactory terrainFactory = new TerrainFactory(renderer.getCamera()); + ForestGameArea forestGameArea = new ForestGameArea(); forestGameArea.create(); } diff --git a/source/core/src/main/com/csse3200/game/services/MapService.java b/source/core/src/main/com/csse3200/game/services/MapService.java new file mode 100644 index 000000000..e677c9586 --- /dev/null +++ b/source/core/src/main/com/csse3200/game/services/MapService.java @@ -0,0 +1,76 @@ +package com.csse3200.game.services; + +import com.csse3200.game.areas.terrain.TerrainComponent; +import com.csse3200.game.areas.terrain.TerrainFactory; +import com.csse3200.game.components.CameraComponent; +import com.csse3200.game.entities.Entity; + +/** + * Provides services related to map functionalities such as tiles and lanes in genral. + */ +public class MapService { + + private Entity entity; + private final TerrainFactory terrainFactory; + + /** + * Constructs a new MapService instance based on the provided camera. + * + * @param camera The camera component used for the terrain creation. + */ + public MapService(CameraComponent camera) { + this.terrainFactory = new TerrainFactory(camera); + this.entity = new Entity().addComponent(terrainFactory.createTerrain(TerrainFactory.TerrainType.ALL_DEMO)); + } + + /** + * Constructs a new MapService instance using the given entity and terrain factory. + * + * @param entity The entity associated with this service. + * @param terrainFactory The terrain factory used for creating terrains. + */ + public MapService(Entity entity, TerrainFactory terrainFactory) { + this.entity = entity; + this.terrainFactory = terrainFactory; + } + + /** + * Returns the associated entity. + * + * @return The entity related to this map service. + */ + public Entity getEntity() { + + return this.entity; + } + + /** + * Retrieves the terrain component from the entity. + * + * @return The terrain component of the associated entity. + */ + public TerrainComponent getComponent() { + + return entity.getComponent(TerrainComponent.class); + } + + /** + * Returns the height of the Grid. + * + * @return Height of the Grid. + */ + public int getHeight() { + + return entity.getComponent(TerrainComponent.class).getMapBounds(0).y; + } + + /** + * Returns the width of the Grid. + * + * @return Width of the Grid. + */ + public int getWidth() { + + return entity.getComponent(TerrainComponent.class).getMapBounds(0).x; + } +} 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 12d53a83f..449b7f11a 100644 --- a/source/core/src/main/com/csse3200/game/services/ServiceLocator.java +++ b/source/core/src/main/com/csse3200/game/services/ServiceLocator.java @@ -26,6 +26,7 @@ public class ServiceLocator { private static ResourceService resourceService; private static GameEndService gameEndService; private static WaveService waveService; + private static MapService mapService; public static CurrencyService getCurrencyService() { return currencyService; @@ -61,6 +62,8 @@ public static GameEndService getGameEndService() { public static WaveService getWaveService() { return waveService; } + public static MapService getMapService() { return mapService; } + public static void registerCurrencyService(CurrencyService service) { logger.debug("Registering currency service {}", service); currencyService = service; @@ -105,6 +108,11 @@ public static void registerWaveService(WaveService source) { waveService = source; } + public static void registerMapService(MapService source) { + logger.debug("Registering wave service {}", source); + mapService = source; + } + public static void clear() { entityService = null; renderService = null; @@ -113,6 +121,8 @@ public static void clear() { inputService = null; resourceService = null; gameEndService = null; + waveService = null; + mapService = null; } private ServiceLocator() { diff --git a/source/core/src/test/com/csse3200/game/areas/terrain/TerrainComponentTest.java b/source/core/src/test/com/csse3200/game/areas/terrain/TerrainComponentTest.java index 6761b39b9..72961fb8d 100644 --- a/source/core/src/test/com/csse3200/game/areas/terrain/TerrainComponentTest.java +++ b/source/core/src/test/com/csse3200/game/areas/terrain/TerrainComponentTest.java @@ -3,12 +3,23 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Input; import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.maps.MapLayers; import com.badlogic.gdx.maps.tiled.TiledMap; import com.badlogic.gdx.maps.tiled.TiledMapRenderer; +import com.badlogic.gdx.maps.tiled.TiledMapTile; +import com.badlogic.gdx.maps.tiled.TiledMapTileLayer; import com.badlogic.gdx.math.Vector2; import com.csse3200.game.areas.terrain.TerrainComponent.TerrainOrientation; import com.csse3200.game.extensions.GameExtension; +import static org.mockito.Mockito.*; + +import com.csse3200.game.services.ResourceService; +import com.csse3200.game.services.ServiceLocator; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -35,6 +46,42 @@ void shouldConvertPositionHexagonal() { TerrainComponent component = makeComponent(TerrainOrientation.HEXAGONAL, 3f); } + @Test + void shouldHighlightTileOnHover1() { + + TerrainComponent component = makeComponent(TerrainOrientation.ORTHOGONAL, 1f); + + // Mock Gdx input to return specific mouse position + Gdx.input = mock(Input.class); + when(Gdx.input.getX()).thenReturn(2); + when(Gdx.input.getY()).thenReturn(4); + + + MapLayers mockLayers = mock(MapLayers.class); + when(component.getMap().getLayers()).thenReturn(mockLayers); + + TiledMapTileLayer mockTileLayer = mock(TiledMapTileLayer.class); + when(mockLayers.get(0)).thenReturn(mockTileLayer); + + TiledMapTileLayer.Cell mockCell = mock(TiledMapTileLayer.Cell.class); + when(mockTileLayer.getCell(2, 4)).thenReturn(mockCell); + + TiledMapTile mockTile = mock(TiledMapTile.class); + when(mockCell.getTile()).thenReturn(mockTile); + + + Texture mockTexture = mock(Texture.class); + ServiceLocator.registerResourceService(mock(ResourceService.class)); + when(ServiceLocator.getResourceService().getAsset("images/highlight_tile.png", Texture.class)) + .thenReturn(mockTexture); + + + component.hoverHighlight(); + + // Verify that the tile's texture region was changed + verify(mockTile).setTextureRegion(any(TextureRegion.class)); + } + private static TerrainComponent makeComponent(TerrainOrientation orientation, float tileSize) { OrthographicCamera camera = mock(OrthographicCamera.class); TiledMap map = mock(TiledMap.class); diff --git a/source/core/src/test/com/csse3200/game/areas/terrain/TerrainFactoryTest.java b/source/core/src/test/com/csse3200/game/areas/terrain/TerrainFactoryTest.java new file mode 100644 index 000000000..c70237fd5 --- /dev/null +++ b/source/core/src/test/com/csse3200/game/areas/terrain/TerrainFactoryTest.java @@ -0,0 +1,63 @@ +package com.csse3200.game.areas.terrain; + +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.maps.tiled.TiledMap; +import com.badlogic.gdx.maps.tiled.TiledMapTileLayer; +import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer; +import com.csse3200.game.components.CameraComponent; +import com.csse3200.game.services.ResourceService; +import com.csse3200.game.services.ServiceLocator; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +public class TerrainFactoryTest { + + private TerrainFactory terrainFactory; + private CameraComponent mockedCameraComponent; + private OrthogonalTiledMapRenderer mockedRenderer; + private ResourceService mockResourceService; + private Texture mockTexture; + + @BeforeEach + public void setUp() { + // Create mocks + mockedCameraComponent = mock(CameraComponent.class); + mockedRenderer = mock(OrthogonalTiledMapRenderer.class); + mockResourceService = mock(ResourceService.class); + mockTexture = mock(Texture.class); + + + ServiceLocator.registerResourceService(mockResourceService); + + + OrthographicCamera mockedCamera = mock(OrthographicCamera.class); + when(mockedCameraComponent.getCamera()).thenReturn(mockedCamera); + + + terrainFactory = spy(new TerrainFactory(mockedCameraComponent)); + + + // When createRenderer is called on terrainFactory return the mockedRenderer + doReturn(mockedRenderer).when(terrainFactory).createRenderer(any(TiledMap.class), anyFloat()); + } + + @Test + public void testCreateTerrainGeneral() { + // Given the texture is taken from the ResourceService + when(mockResourceService.getAsset("images/terrain_use.png", Texture.class)).thenReturn(mockTexture); + + + TerrainComponent terrainComponent = terrainFactory.createTerrain(TerrainFactory.TerrainType.ALL_DEMO); + TiledMapTileLayer layer = (TiledMapTileLayer) terrainComponent.getMap().getLayers().get(0); + + // the terrainComponent should not be null + assertNotNull(terrainComponent, "TerrainComponent should not be null"); + assertEquals(6,layer.getHeight()); // 6 lanes + assertEquals(20,layer.getWidth()); // 20 tiles per lane + + } +} diff --git a/source/core/src/test/com/csse3200/game/services/MapServiceTest.java b/source/core/src/test/com/csse3200/game/services/MapServiceTest.java new file mode 100644 index 000000000..bf1173095 --- /dev/null +++ b/source/core/src/test/com/csse3200/game/services/MapServiceTest.java @@ -0,0 +1,58 @@ +package com.csse3200.game.services; + +import com.badlogic.gdx.math.GridPoint2; +import com.csse3200.game.areas.terrain.TerrainComponent; +import com.csse3200.game.areas.terrain.TerrainFactory; + +import com.csse3200.game.entities.Entity; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import static org.mockito.Mockito.*; + +public class MapServiceTest { + + private TerrainFactory mockTerrainFactory; + private TerrainComponent mockTerrainComponent; + private Entity mockEntity; + + + @BeforeEach + public void setUp() { + mockTerrainFactory = mock(TerrainFactory.class); + mockTerrainComponent = mock(TerrainComponent.class); + mockEntity = mock(Entity.class); + + + when(mockTerrainFactory.createTerrain(TerrainFactory.TerrainType.ALL_DEMO)).thenReturn(mockTerrainComponent); + when(mockEntity.getComponent(TerrainComponent.class)).thenReturn(mockTerrainComponent); + + } + + @Test + public void testConstructor() { + MapService mapService = new MapService(mockEntity, mockTerrainFactory); + + assertEquals(mockTerrainComponent, mapService.getComponent()); + + } + + @Test + public void testGetHeight() { + when(mockTerrainComponent.getMapBounds(0)).thenReturn(new GridPoint2(5,2)); // Example Point class to represent x and y + MapService mapService = new MapService(mockEntity, mockTerrainFactory); + + assertEquals(2, mapService.getHeight()); + } + + @Test + public void testGetWidth() { + when(mockTerrainComponent.getMapBounds(0)).thenReturn(new GridPoint2(5, 10)); // Example Point class to represent x and y + MapService mapService = new MapService(mockEntity, mockTerrainFactory); + + assertEquals(5, mapService.getWidth()); + } + +}