diff --git a/source/core/src/main/com/csse3200/game/GdxGame.java b/source/core/src/main/com/csse3200/game/GdxGame.java index e349821ee..77917b431 100644 --- a/source/core/src/main/com/csse3200/game/GdxGame.java +++ b/source/core/src/main/com/csse3200/game/GdxGame.java @@ -77,6 +77,8 @@ private Screen newScreen(ScreenType screenType) { return new SpaceMapScreen(this); case EXTRACTOR_GAME: return new ExtractorMiniGameScreen(this); + case NAVIGATION_SCREEN: + return new SpaceNavigationScreen(this); default: return null; } @@ -84,7 +86,7 @@ private Screen newScreen(ScreenType screenType) { public enum ScreenType { - MAIN_MENU, MAIN_GAME, SETTINGS, TITLE_SCREEN,SPACE_MAP ,EXTRACTOR_GAME, GAME_STORY + MAIN_MENU, MAIN_GAME, SETTINGS, TITLE_SCREEN,SPACE_MAP ,EXTRACTOR_GAME, GAME_STORY, NAVIGATION_SCREEN } diff --git a/source/core/src/main/com/csse3200/game/areas/NavigationArea.java b/source/core/src/main/com/csse3200/game/areas/NavigationArea.java deleted file mode 100644 index 729c1675a..000000000 --- a/source/core/src/main/com/csse3200/game/areas/NavigationArea.java +++ /dev/null @@ -1,121 +0,0 @@ -package com.csse3200.game.areas; - -import com.badlogic.gdx.Game; -import com.badlogic.gdx.Gdx; -import com.csse3200.game.GdxGame; -import com.csse3200.game.areas.terrain.TerrainFactory; -import com.csse3200.game.components.gamearea.GameAreaDisplay; -import com.csse3200.game.components.navigation.NavigationPlanetComponent; -import com.csse3200.game.entities.Entity; -import com.csse3200.game.services.PlanetTravel; -import com.csse3200.game.services.ResourceService; -import com.csse3200.game.services.ServiceLocator; - -/** - * A GameArea that displays all the possible planets the player can travel to and - * allows for the selection of which planet to go to next. - */ -public class NavigationArea extends GameArea{ - - // Textures to be loaded - private static final String[] spaceMapTextures = { - "images/heart.png" - }; - - // The game this area is in - private final GdxGame game; - - // The Factory to generate the new areas terrain - private final TerrainFactory terrainFactory; - - // Handler of the transition point between planets - private final PlanetTravel planetTravel; - - /** - * Constructor for the Navigation Game Area - * @param game Game its being played on - * @param terrainFactory The terrain factor used to generate the next planet area. - */ - public NavigationArea(GdxGame game, TerrainFactory terrainFactory) { - this.game = game; - this.terrainFactory = terrainFactory; - this.planetTravel = new PlanetTravel(game); - } - - /** - * Creates the NavigationArea buttons and assets - */ - @Override - public void create() { - loadAssets(); - displayUI(); - createNavigationPlanets(); - } - - /** - * Disposes of the NavigationArea - */ - @Override - public void dispose() { - super.dispose(); - unloadAssets(); - } - - /** - * Display the UI GameArea - */ - private void displayUI() { - Entity ui = new Entity(); - ui.addComponent(new GameAreaDisplay("Space Map")); - spawnEntity(ui); - } - - /** - * Create all the planet button options - */ - private void createNavigationPlanets() { - createPlanetUI("Level 1", 100, 100); - createPlanetUI("Level 2", 300, 100); - createPlanetUI("Level 3", 500, 100); - createPlanetUI("Level 4", 700, 100); - - } - - /** - * Create a single planet button - * @param planetName The name of the planet - * @param x The x-coord of the button - * @param y The y-coord of the button - */ - private void createPlanetUI(String planetName, int x, int y) { - Entity planet = new Entity().addComponent(new NavigationPlanetComponent( - "images/heart.png", x, y, planetName)); - planet.getEvents().addListener("Navigate" + planetName, () -> - navigateToArea(new EarthGameArea(terrainFactory, game))); - spawnEntity(planet); - } - - /** - * Transition from current NavigationArea to the new area - * @param nextArea Next area to transition to. - */ - private void navigateToArea(GameArea nextArea) { - this.dispose(); - nextArea.create(); - } - - /** - * Load all required assets - */ - private void loadAssets() { - ServiceLocator.getResourceService().loadTextures(spaceMapTextures); - } - - /** - * Unload the assets used - */ - private void unloadAssets() { - ServiceLocator.getResourceService().unloadAssets(spaceMapTextures); - } - -} diff --git a/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuActions.java b/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuActions.java index f0b8420c5..b35c9f2f7 100644 --- a/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuActions.java +++ b/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuActions.java @@ -93,9 +93,8 @@ private void onExtractor(){ } private void onSpaceMap() { - logger.info("Launching Space Map in Screen"); - game.setScreen(GdxGame.ScreenType.MAIN_GAME); - ((MainGameScreen)game.getScreen()).loadSpaceMap(); + logger.info("Launching space map screen"); + game.setScreen(GdxGame.ScreenType.NAVIGATION_SCREEN); } } diff --git a/source/core/src/main/com/csse3200/game/components/navigation/NavigationPlanetComponent.java b/source/core/src/main/com/csse3200/game/components/navigation/NavigationPlanetComponent.java deleted file mode 100644 index bab0561da..000000000 --- a/source/core/src/main/com/csse3200/game/components/navigation/NavigationPlanetComponent.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.csse3200.game.components.navigation; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.Button; -import com.badlogic.gdx.scenes.scene2d.ui.Image; -import com.badlogic.gdx.scenes.scene2d.ui.Label; -import com.badlogic.gdx.scenes.scene2d.ui.Table; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.badlogic.gdx.utils.Align; -import com.csse3200.game.services.ServiceLocator; -import com.csse3200.game.ui.UIComponent; - -/** - * The `PlanetComponent` class represents a navigational component in the game, allowing players - * to interact with and navigate to different game areas represented as planets. - */ -public class NavigationPlanetComponent extends UIComponent { - - // The path to the planet image - private final String PlanetImage; - - // The x and y coords - private final float x; - private final float y; - - // Table of UI elements - private Table table; - - // The name of the planet - private final String name; - - /** - * Constructs a `PlanetComponent` instance with the specified planet image and coordinates. - * - * @param PlanetImage The path to the image representing the planet. - * @param x The x-coordinate of the planet's position. - * @param y The y-coordinate of the planet's position. - */ - public NavigationPlanetComponent(String PlanetImage, float x, float y, String name) { - this.PlanetImage = PlanetImage; - this.x = x; - this.y = y; - this.name = name; - } - - /** - * Creates the planet UI component, including the planet image and navigation button. - * Sets up event listeners for navigation triggers. - */ - @Override - public void create() { - super.create(); - - // Create and configure the UI elements - table = new Table(); - Image planetImage = new Image(ServiceLocator.getResourceService().getAsset(PlanetImage, Texture.class)); - Label label = new Label(name, skin, "large"); - Button button = new Button(label, skin); - - // Add a listener to the navigation button - button.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent changeEvent, Actor actor) { - // Trigger navigation event when the button is clicked - entity.getEvents().trigger("Navigate"+name); - } - }); - - // Configure the layout of UI elements within the table - table.add(planetImage).align(Align.top).size(100f); - table.row(); - table.add(button); - - // Set the position and size of the table - table.setPosition(x, y); - table.setSize(20, 20); - - // Add the table to the stage for rendering - stage.addActor(table); - } - - /** - * Draws the UI component. This method is intentionally left empty as the drawing - * is handled by the LibGDX scene2d framework. - * - * @param batch The sprite batch used for rendering. - */ - @Override - protected void draw(SpriteBatch batch) { - // Drawing is managed by the LibGDX scene2d framework - } - - /** - * Disposes of resources used by the `PlanetComponent`. Clears the internal table - * and performs the parent class disposal. Removes the table from the stage. - */ - @Override - public void dispose() { - // Clear and remove the table from the stage - table.clear(); - super.dispose(); - table.remove(); - } -} \ No newline at end of file diff --git a/source/core/src/main/com/csse3200/game/components/navigation/PlanetComponent.java b/source/core/src/main/com/csse3200/game/components/navigation/PlanetComponent.java deleted file mode 100644 index 7e460e853..000000000 --- a/source/core/src/main/com/csse3200/game/components/navigation/PlanetComponent.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.csse3200.game.components.navigation; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.Button; -import com.badlogic.gdx.scenes.scene2d.ui.Image; -import com.badlogic.gdx.scenes.scene2d.ui.Label; -import com.badlogic.gdx.scenes.scene2d.ui.Table; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.badlogic.gdx.utils.Align; -import com.csse3200.game.services.ServiceLocator; -import com.csse3200.game.ui.UIComponent; - -/** - * The PlanetComponent class represents a UI component that displays a planet image, - * along with a button for navigation to a different level. - */ -public class PlanetComponent extends UIComponent { - - // The path to the planet image - private final String PlanetImage; - - // The x and y coords - private final float x; - private final float y; - - // Table of UI elements - private Table table; - - /** - * Constructs a new PlanetComponentt instance. - * - * @param PlanetImage The path to the planet image. - * @param x The x-coordinate for the position of the planet component. - * @param y The y-coordinate for the position of the planet component. - */ - public PlanetComponent(String PlanetImage, float x, float y) { - this.PlanetImage=PlanetImage; - this.x=x; - this.y=y; - } - - /** - * Creates the UI elements for the planet component. - */ - @Override - public void create() { - super.create(); - table=new Table(); - Image planetImage = new Image(ServiceLocator.getResourceService().getAsset(PlanetImage, Texture.class)); - Label label=new Label("Level 2 ",skin,"large"); - Button button=new Button(label,skin); - button.addListener( - new ChangeListener() { - @Override - public void changed(ChangeEvent changeEvent, Actor actor) { - - entity.getEvents().trigger("Navigatee"); - } - }); - - table.add(planetImage).align(Align.top).size(100f); - table.row(); - table.add(button); - table.setPosition(x,y); - table.setSize(20,20); - stage.addActor(table); - } - - /** - * Draws the planet component (not implemented in this class). - * - * @param batch The SpriteBatch to use for drawing. - */ - @Override - protected void draw(SpriteBatch batch) { - - } - - /** - * Disposes of resources and clears the table. - */ - @Override - public void dispose() { - table.clear(); - super.dispose(); - table.remove(); - } -} - diff --git a/source/core/src/main/com/csse3200/game/components/navigation/level3.java b/source/core/src/main/com/csse3200/game/components/navigation/level3.java deleted file mode 100644 index 4b5dd263b..000000000 --- a/source/core/src/main/com/csse3200/game/components/navigation/level3.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.csse3200.game.components.navigation; - -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.Button; -import com.badlogic.gdx.scenes.scene2d.ui.Image; -import com.badlogic.gdx.scenes.scene2d.ui.Label; -import com.badlogic.gdx.scenes.scene2d.ui.Table; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.badlogic.gdx.utils.Align; -import com.csse3200.game.services.ServiceLocator; -import com.csse3200.game.ui.UIComponent; - -/** - * The {@code level3} class represents a specialized UI component used to display and interact with - * level 3 in the game. It extends {@code UIComponent} and provides functionality for creating and - * managing the UI elements associated with level 3. - * - *

This class includes methods for creating the UI components, handling user interactions, and - * disposing of resources when no longer needed. - */ -public class level3 extends UIComponent { - private final String PlanetImage; - private final float x; - private final float y; - private Table table; - - /** - * Constructs a new {@code level3} instance with the specified planet image path, x and y - * coordinates. - * - * @param PlanetImage The path to the image representing the planet. - * @param x The x-coordinate position of the UI component. - * @param y The y-coordinate position of the UI component. - */ - public level3(String PlanetImage, float x, float y) { - this.PlanetImage = PlanetImage; - this.x = x; - this.y = y; - } - - /** - * Creates the UI components for level 3, including the planet image, label, and button for - * interaction. This method sets up the layout and positioning of these components on the screen. - */ - @Override - public void create() { - super.create(); - table = new Table(); - Image planetImage = new Image(ServiceLocator.getResourceService().getAsset(PlanetImage, Texture.class)); - Label label = new Label("Level 3 ", skin, "large"); - Button button = new Button(label, skin); - button.addListener( - new ChangeListener() { - @Override - public void changed(ChangeEvent changeEvent, Actor actor) { - entity.getEvents().trigger("Navigateee"); - } - }); - - table.add(planetImage).align(Align.top).size(100f); - table.row(); - table.add(button); - table.setPosition(x, y); - table.setSize(20, 20); - stage.addActor(table); - } - - /** - * This method is responsible for drawing UI elements but is currently empty as there is no - * custom drawing logic. - * - * @param batch The SpriteBatch used for rendering. - */ - @Override - protected void draw(SpriteBatch batch) { - // Currently no custom drawing logic. - } - - /** - * Disposes of the resources associated with this UI component. This includes clearing the table - * and removing it from the stage. - */ - @Override - public void dispose() { - table.clear(); - super.dispose(); - table.remove(); - } -} diff --git a/source/core/src/main/com/csse3200/game/components/navigation/level4.java b/source/core/src/main/com/csse3200/game/components/navigation/level4.java deleted file mode 100644 index c601c1601..000000000 --- a/source/core/src/main/com/csse3200/game/components/navigation/level4.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.csse3200.game.components.navigation; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.Button; -import com.badlogic.gdx.scenes.scene2d.ui.Image; -import com.badlogic.gdx.scenes.scene2d.ui.Label; -import com.badlogic.gdx.scenes.scene2d.ui.Table; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.badlogic.gdx.utils.Align; -import com.csse3200.game.services.ServiceLocator; -import com.csse3200.game.ui.UIComponent; - -/** - * The level4 class represents a UI component for Level 4 in a game's navigation system. - * It displays a planet image and a button for navigation to a different level. - */ -public class level4 extends UIComponent { - - // The path to the planet image - private final String PlanetImage; - - // The x and y coords - private final float x; - private final float y; - - // Table of UI elements - private Table table; - - /** - * Constructs a new level4 instance. - * - * @param PlanetImage The path to the planet image. - * @param x The x-coordinate for the position of the planet component. - * @param y The y-coordinate for the position of the planet component. - */ - public level4(String PlanetImage,float x,float y) { - this.PlanetImage=PlanetImage; - this.x=x; - this.y=y; - } - - /** - * Creates the UI elements for Level 4 component. - */ - @Override - public void create() { - super.create(); - table=new Table(); - Image planetImage = new Image(ServiceLocator.getResourceService().getAsset(PlanetImage, Texture.class)); - Label label=new Label("Level 4 ",skin,"large"); - Button button=new Button(label,skin); - button.addListener( - new ChangeListener() { - @Override - public void changed(ChangeEvent changeEvent, Actor actor) { - - entity.getEvents().trigger("Navigateeee"); - } - }); - - table.add(planetImage).align(Align.top).size(100f); - table.row(); - table.add(button); - table.setPosition(x,y); - table.setSize(20,20); - stage.addActor(table); - } - - /** - * Draws the Level 4 component (not implemented in this class). - * - * @param batch The SpriteBatch to use for drawing. - */ - @Override - protected void draw(SpriteBatch batch) { - - } - - /** - * Disposes of resources and clears the table. - */ - @Override - public void dispose() { - table.clear(); - super.dispose(); - table.remove(); - } -} - - - diff --git a/source/core/src/main/com/csse3200/game/components/spacenavigation/NavigationBackground.java b/source/core/src/main/com/csse3200/game/components/spacenavigation/NavigationBackground.java new file mode 100644 index 000000000..ef429769b --- /dev/null +++ b/source/core/src/main/com/csse3200/game/components/spacenavigation/NavigationBackground.java @@ -0,0 +1,100 @@ +package com.csse3200.game.components.spacenavigation; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Animation; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.graphics.g2d.Batch; + +public class NavigationBackground extends Actor { + /** + * The texture for the space background of the navigation screen. + */ + private Texture spaceBackground; + + /** + * Array of animations for individual star sprites. + */ + private Animation[] animations; + + /** + * Array of positions for individual star sprites. + */ + private Vector2[] spritePositions; + + /** + * The number of star sprites in the background. + */ + private int numOfSprites = 150; + + /** + * Array to store the time passed for each sprite's animation. + */ + private float[] stateTimes; // Time passed for each sprite's animation + + /** + * Constructs a new NavigationBackground instance. + * Loads necessary textures and initializes the star animations and positions. + */ + public NavigationBackground() { + spaceBackground = new Texture(Gdx.files.internal("images/space_navigation_background.png")); + + int numOfFrames = 8; + TextureRegion[] frames = new TextureRegion[numOfFrames]; + + for (int i = 0; i < numOfFrames; i++) { + frames[i] = new TextureRegion(new Texture(Gdx.files.internal("images/space_navigation_background_star_frame_" + i + ".png"))); + } + + animations = new Animation[numOfSprites]; + spritePositions = new Vector2[numOfSprites]; + stateTimes = new float[numOfSprites]; + + for (int i = 0; i < numOfSprites; i++) { + animations[i] = new Animation<>(0.1f, frames); + animations[i].setPlayMode(Animation.PlayMode.LOOP_PINGPONG); // Ping pong effect + + // No stars in the centre third + int x = MathUtils.random(0, Gdx.graphics.getWidth()); + while (x > Gdx.graphics.getWidth() / 3 && x < 2 * (Gdx.graphics.getWidth() / 3)) { + x = MathUtils.random(0, Gdx.graphics.getWidth()); + } + spritePositions[i] = new Vector2(x, MathUtils.random(0, Gdx.graphics.getHeight())); + stateTimes[i] = MathUtils.random(0f, 1f); // Offset animation start times + } + } + + /** + * Called when the actor should perform its action. + * Updates the state times for star animations. + * + * @param delta The time in seconds since the last frame. + */ + @Override + public void act(float delta) { + super.act(delta); + + for (int i = 0; i < numOfSprites; i++) { + stateTimes[i] += delta; + } + } + + /** + * Called when the actor should be drawn. + * Draws the black background and the animated star sprites. + * + * @param batch The batch to draw with. + * @param parentAlpha The parent alpha value. + */ + @Override + public void draw(Batch batch, float parentAlpha) { + batch.draw(spaceBackground, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + for (int i = 0; i < numOfSprites; i++) { + TextureRegion currentFrame = animations[i].getKeyFrame(stateTimes[i]); + batch.draw(currentFrame, spritePositions[i].x, spritePositions[i].y); + } + } +} 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 3bb186c30..e4e4edcc0 100644 --- a/source/core/src/main/com/csse3200/game/screens/MainGameScreen.java +++ b/source/core/src/main/com/csse3200/game/screens/MainGameScreen.java @@ -5,9 +5,7 @@ import com.badlogic.gdx.scenes.scene2d.Stage; import com.csse3200.game.GdxGame; import com.csse3200.game.areas.EarthGameArea; -import com.csse3200.game.areas.ForestGameArea; import com.csse3200.game.areas.GameArea; -import com.csse3200.game.areas.NavigationArea; import com.csse3200.game.areas.terrain.TerrainFactory; import com.csse3200.game.components.maingame.MainGameActions; import com.csse3200.game.entities.Entity; @@ -90,15 +88,6 @@ public MainGameScreen(GdxGame game) { } - /** - * Loads the space map game area onto the screen to allow transitions to new planets (GameAreas) - */ - public void loadSpaceMap(){ - gameArea.dispose(); - NavigationArea navArea = new NavigationArea(game, terrainFactory); - navArea.create(); - } - @Override public void render(float delta) { physicsEngine.update(); diff --git a/source/core/src/main/com/csse3200/game/screens/SpaceNavigationScreen.java b/source/core/src/main/com/csse3200/game/screens/SpaceNavigationScreen.java new file mode 100644 index 000000000..6fb6ad2b0 --- /dev/null +++ b/source/core/src/main/com/csse3200/game/screens/SpaceNavigationScreen.java @@ -0,0 +1,306 @@ +package com.csse3200.game.screens; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Screen; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.*; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.utils.Align; +import com.badlogic.gdx.utils.Scaling; +import com.badlogic.gdx.utils.viewport.ScreenViewport; +import com.csse3200.game.GdxGame; +import com.csse3200.game.components.spacenavigation.NavigationBackground; + +/** + * Represents the navigation screen for the game, allowing the user to navigate + * between various planets and options. + */ +public class SpaceNavigationScreen implements Screen { + /** Reference to the main game instance */ + private final GdxGame game; + /** Stage where all actors will be drawn */ + private Stage stage; + /** Skin for the UI elements */ + private Skin skin; + /** Texture for the title of this screen */ + private Texture navigationTitle; + /** Textures for the planets shown on the screen */ + private final Texture[] planetTextures = new Texture[9]; + /** Textures for the arrows on the screen */ + private final Texture[] arrowTextures = new Texture[4]; + /** Names of the planets */ + private final String[] planetNames = {"Verdant Haven", "Chronos", "Rusterra", "Pyroterra", "Crimsona", "Novara", "Pyralis", "Luminae", "Aquelar"}; + + /** + * Constructs a new SpaceNavigationScreen with a reference to the main game. + * @param game The main game instance. + */ + public SpaceNavigationScreen(GdxGame game) { + this.game = game; + } + + /** + * Invoked when this screen becomes the current screen. + */ + @Override + public void show() { + // First load textures + navigationTitle = new Texture(Gdx.files.internal("images/space_navigation_title.png")); + + // Planet icons from: + // https://www.freepik.com/premium-vector/pixel-planets-set-pixel-art-solar-system_36179935.htm + for(var i = 0; i < planetTextures.length; i++){ + planetTextures[i] = new Texture(Gdx.files.internal("images/space_navigation_planet_" + i + ".png")); + } + + arrowTextures[0] = new Texture(Gdx.files.internal("images/space_navigation_arrow_left.png")); + arrowTextures[1] = new Texture(Gdx.files.internal("images/space_navigation_arrow_right.png")); + arrowTextures[2] = new Texture(Gdx.files.internal("images/space_navigation_arrow_up.png")); + arrowTextures[3] = new Texture(Gdx.files.internal("images/space_navigation_arrow_down.png")); + + + // Initialise a stage for the scene + stage = new Stage(new ScreenViewport()); + + // Animated background + NavigationBackground animatedBackground = new NavigationBackground(); + stage.addActor(animatedBackground); + + // Create Back button + skin = new Skin(Gdx.files.internal("flat-earth/skin/flat-earth-ui.json")); + + TextButton button = new TextButton("Main Menu", skin); + button.setPosition(Gdx.graphics.getWidth() - (button.getWidth() + 20), + Gdx.graphics.getHeight() - (button.getHeight() + 20) ); + + button.addListener(new ClickListener() { + @Override + public void clicked(com.badlogic.gdx.scenes.scene2d.InputEvent event, float x, float y) { + game.setScreen(GdxGame.ScreenType.MAIN_MENU); + } + }); + + stage.addActor(button); + + // Add title + Image navigationTitleImage = new Image(navigationTitle); + navigationTitleImage.setOrigin(navigationTitleImage.getImageWidth()/2, navigationTitleImage.getImageHeight()/2); + navigationTitleImage.setScaling(Scaling.fit); + + Table titleTable = new Table(); + titleTable.top().padTop(10); + titleTable.setFillParent(true); + titleTable.add(navigationTitleImage).width((float) Gdx.graphics.getWidth() / 4).align(Align.top).padTop(30); + + stage.addActor(titleTable); + + // Add planets + spawnPlanets(stage); + + // register input processor + Gdx.input.setInputProcessor(stage); + } + + /** + * Spawns planets on the stage, arranging them in a predefined grid pattern. + * @param stage The stage on which to add planets. + */ + private void spawnPlanets(Stage stage) { + int numCols = 5; + int planetSize = (Gdx.graphics.getHeight() / 2) / numCols; + int arrowSize = (Gdx.graphics.getHeight() / 3) / numCols; + int arrowPadding = 20; + + // Create the table of planets + Table table = new Table(); + table.setFillParent(true); // Make it fill the screen + table.bottom(); // Align the table to the bottom and center it + table.padBottom(planetSize); // Add padding + + // LibGDX's Scene2D ui framework is imperative, so we have to explicitly define the planet grid: + // Row 1 + table.add(createPlanetTable(0, planetSize)); + table.add(createArrow("right")).pad(arrowPadding).width(arrowSize).height(arrowSize); + table.add(createPlanetTable(1, planetSize)); + table.add(createArrow("right")).pad(arrowPadding).width(arrowSize).height(arrowSize); + table.add(createPlanetTable(2, planetSize)); + + // Row 2: down arrow row + table.row(); + table.add().width(planetSize*4).height(planetSize).colspan(4); + Image rowTwoArrow = createArrow("down"); + table.add(rowTwoArrow).width(arrowSize).height(arrowSize); + + // Row 3 + table.row(); + table.add(createPlanetTable(3, planetSize)); + table.add(createArrow("left")).pad(arrowPadding).width(arrowSize).height(arrowSize); + table.add(createPlanetTable(4, planetSize)); + table.add(createArrow("left")).pad(arrowPadding).width(arrowSize).height(arrowSize); + table.add(createPlanetTable(5, planetSize)); + + // Row 4: down arrow row + table.row(); + Image rowFourArrow = createArrow("down"); + table.add(rowFourArrow).width(arrowSize).height(arrowSize); + table.add().width(planetSize*4).height(planetSize).colspan(4); + + // Row 5 + table.row(); + table.add(createPlanetTable(6, planetSize)); + table.add(createArrow("right")).pad(arrowPadding).width(arrowSize).height(arrowSize); + table.add(createPlanetTable(7, planetSize)); + table.add(createArrow("right")).pad(arrowPadding).width(arrowSize).height(arrowSize); + table.add(createPlanetTable(8, planetSize)); + + // Add the populated table to the Scene2D stage + stage.addActor(table); + } + + /** + * Creates an arrow image pointing in the specified direction. + * @param direction The direction in which the arrow should point. + * @return An Image instance of the arrow. + */ + private Image createArrow(String direction) { + Texture arrowTexture = switch (direction) { + case "left" -> arrowTextures[0]; + case "right" -> arrowTextures[1]; + case "up" -> arrowTextures[2]; + case "down" -> arrowTextures[3]; + default -> arrowTextures[1]; // Default to right arrow + }; + + return new Image(arrowTexture); + } + + /** + * Creates a label with the given text. + * @param text Text to display on the label. + * @return A new Label instance. + */ + private Label createLabel(String text) { + Label.LabelStyle labelStyle = new Label.LabelStyle(); + labelStyle.font = skin.getFont("thick_white"); + return new Label(text, labelStyle); + } + + /** + * Creates a table for a specific planet which includes its image and name. + * @param planetIndex Index of the planet in the planetTextures array. + * @param planetSize Size for displaying the planet image. + * @return A new Table instance containing the planet image and its name. + */ + private Table createPlanetTable(int planetIndex, int planetSize) { + Table planetTable = new Table(); + planetTable.top(); + + Image planetImage = createPlanet(planetIndex); + planetTable.add(planetImage).width(planetSize).height(planetSize).expand().fill().row(); + + planetTable.add(createLabel(planetNames[planetIndex])).padTop(5); + + return planetTable; + } + + /** + * Creates an image of a planet. + * @param planetIndex Index of the planet in the planetTextures array. + * @return A new Image instance for the planet. + */ + private Image createPlanet(int planetIndex) { + Texture planetTexture = planetTextures[planetIndex]; + Image planet = new Image(planetTexture); + + // Add planet event listeners + planet.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + // Currently there is only one planet/map. + // For now, clicking any planet will take users to the one available map. + // When new maps are made, they should b integrated here. + game.setScreen(GdxGame.ScreenType.MAIN_GAME); + } + + @Override + public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) { + planet.setScale(1.1f); // scale up by 10% on hover + } + + @Override + public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) { + planet.setScale(1f); // scale back to original size + } + }); + + return planet; + } + + /** + * Renders the screen. + * @param delta The time in seconds since the last render. + */ + @Override + public void render(float delta) { + Gdx.gl.glClearColor(0, 0, 0, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + stage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f)); + stage.draw(); + } + + /** + * Resizes the viewport dimensions based on the given width and height. + * @param width The new width. + * @param height The new height. + */ + @Override + public void resize(int width, int height) { + stage.getViewport().update(width, height, true); + } + + /** + * Method called when the game is paused. Currently empty to prevent pausing on the space map. + */ + @Override + public void pause() { + // Blank to prevent pausing on the space map + } + + /** + * Method called when the game is resumed after pausing. Currently empty as there is no pausing on the space map. + */ + @Override + public void resume() { + // Left blank as there is no pausing on the space map + } + + /** + * Method called when this screen is no longer the current screen for the game. + * Currently left blank to avoid any unwanted behavior. + */ + @Override + public void hide() { + // Left blank as unwanted behaviour + } + + /** + * Frees up resources used by this screen. + */ + @Override + public void dispose() { + stage.dispose(); + skin.dispose(); + navigationTitle.dispose(); + for(Texture texture : planetTextures){ + texture.dispose(); + } + for(Texture texture : arrowTextures){ + texture.dispose(); + } + } +} \ No newline at end of file