diff --git a/source/core/assets/images/ingamebg.png b/source/core/assets/images/desert_bg.png similarity index 100% rename from source/core/assets/images/ingamebg.png rename to source/core/assets/images/desert_bg.png diff --git a/source/core/assets/images/ice_bg.png b/source/core/assets/images/ice_bg.png new file mode 100644 index 000000000..2fae5a19e Binary files /dev/null and b/source/core/assets/images/ice_bg.png differ diff --git a/source/core/assets/images/lava_bg.png b/source/core/assets/images/lava_bg.png new file mode 100644 index 000000000..cca706805 Binary files /dev/null and b/source/core/assets/images/lava_bg.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 0ab3b95e9..138e0e6d9 100644 --- a/source/core/src/main/com/csse3200/game/areas/ForestGameArea.java +++ b/source/core/src/main/com/csse3200/game/areas/ForestGameArea.java @@ -14,6 +14,7 @@ import com.csse3200.game.physics.PhysicsLayer; import com.csse3200.game.utils.math.RandomUtils; import com.csse3200.game.services.ResourceService; +import com.csse3200.game.services.GameEndService; import com.csse3200.game.services.ServiceLocator; import com.csse3200.game.components.gamearea.GameAreaDisplay; import org.slf4j.Logger; @@ -54,7 +55,6 @@ public class ForestGameArea extends GameArea { "images/desert_bg.png", "images/ice_bg.png", "images/lava_bg.png", - "images/ingamebg.png", "images/projectiles/projectile.png", "images/ingamebg.png", "images/box_boy_leaf.png", 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 794878666..0f087d6fd 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 @@ -22,7 +22,7 @@ import com.csse3200.game.components.CameraComponent; import com.csse3200.game.services.ResourceService; import com.csse3200.game.services.ServiceLocator; - +import com.csse3200.game.screens.GameLevelData; import static com.csse3200.game.screens.MainGameScreen.viewportHeight; import static com.csse3200.game.screens.MainGameScreen.viewportWidth; @@ -34,6 +34,7 @@ public class TerrainFactory { private final TerrainOrientation orientation; private static Stage stage; private Texture whiteTexture; + int selectedLevel = GameLevelData.getSelectedLevel(); /** * Create a terrain factory with Orthogonal orientation @@ -106,25 +107,78 @@ private TiledMapRenderer createRenderer(TiledMap tiledMap, float tileScale) { private TiledMap createForestDemoTiles(GridPoint2 tileSize, TextureRegion grass) { TiledMap tiledMap = new TiledMap(); - + /** + * Creates a background layer for a tiled map with the specified dimensions and tile size. + * + * @param width The width of the layer in tiles. + * @param height The height of the layer in tiles. + * @param tileWidth The width of each individual tile in pixels. + * @param tileHeight The height of each individual tile in pixels. + */ // Create a background layer TiledMapTileLayer backgroundLayer = new TiledMapTileLayer(20, 8, tileSize.x, tileSize.y); - TextureRegion backgroundTextureRegion = new TextureRegion(ServiceLocator.getResourceService().getAsset("images/ingamebg.png", Texture.class)); + /** + * Define a TextureRegion to be used as the background texture. + */ + + TextureRegion backgroundTextureRegion ; + + switch (selectedLevel) { + case 0: // Desert + backgroundTextureRegion = new TextureRegion(ServiceLocator.getResourceService().getAsset("images/desert_bg.png", Texture.class)); + break; + case 1: // Ice + backgroundTextureRegion = new TextureRegion(ServiceLocator.getResourceService().getAsset("images/ice_bg.png", Texture.class)); + break; + case 2: // Lava + backgroundTextureRegion = new TextureRegion(ServiceLocator.getResourceService().getAsset("images/lava_bg.png", Texture.class)); + break; + default: + // Use a default background for other levels or planets + backgroundTextureRegion = new TextureRegion(ServiceLocator.getResourceService().getAsset("images/desert_bg.png", Texture.class)); + break; + } - // Create a single cell for the entire background image + /** + * Creates a single cell with the specified background texture region and adds it to the background layer + * of a tiled map. The background layer represents the entire background image of the map. + * + * @param backgroundTextureRegion The TextureRegion to use as the background texture. + * @param tileSizeX The width of each individual tile in pixels. + * @param tileSizeY The height of each individual tile in pixels. + * @param tiledMap The TiledMap to which the background layer should be added. + */ Cell cell = new Cell(); cell.setTile(new StaticTiledMapTile(backgroundTextureRegion)); backgroundLayer.setCell(0, 0, cell); tiledMap.getLayers().add(backgroundLayer); - // Create a grass layer + /** + * Creates a grass layer for the tiled map with the specified dimensions and tile size, filling it with + * grass tiles using the provided grass terrain tile. + * + * @param tileSizeX The width of each individual tile in pixels. + * @param tileSizeY The height of each individual tile in pixels. + * @param grassTile The TerrainTile representing the grass tile to be used for the layer. + * @param tiledMap The TiledMap to which the grass layer should be added. + */ TerrainTile grassTile = new TerrainTile(grass); TiledMapTileLayer grassLayer = new TiledMapTileLayer(20, 8, tileSize.x, tileSize.y); fillTiles(grassLayer, new GridPoint2(20, 8), grassTile); tiledMap.getLayers().add(grassLayer); - // Create lanes (invisible) + /** + * Creates lanes of invisible tiles in the TiledMap. These lanes are added as separate layers + * and are typically used for gameplay purposes. + * + * @param tiledMap The TiledMap to which the lanes should be added. + * @param tileSize The size of each tile in pixels (width and height). + * @param numberOfLanes The total number of lanes to create. + * @param mapWidth The width of the TiledMap in tiles. + * @param mapHeight The height of the TiledMap in tiles. + * @return The modified TiledMap with the added invisible lanes. + */ int numberOfLanes = 8; int laneHeight = 1; // Height of each lane in tiles int mapWidth = 20; @@ -140,6 +194,12 @@ private TiledMap createForestDemoTiles(GridPoint2 tileSize, TextureRegion grass) return tiledMap; } + /** + * Fills a TiledMapTileLayer with invisible tiles, creating a lgaayer of transparent tiles. + * + * @param layer The TiledMapTileLayer to fill with invisible tiles. + * @param mapSize The size of the layer in tiles (width and height). + */ private void fillInvisibleTiles(TiledMapTileLayer layer, GridPoint2 mapSize) { for (int x = 0; x < mapSize.x; x++) { for (int y = 0; y < mapSize.y; y++) { diff --git a/source/core/src/main/com/csse3200/game/screens/DesertGameScreen.java b/source/core/src/main/com/csse3200/game/screens/DesertGameScreen.java new file mode 100644 index 000000000..003cd6529 --- /dev/null +++ b/source/core/src/main/com/csse3200/game/screens/DesertGameScreen.java @@ -0,0 +1,208 @@ +package com.csse3200.game.screens; +import com.badlogic.gdx.graphics.Pixmap; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.ScreenAdapter; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.utils.viewport.FitViewport; +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.components.maingame.MainGameLoseDisplay; +import com.csse3200.game.entities.Entity; +import com.csse3200.game.entities.EntityService; +import com.csse3200.game.entities.factories.PlayerFactory; +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.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.UIComponent; +import com.csse3200.game.ui.terminal.Terminal; +import com.csse3200.game.ui.terminal.TerminalDisplay; +import com.csse3200.game.components.maingame.MainGameExitDisplay; +import com.csse3200.game.components.gamearea.PerformanceDisplay; +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(viewportWidth / 2, 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/GameLevelData.java b/source/core/src/main/com/csse3200/game/screens/GameLevelData.java new file mode 100644 index 000000000..f1319007f --- /dev/null +++ b/source/core/src/main/com/csse3200/game/screens/GameLevelData.java @@ -0,0 +1,28 @@ +package com.csse3200.game.screens; + +/** + * The {@code GameLevelData} class is responsible for managing the selected game level. + * It provides methods to get and set the selected game level. + */ +public class GameLevelData { + private static int selectedLevel = -1; + + /** + * Get the currently selected game level. + * + * @return The selected game level. + */ + public static int getSelectedLevel() { + return selectedLevel; + } + + /** + * Set the selected game level. + * + * @param level The new game level to be selected. + */ + public static void setSelectedLevel(int level) { + selectedLevel = level; + } + +} \ 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 new file mode 100644 index 000000000..1c74fff70 --- /dev/null +++ b/source/core/src/main/com/csse3200/game/screens/IceGameScreen.java @@ -0,0 +1,207 @@ +package com.csse3200.game.screens; +import com.badlogic.gdx.graphics.Pixmap; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.ScreenAdapter; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.utils.viewport.FitViewport; +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.components.maingame.MainGameLoseDisplay; +import com.csse3200.game.entities.Entity; +import com.csse3200.game.entities.EntityService; +import com.csse3200.game.entities.factories.PlayerFactory; +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.UIComponent; +import com.csse3200.game.ui.terminal.Terminal; +import com.csse3200.game.ui.terminal.TerminalDisplay; +import com.csse3200.game.components.maingame.MainGameExitDisplay; +import com.csse3200.game.components.gamearea.PerformanceDisplay; +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(viewportWidth / 2, 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 new file mode 100644 index 000000000..71aab443b --- /dev/null +++ b/source/core/src/main/com/csse3200/game/screens/LavaGameScreen.java @@ -0,0 +1,208 @@ +package com.csse3200.game.screens; +import com.badlogic.gdx.graphics.Pixmap; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.ScreenAdapter; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.utils.viewport.FitViewport; +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.components.maingame.MainGameLoseDisplay; +import com.csse3200.game.entities.Entity; +import com.csse3200.game.entities.EntityService; +import com.csse3200.game.entities.factories.PlayerFactory; +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.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.UIComponent; +import com.csse3200.game.ui.terminal.Terminal; +import com.csse3200.game.ui.terminal.TerminalDisplay; +import com.csse3200.game.components.maingame.MainGameExitDisplay; +import com.csse3200.game.components.gamearea.PerformanceDisplay; +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(viewportWidth / 2, 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 4403de6f5..00e7cf234 100644 --- a/source/core/src/main/com/csse3200/game/screens/LevelSelectScreen.java +++ b/source/core/src/main/com/csse3200/game/screens/LevelSelectScreen.java @@ -14,6 +14,9 @@ import com.csse3200.game.entities.factories.RenderFactory; import com.csse3200.game.rendering.Renderer; import com.csse3200.game.screens.text.AnimatedText; +import com.csse3200.game.screens.Planets; +import com.csse3200.game.services.GameEndService; +import com.csse3200.game.services.ServiceLocator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Text; @@ -25,6 +28,7 @@ public class LevelSelectScreen extends ScreenAdapter { Logger logger = LoggerFactory.getLogger(LevelSelectScreen.class); private final GdxGame game; private SpriteBatch batch; + private int selectedLevel = -1; private static final String INTRO_TEXT = "Select a Planet for Conquest"; @@ -49,6 +53,7 @@ public LevelSelectScreen(GdxGame game) { public void show() { batch = new SpriteBatch(); background = new Sprite(new Texture(BG_PATH)); + ServiceLocator.registerGameEndService(new GameEndService()); } /** @@ -95,19 +100,47 @@ private void spawnPlanetBorders() { for (int[] planet : Planets.PLANETS) { Rectangle planetRect = new Rectangle(planet[0], planet[1], planet[2], planet[3]); if (planetRect.contains(mousePos.x, (float) Gdx.graphics.getHeight() - mousePos.y)) { - // If a planet is clicked it will load the level based on the planet + // If the mouse is over a planet, draw the planet border + Sprite planetBorder = new Sprite(new Texture("planets/planetBorder.png")); + batch.draw(planetBorder, planet[0] - 2.0f, planet[1] - 2.0f, planet[2] + 3.0f, planet[3] + 3.0f); if (Gdx.input.justTouched()) { + // If the planet is clicked, load the corresponding level dispose(); logger.info("Loading level {}", planet[4]); - game.setScreen(new TurretSelectionScreen(game)); - } else { - Sprite planetBorder = new Sprite(new Texture("planets/planetBorder.png")); - batch.draw(planetBorder, planet[0] - 2.0f, planet[1] - 2.0f, planet[2] + 3.0f, planet[3] + 3.0f); + GameLevelData.setSelectedLevel(planet[4]); + 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 public void render(float delta) { 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 e3cb512b0..ab475797f 100644 --- a/source/core/src/main/com/csse3200/game/screens/MainGameScreen.java +++ b/source/core/src/main/com/csse3200/game/screens/MainGameScreen.java @@ -19,6 +19,7 @@ import com.csse3200.game.GdxGame; import com.csse3200.game.areas.ForestGameArea; import com.csse3200.game.areas.terrain.TerrainFactory; +import com.csse3200.game.components.gamearea.PerformanceDisplay; import com.csse3200.game.components.maingame.MainGameActions; import com.csse3200.game.components.maingame.MainGameLoseDisplay; import com.csse3200.game.entities.Entity;