From fccdbc3e745996e697ff767f21e27cbeb1832aa1 Mon Sep 17 00:00:00 2001 From: TheRealEmissions Date: Thu, 21 Mar 2024 03:13:00 +0000 Subject: [PATCH] Java docs --- .../student/assets/map/ActivityMapObject.java | 23 +- .../assets/map/TransitionMapObject.java | 16 + .../controllers/KeyboardController.java | 1 + .../src/uk/ac/york/student/game/GameTime.java | 121 +++++ .../ac/york/student/player/PlayerEnergy.java | 21 + .../york/student/player/PlayerHappiness.java | 21 + .../ac/york/student/player/PlayerMetric.java | 52 ++ .../ac/york/student/player/PlayerMetrics.java | 21 +- .../york/student/player/PlayerStudyLevel.java | 21 + .../ac/york/student/screens/ExitScreen.java | 1 + .../ac/york/student/screens/GameScreen.java | 487 +++++++++++++++++- 11 files changed, 753 insertions(+), 32 deletions(-) diff --git a/core/src/uk/ac/york/student/assets/map/ActivityMapObject.java b/core/src/uk/ac/york/student/assets/map/ActivityMapObject.java index 1d5dac4..bded22b 100644 --- a/core/src/uk/ac/york/student/assets/map/ActivityMapObject.java +++ b/core/src/uk/ac/york/student/assets/map/ActivityMapObject.java @@ -68,18 +68,37 @@ public float getChangeAmount(PlayerMetrics.MetricType metricType) { * @param object The MapObject to initialize the ActivityMapObject with. */ public ActivityMapObject(@NotNull MapObject object) { + // Calls the superclass constructor super(); + + // Sets the name of the ActivityMapObject to the name of the given MapObject setName(object.getName()); + + // Sets the color of the ActivityMapObject to the color of the given MapObject setColor(object.getColor()); + + // Sets the opacity of the ActivityMapObject to the opacity of the given MapObject setOpacity(object.getOpacity()); + + // Sets the visibility of the ActivityMapObject to the visibility of the given MapObject setVisible(object.isVisible()); + + // Retrieves the properties of the given MapObject and assigns them to the properties of the ActivityMapObject properties = object.getProperties(); + + // Retrieves the "activityStr" property from the properties of the ActivityMapObject and assigns it to the str field str = properties.get("activityStr", String.class); + + // Retrieves the "activityType" property from the properties of the ActivityMapObject, converts it to uppercase, and assigns it to the type field type = Activity.valueOf(properties.get("activityType", String.class).toUpperCase()); + + // Retrieves the "activityTime" property from the properties of the ActivityMapObject and assigns it to the time field time = properties.get("activityTime", Integer.class); + + // Retrieves the "changeAmount" property from the properties of the ActivityMapObject, splits it into an array of strings, converts each string to a float, and collects them into an unmodifiable list changeAmounts = Arrays.stream(properties.get("changeAmount", String.class).split(",")) - .map(Float::parseFloat) - .collect(Collectors.toUnmodifiableList()); + .map(Float::parseFloat) + .collect(Collectors.toUnmodifiableList()); } /** diff --git a/core/src/uk/ac/york/student/assets/map/TransitionMapObject.java b/core/src/uk/ac/york/student/assets/map/TransitionMapObject.java index d9069b2..aaec362 100644 --- a/core/src/uk/ac/york/student/assets/map/TransitionMapObject.java +++ b/core/src/uk/ac/york/student/assets/map/TransitionMapObject.java @@ -30,16 +30,32 @@ public class TransitionMapObject extends MapObject implements ActionMapObject { /** * Constructor for the TransitionMapObject class. * It initialises the object with the properties of the given MapObject. + * * @param object The MapObject to initialize the TransitionMapObject with. */ public TransitionMapObject(@NotNull MapObject object) { + // Calls the superclass constructor super(); + + // Sets the name of the TransitionMapObject to the name of the given MapObject setName(object.getName()); + + // Sets the color of the TransitionMapObject to the color of the given MapObject setColor(object.getColor()); + + // Sets the opacity of the TransitionMapObject to the opacity of the given MapObject setOpacity(object.getOpacity()); + + // Sets the visibility of the TransitionMapObject to the visibility of the given MapObject setVisible(object.isVisible()); + + // Retrieves the properties of the given MapObject and assigns them to the properties of the TransitionMapObject properties = object.getProperties(); + + // Retrieves the "newMap" property from the properties of the TransitionMapObject and assigns it to the type field type = properties.get("newMap", String.class); + + // Retrieves the "newMapStr" property from the properties of the TransitionMapObject and assigns it to the str field str = properties.get("newMapStr", String.class); } diff --git a/core/src/uk/ac/york/student/controllers/KeyboardController.java b/core/src/uk/ac/york/student/controllers/KeyboardController.java index 62383e3..eb7b8cf 100644 --- a/core/src/uk/ac/york/student/controllers/KeyboardController.java +++ b/core/src/uk/ac/york/student/controllers/KeyboardController.java @@ -1,4 +1,5 @@ package uk.ac.york.student.controllers; +@Deprecated(forRemoval = true) public class KeyboardController { } diff --git a/core/src/uk/ac/york/student/game/GameTime.java b/core/src/uk/ac/york/student/game/GameTime.java index 28e929b..607fcfa 100644 --- a/core/src/uk/ac/york/student/game/GameTime.java +++ b/core/src/uk/ac/york/student/game/GameTime.java @@ -6,15 +6,35 @@ import org.jetbrains.annotations.NotNull; import uk.ac.york.student.utils.DrawableUtils; +/** + * The {@link GameTime} class represents the concept of time in the game. + * It includes methods for managing the progression of time, such as incrementing the hour or the day. + * It also includes a progress bar to visually represent the progression of time. + * This class is final and cannot be subclassed. + */ @Getter public final class GameTime { + // The total number of days in the game private static final int DAYS = 7; + + // The length of a day in the game, in hours private static final int DAY_LENGTH = 16; + + // The width of the progress bar representing the progression of time private static final int WIDTH = 50; + + // The height of the progress bar representing the progression of time private static final int HEIGHT = 5; + // The ProgressBar instance used to visually represent the progression of time in the game private final ProgressBar progressBar; + /** + * Constructor for the {@link GameTime} class. + * It initializes the progress bar with the given scale. + * + * @param scale The scale factor for the progress bar's width and height. + */ public GameTime(float scale) { System.out.println(scale); final int scaledWidth = (int) (WIDTH * scale); @@ -23,75 +43,176 @@ public GameTime(float scale) { progressBar = getProgressBar(scaledWidth, scaledHeight); } + /** + * This method is used to get the length of a day in the game. + * + * @return The length of a day in the game, in hours. + */ public static int getDayLength() { return DAY_LENGTH; } + /** + * This method is used to get the total number of days in the game. + * + * @return The total number of days in the game. + */ public static int getDays() { return DAYS; } + /** + * This method is used to create a new {@link ProgressBar} instance with the given dimensions. + * The {@link ProgressBar} is styled and its initial value is set to the current hour. + * + * @param scaledWidth The width of the {@link ProgressBar}, scaled according to the game's scale factor. + * @param scaledHeight The height of the {@link ProgressBar}, scaled according to the game's scale factor. + * @return A new {@link ProgressBar} instance. + */ @NotNull private ProgressBar getProgressBar(int scaledWidth, int scaledHeight) { + // Create a new ProgressBarStyle instance ProgressBar.ProgressBarStyle style = new ProgressBar.ProgressBarStyle(); + + // Create a new ProgressBar instance with the given parameters final ProgressBar progressBar = new ProgressBar(0, DAY_LENGTH, 1, false, style); + + // Get the ProgressBar's style ProgressBar.ProgressBarStyle barStyle = progressBar.getStyle(); + + // Set the background of the ProgressBar to a gray color barStyle.background = DrawableUtils.getColouredDrawable(scaledWidth, scaledHeight, Color.GRAY); + + // Set the color of the ProgressBar before the knob to green barStyle.knobBefore = DrawableUtils.getColouredDrawable(scaledWidth, scaledHeight, Color.GREEN); + + // Set the color of the knob of the ProgressBar to green barStyle.knob = DrawableUtils.getColouredDrawable(0, scaledHeight, Color.GREEN); + // Apply the style to the ProgressBar progressBar.setStyle(barStyle); + + // Set the width and height of the ProgressBar progressBar.setWidth(scaledWidth); progressBar.setHeight(scaledHeight); + // Set the duration of the animation of the ProgressBar progressBar.setAnimateDuration(0.25f); + + // Set the initial value of the ProgressBar to the current hour progressBar.setValue(currentHour); + + // Return the configured ProgressBar instance return progressBar; } + /** + * This method is used to create a new {@link ProgressBar} instance with the given scale. + * It calls the {@link GameTime#getProgressBar(int, int)} method with the width and height scaled according to the given scale factor. + * + * @param scale The scale factor for the {@link ProgressBar}'s width and height. + * @return A new {@link ProgressBar} instance with the given scale. + */ private @NotNull ProgressBar getProgressBar(float scale) { return getProgressBar((int) (WIDTH * scale), (int) (HEIGHT * scale)); } + /** + * This method is used to update the {@link ProgressBar} instance with a new scale. + * It calls the {@link GameTime#getProgressBar(float)} method with the new scale, effectively resizing the {@link ProgressBar}. + * + * @param scale The new scale factor for the {@link ProgressBar}'s width and height. + */ public void updateProgressBar(float scale) { getProgressBar(scale); } + /** + * The current hour in the game. It ranges from 0 to {@link GameTime#DAY_LENGTH} + */ private int currentHour = 0; + /** + * This method is used to set the current hour in the game. + * It also updates the {@link ProgressBar}'s value to reflect the new current hour. + * + * @param hour The new current hour in the game. It should be within the range [0, {@link GameTime#DAY_LENGTH}]. + */ private void setCurrentHour(int hour) { currentHour = hour; progressBar.setValue(currentHour); } + /** + * This method is used to increment the current hour in the game by a given amount. + * The new current hour is the minimum of the sum of the current hour and the given amount, and the length of a day. + * This ensures that the current hour does not exceed the length of a day. + * + * @param amount The amount by which the current hour is to be incremented. + */ public void incrementHour(int amount) { setCurrentHour(Math.min(DAY_LENGTH, currentHour + amount)); } + /** + * This method is used to reset the current hour in the game to 0. + * It calls the {@link GameTime#setCurrentHour(int)} method with 0 as the argument. + */ public void resetHour() { setCurrentHour(0); } + /** + * This method is used to check if the current hour equals the length of a day. + * It returns true if the current hour is equal {@link GameTime#DAY_LENGTH}, indicating the end of the day. + * + * @return A boolean value indicating whether the current hour equals the length of a day. + */ public boolean isEndOfDay() { return currentHour == DAY_LENGTH; } + /** + * The current day in the game. It ranges from 0 to {@link GameTime#DAYS}-1 + */ private int currentDay = 0; + /** + * This method is used to increment the current day in the game by 1. + * It calls the {@link GameTime#incrementDay(int)} method with 1 as the argument, and then resets the current hour by calling the {@link GameTime#resetHour()} method. + */ public void incrementDay() { incrementDay(1); resetHour(); } + /** + * This method is used to increment the current day in the game by a given amount. + * The new current day is the minimum of the sum of the current day and the given amount, and one less than the total number of days. + * This ensures that the current day does not exceed the total number of days. + * After incrementing the day, it resets the current hour by calling the resetHour method. + * + * @param amount The amount by which the current day is to be incremented. + */ public void incrementDay(int amount) { currentDay = Math.min(DAYS - 1, currentDay + amount); resetHour(); } + /** + * This method is used to reset the current day in the game to 0. + * It sets the current day to 0 and then resets the current hour by calling the {@link GameTime#resetHour()} method. + */ public void resetDay() { currentDay = 0; resetHour(); } + /** + * This method is used to check if the current day equals {@link GameTime#DAYS}-1. + * It returns true if the current day is equal to {@link GameTime#DAYS}-1, indicating the end of the game. + * + * @return A boolean value indicating whether the current day equals {@link GameTime#DAYS}-1. + */ public boolean isEndOfDays() { return currentDay == DAYS - 1; } diff --git a/core/src/uk/ac/york/student/player/PlayerEnergy.java b/core/src/uk/ac/york/student/player/PlayerEnergy.java index cfa7966..f7d7300 100644 --- a/core/src/uk/ac/york/student/player/PlayerEnergy.java +++ b/core/src/uk/ac/york/student/player/PlayerEnergy.java @@ -42,18 +42,39 @@ public PlayerEnergy() { */ private float totalEnergy = 0f; + /** + * Returns the maximum total energy that a player can accumulate. + * This is equivalent to the number of days in the game, as represented by {@link GameTime#getDays()}. + * + * @return the maximum total energy that a player can accumulate + */ public float getMaxTotal() { return GameTime.getDays(); } + /** + * Returns the total amount of energy accumulated by the player. + * + * @return the total amount of energy accumulated by the player + */ public float getTotal() { return totalEnergy; } + /** + * Sets the total amount of energy accumulated by the player. + * + * @param total the new total amount of energy accumulated by the player + */ public void setTotal(float total) { this.totalEnergy = total; } + /** + * Increases the total amount of energy accumulated by the player by a specified amount. + * + * @param amount the amount of energy to add to the total + */ public void increaseTotal(float amount) { this.totalEnergy += amount; } diff --git a/core/src/uk/ac/york/student/player/PlayerHappiness.java b/core/src/uk/ac/york/student/player/PlayerHappiness.java index 9f4d68d..b258180 100644 --- a/core/src/uk/ac/york/student/player/PlayerHappiness.java +++ b/core/src/uk/ac/york/student/player/PlayerHappiness.java @@ -41,18 +41,39 @@ public PlayerHappiness() { */ private float totalHappiness = 0f; + /** + * Returns the maximum total happiness that a player can accumulate. + * This is equivalent to the number of days in the game, as represented by {@link GameTime#getDays()}. + * + * @return the maximum total happiness that a player can accumulate + */ public float getMaxTotal() { return GameTime.getDays(); } + /** + * Returns the total amount of happiness accumulated by the player. + * + * @return the total amount of happiness accumulated by the player + */ public float getTotal() { return totalHappiness; } + /** + * Sets the total amount of happiness accumulated by the player. + * + * @param total the new total amount of happiness accumulated by the player + */ public void setTotal(float total) { this.totalHappiness = total; } + /** + * Increases the total amount of happiness accumulated by the player by a specified amount. + * + * @param amount the amount of happiness to add to the total + */ public void increaseTotal(float amount) { this.totalHappiness += amount; } diff --git a/core/src/uk/ac/york/student/player/PlayerMetric.java b/core/src/uk/ac/york/student/player/PlayerMetric.java index e1a8087..3122bac 100644 --- a/core/src/uk/ac/york/student/player/PlayerMetric.java +++ b/core/src/uk/ac/york/student/player/PlayerMetric.java @@ -32,15 +32,67 @@ public interface PlayerMetric { */ String getLabel(); + /** + * Returns the current value of the player metric. + * + * @return the current value of the player metric + */ float get(); + + /** + * Sets the current value of the player metric. + * + * @param value the new value of the player metric + */ void set(float value); + + /** + * Increases the current value of the player metric by a specified amount. + * + * @param amount the amount to add to the current value of the player metric + */ void increase(float amount); + + /** + * Decreases the current value of the player metric by a specified amount. + * + * @param amount the amount to subtract from the current value of the player metric + */ void decrease(float amount); + + /** + * Returns the default value of the player metric. + * + * @return the default value of the player metric + */ float getDefault(); + /** + * Sets the total accumulated value of the player metric. + * + * @param total the new total accumulated value of the player metric + */ void setTotal(float total); + + /** + * Increases the total accumulated value of the player metric by a specified amount. + * + * @param amount the amount to add to the total accumulated value of the player metric + */ void increaseTotal(float amount); + + /** + * Returns the total accumulated value of the player metric. + * + * @return the total accumulated value of the player metric + */ float getTotal(); + + /** + * Returns the maximum total accumulated value that a player can achieve. + * + * @return the maximum total accumulated value that a player can achieve + */ float getMaxTotal(); /** diff --git a/core/src/uk/ac/york/student/player/PlayerMetrics.java b/core/src/uk/ac/york/student/player/PlayerMetrics.java index 0aff838..ad5daab 100644 --- a/core/src/uk/ac/york/student/player/PlayerMetrics.java +++ b/core/src/uk/ac/york/student/player/PlayerMetrics.java @@ -51,8 +51,17 @@ public enum MetricEffect { */ private final PlayerStudyLevel studyLevel = new PlayerStudyLevel(); - public void changeMetric(@NotNull MetricType type, MetricEffect effect, float changeAmount) { + /** + * Changes the specified player metric based on the given effect and change amount. + * + * @param type The type of the player metric to change. This should be one of the values from the {@link MetricType} enum. + * @param effect The effect to apply to the player metric. This should be one of the values from the {@link MetricEffect} enum. + * @param changeAmount The amount by which to change the player metric. This is used when the effect is either {@link MetricEffect#INCREASE} or {@link MetricEffect#DECREASE}. + * @throws IllegalArgumentException If an invalid metric type or effect is provided. + */ + public void changeMetric(@NotNull MetricType type, MetricEffect effect, float changeAmount) throws IllegalArgumentException { PlayerMetric metric; + // Determine the metric to change based on the provided type switch (type) { case ENERGY: metric = energy; @@ -67,6 +76,7 @@ public void changeMetric(@NotNull MetricType type, MetricEffect effect, float ch throw new IllegalArgumentException("Invalid metric type: " + type); } + // Apply the specified effect to the determined metric switch (effect) { case INCREASE: metric.increase(changeAmount); @@ -82,7 +92,14 @@ public void changeMetric(@NotNull MetricType type, MetricEffect effect, float ch } } - public PlayerMetric getMetric(@NotNull MetricType type) { + /** + * Returns the player metric of the specified type. + * + * @param type The type of the player metric to return. This should be one of the values from the {@link MetricType} enum. + * @return The player metric of the specified type. + * @throws IllegalArgumentException If an invalid metric type is provided. + */ + public PlayerMetric getMetric(@NotNull MetricType type) throws IllegalArgumentException { switch (type) { case ENERGY: return energy; diff --git a/core/src/uk/ac/york/student/player/PlayerStudyLevel.java b/core/src/uk/ac/york/student/player/PlayerStudyLevel.java index eff332f..4cf3d28 100644 --- a/core/src/uk/ac/york/student/player/PlayerStudyLevel.java +++ b/core/src/uk/ac/york/student/player/PlayerStudyLevel.java @@ -43,18 +43,39 @@ public PlayerStudyLevel() { */ private float totalStudy = 0f; + /** + * Returns the maximum total study that a player can accumulate. + * This is equivalent to the number of days in the game, as represented by {@link GameTime#getDays()}. + * + * @return the maximum total study that a player can accumulate + */ public float getMaxTotal() { return GameTime.getDays(); } + /** + * Returns the total amount of study accumulated by the player. + * + * @return the total amount of study accumulated by the player + */ public float getTotal() { return totalStudy; } + /** + * Sets the total amount of study accumulated by the player. + * + * @param total the new total amount of study accumulated by the player + */ public void setTotal(float total) { this.totalStudy = total; } + /** + * Increases the total amount of study accumulated by the player by a specified amount. + * + * @param amount the amount of study to add to the total + */ public void increaseTotal(float amount) { this.totalStudy += amount; } diff --git a/core/src/uk/ac/york/student/screens/ExitScreen.java b/core/src/uk/ac/york/student/screens/ExitScreen.java index 02d7c1c..ae1b193 100644 --- a/core/src/uk/ac/york/student/screens/ExitScreen.java +++ b/core/src/uk/ac/york/student/screens/ExitScreen.java @@ -7,6 +7,7 @@ import uk.ac.york.student.GdxGame; import uk.ac.york.student.assets.fonts.FontManager; +@Deprecated(forRemoval = true) public class ExitScreen extends BaseScreen { @Getter private final Stage processor; diff --git a/core/src/uk/ac/york/student/screens/GameScreen.java b/core/src/uk/ac/york/student/screens/GameScreen.java index 51ccf5e..d29d9d7 100644 --- a/core/src/uk/ac/york/student/screens/GameScreen.java +++ b/core/src/uk/ac/york/student/screens/GameScreen.java @@ -36,6 +36,7 @@ import uk.ac.york.student.player.Player; import uk.ac.york.student.player.PlayerMetric; import uk.ac.york.student.player.PlayerMetrics; +import uk.ac.york.student.utils.MapOfSuppliers; import uk.ac.york.student.utils.Pair; import uk.ac.york.student.utils.StreamUtils; @@ -44,38 +45,109 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; +/** + * The {@link GameScreen} class extends the {@link BaseScreen} class and implements the {@link InputProcessor} interface. + * This class is responsible for handling the game screen and its related functionalities. + * It includes methods for rendering the game screen, handling user inputs, managing game activities, and more. + */ public class GameScreen extends BaseScreen implements InputProcessor { + /** + * The key code for the action key. This is used to trigger actions in the game. + */ private static final int ACTION_KEY = Input.Keys.E; + + /** + * The stage for this game screen. This is where all the actors for the game are added. + */ @Getter private final Stage processor; + + /** + * The player of the game. This is the main character that the user controls. + */ private final Player player; + + /** + * The game time. This keeps track of the current time in the game. + */ private final GameTime gameTime; + + /** + * The map for the game. This is loaded from the {@link MapManager} with {@link MapManager#getMaps()} then {@link MapOfSuppliers#getResult(Object)}. + */ private TiledMap map = MapManager.getMaps().getResult("map"); + + /** + * The scale of the map. This is used to adjust the size of the map to fit the screen. + */ private float mapScale; + + /** + * The renderer for the map. This is used to draw the map on the screen. + */ private TiledMapRenderer renderer; + + /** + * The skin for the game. This is used to style the game's UI elements. + */ private final Skin craftacularSkin = SkinManager.getSkins().getResult(Skins.CRAFTACULAR); + + /** + * The table for the action UI. This is where the action label is added. + */ private final Table actionTable = new Table(craftacularSkin); + + /** + * The table for the metrics UI. This is where the metrics labels and progress bars are added. + */ private final Table metricsTable = new Table(); + + /** + * The table for the time UI. This is where the time label and progress bar are added. + */ private final Table timeTable = new Table(); + + /** + * The label for the action UI. This displays the current action that the player can perform. + */ private final Label actionLabel = new Label("ENG1 Project. Super cool. (You will never see this)", craftacularSkin); + + /** + * The label for the time UI. This displays the current time in the game. + */ private final Label timeLabel = new Label("You exist outside of the space-time continuum.", craftacularSkin); + /** + * Constructor for the {@link GameScreen} class. + * + * @param game The {@link GdxGame} instance that this screen is part of. + */ public GameScreen(GdxGame game) { super(game); // Set up the tilemap - // Cannot extract into a method because class variables are set as final + // Note: cannot extract into a method because class variables are set as final + //#region Load Tilemap + // Get the first layer of the map TiledMapTileLayer layer = (TiledMapTileLayer) map.getLayers().get(0); + // Get the width and height of a tile int tileWidth = layer.getTileWidth(); int tileHeight = layer.getTileHeight(); + // Calculate the scale of the map based on the screen size and tile size mapScale = Math.max(Gdx.graphics.getWidth() / (layer.getWidth() * tileWidth), Gdx.graphics.getHeight() / (layer.getHeight() * tileHeight)); + // Initialize the game time gameTime = new GameTime(mapScale); + // Initialize the map renderer renderer = new OrthogonalTiledMapRenderer(map, mapScale); //#endregion + // Initialize the starting point of the player Vector2 startingPoint = new Vector2(25, 25); + // Get the layer of the map that contains game objects MapLayer gameObjectsLayer = map.getLayers().get("gameObjects"); + // Get all objects in the game objects layer MapObjects objects = gameObjectsLayer.getObjects(); + // Iterate over all objects to find the starting point for (MapObject object : objects) { if (!object.getName().equals("startingPoint")) continue; MapProperties properties = object.getProperties(); @@ -84,17 +156,20 @@ public GameScreen(GdxGame game) { if (spawnpoint == null || Boolean.FALSE.equals(spawnpoint)) continue; RectangleMapObject rectangleObject = (RectangleMapObject) object; Rectangle rectangle = rectangleObject.getRectangle(); + // Update the starting point based on the found object startingPoint = new Vector2(rectangle.getX() * mapScale, rectangle.getY() * mapScale); break; } - + // Initialize the player at the starting point player = new Player(map, startingPoint); + // Initialize the stage and set it as the input processor processor = new Stage(new ScreenViewport()); renderer.setView((OrthographicCamera) processor.getCamera()); Gdx.input.setInputProcessor(processor); + // Add a listener to the stage to handle key events processor.addListener(new InputListener() { @Override public boolean keyDown(InputEvent event, int keycode) { @@ -108,23 +183,39 @@ public boolean keyUp(InputEvent event, int keycode) { }); } + /** + * Changes the current map to a new map specified by the mapName parameter. + * The screen fades out to black, then the new map is loaded and the screen fades back in. + * + * @param mapName The name of the new map to load. + */ public void changeMap(String mapName) { // make the screen black slowly processor.getRoot().getColor().a = 1; SequenceAction sequenceAction = new SequenceAction(); sequenceAction.addAction(Actions.fadeOut(0.5f)); sequenceAction.addAction(Actions.run(() -> { + // Dispose of the current map map.dispose(); + // Load the new map map = MapManager.getMaps().getResult(mapName); + // Get the first layer of the new map TiledMapTileLayer layer = (TiledMapTileLayer) map.getLayers().get(0); + // Get the width and height of a tile in the new map int tileWidth = layer.getTileWidth(); int tileHeight = layer.getTileHeight(); + // Calculate the scale of the new map based on the screen size and tile size mapScale = Math.max(Gdx.graphics.getWidth() / (layer.getWidth() * tileWidth), Gdx.graphics.getHeight() / (layer.getHeight() * tileHeight)); + // Initialize the map renderer for the new map renderer = new OrthogonalTiledMapRenderer(map, mapScale); + // Initialize the starting point of the player for the new map Vector2 startingPoint = new Vector2(25, 25); + // Get the layer of the new map that contains game objects MapLayer gameObjectsLayer = map.getLayers().get("gameObjects"); + // Get all objects in the game objects layer MapObjects objects = gameObjectsLayer.getObjects(); + // Iterate over all objects to find the starting point for (MapObject object : objects) { if (!object.getName().equals("startingPoint")) continue; MapProperties properties = object.getProperties(); @@ -133,31 +224,48 @@ public void changeMap(String mapName) { if (spawnpoint == null || Boolean.FALSE.equals(spawnpoint)) continue; RectangleMapObject rectangleObject = (RectangleMapObject) object; Rectangle rectangle = rectangleObject.getRectangle(); + // Update the starting point based on the found object startingPoint = new Vector2(rectangle.getX() * mapScale, rectangle.getY() * mapScale); break; } + // Set the new map and starting point for the player player.setMap(map, startingPoint); + // Update the game time progress bar for the new map gameTime.updateProgressBar(mapScale); + // Set the view of the map renderer to the camera of the stage renderer.setView((OrthographicCamera) processor.getCamera()); + // Set the input processor to the stage Gdx.input.setInputProcessor(processor); })); + // Fade the screen back in sequenceAction.addAction(Actions.fadeIn(0.5f)); + // Add the sequence action to the root of the stage processor.getRoot().addAction(sequenceAction); } + /** + * This method is called when this screen becomes the current screen for the {@link GdxGame}. + * It sets up the game UI, including the action table, metrics table, and time table. + * It also updates the viewport of the stage. + */ @Override public void show() { + // Get the width and height of the screen float width = Gdx.graphics.getWidth(); float height = Gdx.graphics.getHeight(); + // Get the batch for the stage and start it Batch batch = processor.getBatch(); batch.begin(); + // Draw the player on the batch player.draw(batch, 1f); + // End the batch batch.end(); + // Set up the action table actionTable.setFillParent(true); processor.addActor(actionTable); actionLabel.setVisible(false); @@ -165,6 +273,7 @@ public void show() { actionTable.bottom(); actionTable.padBottom(10); + // Set up the metrics table metricsTable.setFillParent(true); metricsTable.setWidth(500); processor.addActor(metricsTable); @@ -182,6 +291,7 @@ public void show() { metricsTable.padBottom(10); metricsTable.padRight(20); + // Set up the time table ProgressBar timeBar = gameTime.getProgressBar(); String currentHour = getCurrentHourString(); String currentDay = "Day " + (gameTime.getCurrentDay() + 1); @@ -196,49 +306,84 @@ public void show() { timeTable.top(); timeTable.padTop(10); - + // Update the viewport of the stage processor.getViewport().update((int) width, (int) height); - } + /** + * This method returns a string representation of the current hour in the game. + * The game starts at 8 AM and ends at 12 AM (midnight). The time is formatted as HH:MM AM/PM. + * However, MM is always 00 because the game progresses in hourly increments. + * If the game is at the end of the day, the method returns "00:00 - Time to sleep!". + * + * @return A string representing the current hour in the game. + */ @NotNull private String getCurrentHourString() { - int currentHourNum = gameTime.getCurrentHour(); - final int startHour = 8; - final int midday = 12 - startHour; - boolean isAm = currentHourNum < (12 - startHour); - String currentHour; - if (!gameTime.isEndOfDay()) { + int currentHourNum = gameTime.getCurrentHour(); // Get the current hour number from the game time + final int startHour = 8; // Define the start hour of the game + final int midday = 12 - startHour; // Calculate the hour number for midday + boolean isAm = currentHourNum < (12 - startHour); // Determine if the current time is AM + String currentHour; // Initialize the string to hold the current hour + if (!gameTime.isEndOfDay()) { // If it's not the end of the day + // Calculate the current hour based on whether it's AM or PM currentHour = String.valueOf(isAm || currentHourNum == midday ? currentHourNum + startHour : currentHourNum - (12 - startHour)); // 9am start - if (currentHour.length() == 1) currentHour = "0" + currentHour; - currentHour += ":00"; - if (isAm) { - currentHour += " AM"; - } else { - currentHour += " PM"; + if (currentHour.length() == 1) currentHour = "0" + currentHour; // Add a leading zero if the hour is a single digit + currentHour += ":00"; // Add the minutes (always 00) + if (isAm) { // If it's AM + currentHour += " AM"; // Add " AM" to the current hour + } else { // If it's PM + currentHour += " PM"; // Add " PM" to the current hour } - } else { - currentHour = "00:00 - Time to sleep!"; + } else { // If it's the end of the day + currentHour = "00:00 - Time to sleep!"; // Set the current hour to "00:00 - Time to sleep!" } - return currentHour; + return currentHour; // Return the current hour } + /** + * An {@link AtomicReference} to an {@link ActionMapObject}. This object represents the current action that the player can perform. + * It is nullable, meaning it can be null if there is no current action. + * {@link AtomicReference} is used to ensure thread-safety when accessing and updating this variable. + */ private final AtomicReference<@Nullable ActionMapObject> currentActionMapObject = new AtomicReference<>(null); - + /** + * This method is called every frame to render the game screen. + * It clears the screen, updates the player's position, sets the opacity of the player and map layers, + * calculates and sets the camera's position, updates the positions of the UI tables, renders the map, + * draws the player, updates the action label, and updates and draws the stage. + * + * @param v The time in seconds since the last frame. + */ @Override public void render(float v) { + // Set the blend function for the OpenGL context. This determines how new pixels are combined with existing pixels. Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA); + + // Clear the screen. This wipes out all previous drawings and sets the screen to a blank state. Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + // Set the active texture unit to texture unit 0. This is the default and most commonly used texture unit. Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0); + + // Set the clear color to black. This is the color that the screen is cleared to when glClear is called. Gdx.gl.glClearColor(0, 0, 0, 1); + // Move the player. This updates the player's position based on their current velocity and the elapsed time since the last frame. player.move(); + + // Set the opacity of the player. This determines how transparent the player is. A value of 1 means fully opaque, and a value of 0 means fully transparent. player.setOpacity(processor.getRoot().getColor().a); + // Set the opacity of all layers in the map. This determines how transparent the layers are. A value of 1 means fully opaque, and a value of 0 means fully transparent. StreamUtils.parallelFromIterator(map.getLayers().iterator()).forEach(l -> l.setOpacity(processor.getRoot().getColor().a)); + // Get the first layer of the map. This is typically the background layer. TiledMapTileLayer layer = (TiledMapTileLayer) map.getLayers().get(0); + + // Get the camera for the stage. This determines what part of the game world is visible on the screen. OrthographicCamera camera = (OrthographicCamera) processor.getCamera(); + // Calculate the player's position (center of the player's sprite) float playerCenterX = player.getX() + player.getWidth() / 2; float playerCenterY = player.getY() + player.getHeight() / 2; @@ -252,66 +397,131 @@ public void render(float v) { // Set the camera's position to the player's position, but constrained within the minimum and maximum x and y coordinates camera.position.set(Math.min(Math.max(playerCenterX, cameraMinX), cameraMaxX), Math.min(Math.max(playerCenterY, cameraMinY), cameraMaxY), 0); camera.update(); + + // Set the positions of the action, metrics, and time tables. These are UI elements that display information to the player. actionTable.setPosition(camera.position.x - camera.viewportWidth / 2, camera.position.y - camera.viewportHeight / 2); metricsTable.setPosition(camera.position.x + camera.viewportWidth / 2 - metricsTable.getWidth(), camera.position.y - camera.viewportHeight / 2); timeTable.setPosition(camera.position.x - camera.viewportWidth / 2, camera.position.y + camera.viewportHeight / 2 - timeTable.getHeight()); + // Set the view of the map renderer to the camera. This determines what part of the map is drawn to the screen. renderer.setView(camera); + + // Render the map. This draws the map to the screen. renderer.render(); + // Get the batch for the stage. This is used to draw the player and other game objects. Batch batch = processor.getBatch(); batch.begin(); + // Draw the player. This renders the player sprite to the screen. player.draw(batch, processor.getRoot().getColor().a); batch.end(); + // Check if the player is in a transition tile. If they are, update the action label to reflect the possible action. Player.Transition transitionTile = player.isInTransitionTile(); if (transitionTile != null) { setActionLabel(transitionTile); } else { + // If the player is not in a transition tile, hide the action label. currentActionMapObject.set(null); actionLabel.setVisible(false); } + // Draw the stage. This renders all actors added to the stage, including the player and UI elements. processor.draw(); + + // Update the stage. This updates the state of all actors added to the stage, including the player and UI elements. processor.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f)); } + /** + * This method sets the action label based on the player's current transition tile. + * It first gets the {@link ActionMapObject} associated with the transition tile and the player's current map object. + * Then it constructs the action text based on the type of the {@link ActionMapObject}. + * If the {@link ActionMapObject} is an {@link ActivityMapObject}, it checks if the player has enough time and resources to perform the activity. + * If the player does not have enough time or resources, the action text is updated to reflect this. + * Finally, the action text is set as the text of the action label, and the action label is made visible. + * + * @param transitionTile The player's current transition tile. + */ private void setActionLabel(Player.Transition transitionTile) { + // Get the ActionMapObject associated with the transition tile and the player's current map object ActionMapObject actionMapObject = getActionMapObject(transitionTile, player.getCurrentMapObject()); currentActionMapObject.set(actionMapObject); + + // Construct the action text based on the type of the ActionMapObject StringBuilder actionText = new StringBuilder(getActionText(actionMapObject)); + + // Check if the ActionMapObject is an instance of ActivityMapObject if (actionMapObject instanceof ActivityMapObject) { + // Cast the ActionMapObject to an ActivityMapObject ActivityMapObject activityMapObject = (ActivityMapObject) actionMapObject; + + // Get the required time for the activity int requiredTime = activityMapObject.getTime(); + + // Get the type of the activity Activity activity = activityMapObject.getType(); + + // Get a list of negative effects from the activity's effects + // Negative effects are those that decrease a player metric List> negativeEffects = activity.getEffects() .stream().filter(x -> x.getRight().equals(PlayerMetrics.MetricEffect.DECREASE)) .collect(Collectors.toList()); + + // Initialize a boolean to track if the player has enough resources for the activity boolean hasEnough = true; + + // Initialize a list to store the names of the metrics that the player does not have enough of List negativeEffectNames = new ArrayList<>(); + + // Iterate over the negative effects for (Pair negativeEffect : negativeEffects) { + // Get the type of the metric PlayerMetrics.MetricType metricType = negativeEffect.getLeft(); + + // Get the amount by which the activity changes the metric float changeAmount = activityMapObject.getChangeAmount(metricType); + + // Get the current value of the metric for the player PlayerMetric metric = player.getMetrics().getMetric(metricType); float currentMetric = metric.get(); + + // Check if the player has enough of the metric for the activity boolean tempEnough = currentMetric >= changeAmount; + + // Update the hasEnough boolean if the player does not have enough of the metric if (hasEnough) { hasEnough = tempEnough; } + + // If the player does not have enough of the metric, add the metric's label to the list of negative effect names if (!tempEnough) { negativeEffectNames.add(metric.getLabel()); } } + + // Check if the player does not have enough time or resources to perform the activity + // If it's the end of the day and the activity is not sleeping, set the action text to "Night owl, it's time to sleep!" if (gameTime.isEndOfDay() && !activity.equals(Activity.SLEEP)) { actionText = new StringBuilder("Night owl, it's time to sleep!"); - } else if (gameTime.getCurrentHour() + requiredTime > GameTime.getDayLength() && !activity.equals(Activity.SLEEP)) { + } + // If the current hour plus the required time for the activity is greater than the length of the day and the activity is not sleeping, + // set the action text to "You don't have enough time to do this activity." + else if (gameTime.getCurrentHour() + requiredTime > GameTime.getDayLength() && !activity.equals(Activity.SLEEP)) { actionText = new StringBuilder("You don't have enough time to do this activity."); - } else if (!negativeEffects.isEmpty() && !hasEnough && !activity.equals(Activity.SLEEP)) { + } + // If there are negative effects and the player does not have enough resources and the activity is not sleeping, + // set the action text to "You don't have enough [resource] to do this activity." + else if (!negativeEffects.isEmpty() && !hasEnough && !activity.equals(Activity.SLEEP)) { actionText = new StringBuilder("You don't have enough "); + // If there is only one resource the player does not have enough of, append the name of that resource to the action text if (negativeEffectNames.size() == 1) { actionText.append(negativeEffectNames.get(0)); - } else { + } + // If there are multiple resources the player does not have enough of, append each resource name to the action text, + // separated by commas and an "and" before the last resource + else { for (int i = 0; i < negativeEffectNames.size(); i++) { actionText.append(negativeEffectNames.get(i)); if (i == negativeEffectNames.size() - 2) { @@ -323,27 +533,54 @@ private void setActionLabel(Player.Transition transitionTile) { actionText.append(" to do this activity."); } } else { - if (!activity.equals(Activity.SLEEP)) actionText.append(" (").append(requiredTime).append(" hours)"); - else { - if (gameTime.getCurrentDay() + 1 == GameTime.getDays()) { + // If the player has enough resources and time to perform the activity + if (!activity.equals(Activity.SLEEP)) { + // If the activity is not sleeping, append the required time for the activity to the action text + actionText.append(" (").append(requiredTime).append(" hours)"); + } else { + // If the activity is sleeping + if (gameTime.isEndOfDays()) { + // If it's the last day of the game, append "End of the game!" to the action text actionText.append(" (End of the game!)"); } else { + // If it's not the last day of the game, append "End of the day" to the action text actionText.append(" (End of the day)"); } } } } + + // Set the action text as the text of the action label, and make the action label visible actionLabel.setText(actionText.toString()); actionLabel.setVisible(true); } + /** + * This method constructs a string that represents the action text for a given {@link ActionMapObject}. + * The action text is a string that instructs the player to press a certain key to perform an action. + * The action is determined by the string representation of the {@link ActionMapObject}. + * + * @param actionMapObject The {@link ActionMapObject} for which to construct the action text. + * @return A {@link String} representing the action text for the given {@link ActionMapObject}. + */ @NotNull - private String getActionText(ActionMapObject actionMapObject) { + private String getActionText(@NotNull ActionMapObject actionMapObject) { String actionText = "Press " + Input.Keys.toString(ACTION_KEY) + " to "; actionText += actionMapObject.getStr(); return actionText; } + /** + * This method returns an {@link ActionMapObject} based on the player's current transition tile and the associated map object. + * If the transition tile is an {@link Player.Transition#ACTIVITY}, it returns an {@link ActivityMapObject}. + * If the transition tile is a {@link Player.Transition#NEW_MAP}, it returns a {@link TransitionMapObject}. + * If the transition tile is neither an {@link Player.Transition#ACTIVITY} nor a {@link Player.Transition#NEW_MAP}, it throws an {@link IllegalStateException}. + * + * @param transitionTile The player's current transition tile. + * @param tileObject The map object associated with the transition tile. + * @return An {@link ActionMapObject} based on the transition tile and map object. + * @throws IllegalStateException If the transition tile is neither an {@link Player.Transition#ACTIVITY} nor a {@link Player.Transition#NEW_MAP}. + */ @NotNull private static ActionMapObject getActionMapObject(Player.@NotNull Transition transitionTile, MapObject tileObject) { ActionMapObject actionMapObject; @@ -357,18 +594,34 @@ private static ActionMapObject getActionMapObject(Player.@NotNull Transition tra return actionMapObject; } + /** + * This method is called when the screen size changes. It resizes the game screen to fit the new screen size. + * It recalculates the scale of the map based on the new screen size and tile size, and initializes the map renderer with the new map scale. + * It also updates the viewport of the stage with the new screen width and height, and sets the camera's position to the player's position, + * but constrained within the minimum and maximum x and y coordinates. Finally, it sets the view of the map renderer to the camera. + * + * @param screenWidth The new width of the screen. + * @param screenHeight The new height of the screen. + */ @Override public void resize(int screenWidth, int screenHeight) { + // Get the first layer of the map TiledMapTileLayer layer = (TiledMapTileLayer) map.getLayers().get(0); + // Get the width and height of a tile in the map int tileWidth = layer.getTileWidth(); int tileHeight = layer.getTileHeight(); + // Calculate the scale of the map based on the screen size and tile size mapScale = Math.max(Gdx.graphics.getWidth() / (float)(layer.getWidth() * tileWidth), Gdx.graphics.getHeight() / (float)(layer.getHeight() * tileHeight)); + // Initialize the map renderer with the new map scale renderer = new OrthogonalTiledMapRenderer(map, mapScale); + // Get the camera for the stage OrthographicCamera camera = (OrthographicCamera) processor.getCamera(); + // Set the viewport width and height of the camera to the screen width and height camera.viewportWidth = screenWidth; camera.viewportHeight = screenHeight; + // Update the viewport of the stage with the new screen width and height processor.getViewport().update(screenWidth, screenHeight, true); // Calculate the player's position (center of the player's sprite) @@ -383,28 +636,47 @@ public void resize(int screenWidth, int screenHeight) { // Set the camera's position to the player's position, but constrained within the minimum and maximum x and y coordinates camera.position.set(Math.min(Math.max(playerCenterX, cameraMinX), cameraMaxX), Math.min(Math.max(playerCenterY, cameraMinY), cameraMaxY), 0); + // Update the camera camera.update(); + // Set the view of the map renderer to the camera renderer.setView(camera); + // Update the viewport of the stage with the new screen width and height processor.getViewport().update(screenWidth, screenHeight, true); } + /** + * This method is called when the game is paused. + * Currently, it does not perform any actions when the game is paused. + */ @Override public void pause() { } + /** + * This method is called when the game is resumed from a paused state. + * Currently, it does not perform any actions when the game is resumed. + */ @Override public void resume() { } + /** + * This method is called when the game screen is hidden or minimized. + * Currently, it does not perform any actions when the game screen is hidden. + */ @Override public void hide() { } + /** + * This method is called when the game screen is being disposed of. + * It disposes of the {@link GameScreen#map}, {@link GameScreen#processor}, {@link GameScreen#craftacularSkin}, and {@link GameScreen#player} to free up resources and prevent memory leaks. + */ @Override public void dispose() { map.dispose(); @@ -413,6 +685,20 @@ public void dispose() { player.dispose(); } + /** + * This method is called when a key is pressed down. + * It first checks if the key pressed is the action key (defined as a constant). + * If it is, it retrieves the current {@link ActionMapObject} (which represents the current action that the player can perform). + * If the {@link ActionMapObject} is not null, it checks if it is an instance of {@link ActivityMapObject} or {@link TransitionMapObject}. + * If it's an {@link ActivityMapObject}, it calls the {@link GameScreen#doActivity(ActivityMapObject)} method and returns its result. + * If it's a {@link TransitionMapObject}, it calls the {@link GameScreen#doMapChange(TransitionMapObject)} method and returns its result. + * If the {@link ActionMapObject} is neither an {@link ActivityMapObject} nor a {@link TransitionMapObject}, it throws an {@link IllegalStateException}. + * If the key pressed is not the action key, it calls the {@link Player#keyDown(int)} method of the {@link Player} and returns its result. + * + * @param keycode The key code of the key that was pressed down. + * @return A boolean indicating whether the key press was handled. + * @throws IllegalStateException If the {@link ActionMapObject} is neither an {@link ActivityMapObject} nor a {@link TransitionMapObject}. + */ @Override public boolean keyDown(int keycode) { boolean playerKeyDown = player.keyDown(keycode); @@ -431,93 +717,238 @@ public boolean keyDown(int keycode) { return playerKeyDown; } + /** + * This method is used to change the current map to a new map. + * The new map is specified by the type of the provided {@link TransitionMapObject}. + * After changing the map, it returns true to indicate that the map change was successful. + * + * @param actionMapObject The {@link TransitionMapObject} that contains the type of the new map. + * @return A boolean indicating whether the map change was successful. + */ private boolean doMapChange(@NotNull TransitionMapObject actionMapObject) { changeMap(actionMapObject.getType()); return true; } + /** + * This method is used to perform an activity in the game. + * The activity is specified by the provided {@link ActivityMapObject}. + * It first checks if the game is at the end of the day and if the activity is not sleeping, if so it returns false. + * Then it checks if the current hour plus the required time for the activity is greater than the length of the day and if the activity is not sleeping, if so it returns false. + * It then checks if the player has enough resources to perform the activity, if not it returns false. + * If all checks pass, it performs the activity by changing the player's metrics based on the effects of the activity. + * If the activity is sleeping, it resets the game time to the start of the next day. + * Finally, it updates the time label with the current day and hour, and returns true to indicate that the activity was performed successfully. + * + * @param actionMapObject The {@link ActivityMapObject} that represents the activity to be performed. + * @return A boolean indicating whether the activity was performed successfully. + */ private boolean doActivity(@NotNull ActivityMapObject actionMapObject) { + // Get the type of the activity from the ActivityMapObject Activity type = actionMapObject.getType(); + + // Check if the game is at the end of the day and if the activity is not sleeping + // If it is, return false to indicate that the activity cannot be performed if (gameTime.isEndOfDay() && !type.equals(Activity.SLEEP)) return false; + + // Get the required time for the activity from the ActivityMapObject int requiredTime = actionMapObject.getTime(); + + // Check if the current hour plus the required time for the activity is greater than the length of the day + // and if the activity is not sleeping + // If it is, return false to indicate that the activity cannot be performed if (gameTime.getCurrentHour() + requiredTime > GameTime.getDayLength() && !type.equals(Activity.SLEEP)) return false; + + // Get the effects of the activity from the ActivityMapObject + // These effects represent how the activity will change the player's metrics List> effects = type.getEffects(); + + // Filter the effects to get only the negative effects + // Negative effects are those that decrease a player metric List> negativeEffects = effects.stream().filter(x -> x.getRight().equals(PlayerMetrics.MetricEffect.DECREASE)).collect(Collectors.toList()); + + // Get the player's current metrics PlayerMetrics metrics = player.getMetrics(); + // Check if there are any negative effects from the activity if (!negativeEffects.isEmpty()) { + // Initialize a boolean to track if the player has enough resources for the activity boolean hasEnough = true; + + // Iterate over the negative effects for (Pair negativeEffect : negativeEffects) { + // Get the type of the metric PlayerMetrics.MetricType metricType = negativeEffect.getLeft(); + + // Get the amount by which the activity changes the metric float changeAmount = actionMapObject.getChangeAmount(metricType); + + // Get the current value of the metric for the player PlayerMetric metric = metrics.getMetric(metricType); float currentMetric = metric.get(); + + // Check if the player has enough of the metric for the activity hasEnough = currentMetric >= changeAmount; + + // If the player does not have enough of the metric, break the loop if (!hasEnough) break; } + + // If the player does not have enough resources to perform the activity, return false if (!hasEnough) return false; } + // Iterate over the effects of the activity for (Pair effect : effects) { + // Get the type of the metric from the effect PlayerMetrics.MetricType metricType = effect.getLeft(); + // Get the effect on the metric (increase or decrease) PlayerMetrics.MetricEffect metricEffect = effect.getRight(); + // Get the amount by which the activity changes the metric float changeAmount = actionMapObject.getChangeAmount(metricType); + // Apply the effect to the metric metrics.changeMetric(metricType, metricEffect, changeAmount); } + // Check if the activity is sleeping if (type.equals(Activity.SLEEP)) { + // Get all player metrics List allMetrics = metrics.getMetrics(); + // Iterate over all player metrics for (PlayerMetric m : allMetrics) { + // Increase the total of each metric by its current value m.increaseTotal(m.get()); } - if (gameTime.getCurrentDay() + 1 == GameTime.getDays()) { + // Check if the current day plus one equals the total number of days + if (gameTime.isEndOfDays()) { + // If it does, transition the screen to the end screen and return true game.transitionScreen(Screens.END, player); return true; } else { + // If it doesn't, increment the current day gameTime.incrementDay(); } } else { + // If the activity is not sleeping, increment the current hour by the required time for the activity gameTime.incrementHour(requiredTime); } + // Get the current hour as a string using the getCurrentHourString method String currentHour = getCurrentHourString(); + + // Construct a string representing the current day by adding 1 to the current day from gameTime String currentDay = "Day " + (gameTime.getCurrentDay() + 1); + + // Construct a string representing the current time by concatenating the current day and current hour String time = currentDay + " " + currentHour; + + // Set the text of the timeLabel to the constructed time string timeLabel.setText(time); + + // Return true indicating the operation was successful return true; } + /** + * This method is called when a key is released. + * It delegates the key release event to the player object. + * + * @param keycode The key code of the key that was released. + * @return A boolean indicating whether the key release was handled by the player. + */ @Override public boolean keyUp(int keycode) { return player.keyUp(keycode); } + /** + * This method is called when a key is typed. + * Currently, it does not perform any actions when a key is typed. + * + * @param character The character of the key that was typed. + * @return A boolean indicating whether the key typing was handled. Always returns false. + */ @Override public boolean keyTyped(char character) { return false; } + /** + * This method is called when a touch down event occurs. + * Currently, it does not perform any actions when a touch down event occurs. + * + * @param screenX The x-coordinate of the touch down event. + * @param screenY The y-coordinate of the touch down event. + * @param pointer The pointer for the touch down event. + * @param button The button for the touch down event. + * @return A boolean indicating whether the touch down event was handled. Always returns false. + */ @Override public boolean touchDown(int screenX, int screenY, int pointer, int button) { return false; } + /** + * This method is called when a touch up event occurs. + * Currently, it does not perform any actions when a touch up event occurs. + * + * @param screenX The x-coordinate of the touch up event. + * @param screenY The y-coordinate of the touch up event. + * @param pointer The pointer for the touch up event. + * @param button The button for the touch up event. + * @return A boolean indicating whether the touch up event was handled. Always returns false. + */ @Override public boolean touchUp(int screenX, int screenY, int pointer, int button) { return false; } + /** + * This method is called when a touch cancelled event occurs. + * Currently, it does not perform any actions when a touch cancelled event occurs. + * + * @param screenX The x-coordinate of the touch cancelled event. + * @param screenY The y-coordinate of the touch cancelled event. + * @param pointer The pointer for the touch cancelled event. + * @param button The button for the touch cancelled event. + * @return A boolean indicating whether the touch cancelled event was handled. Always returns false. + */ @Override public boolean touchCancelled(int screenX, int screenY, int pointer, int button) { return false; } + /** + * This method is called when a touch dragged event occurs. + * Currently, it does not perform any actions when a touch dragged event occurs. + * + * @param screenX The x-coordinate of the touch dragged event. + * @param screenY The y-coordinate of the touch dragged event. + * @param pointer The pointer for the touch dragged event. + * @return A boolean indicating whether the touch dragged event was handled. Always returns false. + */ @Override public boolean touchDragged(int screenX, int screenY, int pointer) { return false; } + /** + * This method is called when a mouse moved event occurs. + * Currently, it does not perform any actions when a mouse moved event occurs. + * + * @param screenX The x-coordinate of the mouse moved event. + * @param screenY The y-coordinate of the mouse moved event. + * @return A boolean indicating whether the mouse moved event was handled. Always returns false. + */ @Override public boolean mouseMoved(int screenX, int screenY) { return false; } + /** + * This method is called when a scrolled event occurs. + * Currently, it does not perform any actions when a scrolled event occurs. + * + * @param amountX The amount of horizontal scroll. + * @param amountY The amount of vertical scroll. + * @return A boolean indicating whether the scrolled event was handled. Always returns false. + */ @Override public boolean scrolled(float amountX, float amountY) { return false;