diff --git a/src/main/java/uk/mgrove/ac/soton/comp1206/component/GameBlock.java b/src/main/java/uk/mgrove/ac/soton/comp1206/component/GameBlock.java index 4b347d7..a04a20b 100644 --- a/src/main/java/uk/mgrove/ac/soton/comp1206/component/GameBlock.java +++ b/src/main/java/uk/mgrove/ac/soton/comp1206/component/GameBlock.java @@ -207,7 +207,6 @@ public class GameBlock extends Canvas { public void setFocussed(boolean value) { logger.info("Block at x: {}, y: {} has been set to focus: {}", getX(), getY(), value); isFocussed = value; - // TODO: add/remove overlay paint(); } @@ -228,19 +227,17 @@ public class GameBlock extends Canvas { logger.info("Fading out block at x: {}, y: {}", getX(), getY()); AnimationTimer timer = new AnimationTimer() { - Color color = COLOURS[getValue()]; - int iterations = 0; + private Color color = COLOURS[getValue()]; + private int iterations = 0; @Override public void handle(long now) { if (iterations < 12) { color = color.deriveColor(0,1,1.2,1); paintColor(color); - logger.info("New color brightness is {}", color.getBrightness()); if (isFocussed) paintFocusOverlay(); } else if (color.getOpacity() > 0.1) { color = color.deriveColor(0,1,1,0.95); paintColor(color); - logger.info("New color opacity is {}", color.getOpacity()); if (isFocussed) paintFocusOverlay(); } else { paintEmpty(); diff --git a/src/main/java/uk/mgrove/ac/soton/comp1206/component/ScoresList.java b/src/main/java/uk/mgrove/ac/soton/comp1206/component/ScoresList.java new file mode 100644 index 0000000..42634cc --- /dev/null +++ b/src/main/java/uk/mgrove/ac/soton/comp1206/component/ScoresList.java @@ -0,0 +1,71 @@ +package uk.mgrove.ac.soton.comp1206.component; + +import javafx.animation.FadeTransition; +import javafx.beans.property.SimpleListProperty; +import javafx.collections.FXCollections; +import javafx.collections.ListChangeListener; +import javafx.collections.ObservableList; +import javafx.scene.layout.HBox; +import javafx.scene.layout.VBox; +import javafx.scene.text.Text; +import javafx.util.Duration; +import javafx.util.Pair; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * Class for displaying list of scores and associated users + */ +public class ScoresList extends VBox { + + /** + * Logger + */ + private static final Logger logger = LogManager.getLogger(ScoresList.class); + + /** + * Scores + */ + private final SimpleListProperty> scores; + + /** + * Initialise the scores list + */ + public ScoresList() { + logger.info("Building scores list"); + + ObservableList> observableScoresList = FXCollections.observableArrayList(); + scores = new SimpleListProperty<>(observableScoresList); + + setOpacity(0); + + scores.addListener((ListChangeListener>) change -> { + logger.info("Detected change in scores list: {}", change); + getChildren().clear(); + for (var pair : scores.get()) { + var score = new HBox(); + score.getChildren().addAll(new Text(pair.getKey()), new Text(pair.getValue().toString())); + getChildren().add(score); + } + }); + } + + /** + * Bind scores to external property + * @param scores external property to bind to + */ + public void bindScores(SimpleListProperty> scores) { + this.scores.bindBidirectional(scores); + } + + /** + * Reveal the scores + */ + public void reveal() { + logger.info("Revealing scores"); + FadeTransition fadeInTransition = new FadeTransition(Duration.millis(1000), this); + fadeInTransition.setToValue(1); + fadeInTransition.play(); + } + +} diff --git a/src/main/java/uk/mgrove/ac/soton/comp1206/event/GameLoopListener.java b/src/main/java/uk/mgrove/ac/soton/comp1206/event/GameLoopListener.java new file mode 100644 index 0000000..ab1e931 --- /dev/null +++ b/src/main/java/uk/mgrove/ac/soton/comp1206/event/GameLoopListener.java @@ -0,0 +1,14 @@ +package uk.mgrove.ac.soton.comp1206.event; + +/** + * Listener for game loop being scheduled + */ +public interface GameLoopListener { + + /** + * Process the game loop being scheduled + * @param timerDelay delay until game loop is executed + */ + public void process(int timerDelay); + +} diff --git a/src/main/java/uk/mgrove/ac/soton/comp1206/event/LineClearedListener.java b/src/main/java/uk/mgrove/ac/soton/comp1206/event/LineClearedListener.java index 66be8e5..aee632d 100644 --- a/src/main/java/uk/mgrove/ac/soton/comp1206/event/LineClearedListener.java +++ b/src/main/java/uk/mgrove/ac/soton/comp1206/event/LineClearedListener.java @@ -4,8 +4,15 @@ import uk.mgrove.ac.soton.comp1206.component.GameBlockCoordinate; import java.util.Set; +/** + * Listener for lines being cleared on the game board + */ public interface LineClearedListener { + /** + * Process the line(s) being cleared + * @param blockCoordinates coordinates of the blocks being cleared + */ public void clearLine(Set blockCoordinates); } diff --git a/src/main/java/uk/mgrove/ac/soton/comp1206/event/ShowScoresSceneListener.java b/src/main/java/uk/mgrove/ac/soton/comp1206/event/ShowScoresSceneListener.java new file mode 100644 index 0000000..d77c7a8 --- /dev/null +++ b/src/main/java/uk/mgrove/ac/soton/comp1206/event/ShowScoresSceneListener.java @@ -0,0 +1,15 @@ +package uk.mgrove.ac.soton.comp1206.event; + +import uk.mgrove.ac.soton.comp1206.game.Game; + +/** + * Listener for showing the scores scene + */ +public interface ShowScoresSceneListener { + + /** + * Show the scene + */ + public void show(Game game); + +} diff --git a/src/main/java/uk/mgrove/ac/soton/comp1206/game/Game.java b/src/main/java/uk/mgrove/ac/soton/comp1206/game/Game.java index 29e7ef6..0f5350e 100644 --- a/src/main/java/uk/mgrove/ac/soton/comp1206/game/Game.java +++ b/src/main/java/uk/mgrove/ac/soton/comp1206/game/Game.java @@ -1,13 +1,16 @@ package uk.mgrove.ac.soton.comp1206.game; +import javafx.application.Platform; import javafx.beans.property.IntegerProperty; import javafx.beans.property.SimpleIntegerProperty; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import uk.mgrove.ac.soton.comp1206.component.GameBlock; import uk.mgrove.ac.soton.comp1206.component.GameBlockCoordinate; +import uk.mgrove.ac.soton.comp1206.event.GameLoopListener; import uk.mgrove.ac.soton.comp1206.event.LineClearedListener; import uk.mgrove.ac.soton.comp1206.event.NextPieceListener; +import uk.mgrove.ac.soton.comp1206.event.ShowScoresSceneListener; import uk.mgrove.ac.soton.comp1206.util.Multimedia; import java.util.*; @@ -80,6 +83,22 @@ public class Game { */ private LineClearedListener lineClearedListener; + + /** + * Game timer for time-based functionality + */ + private Timer gameTimer; + + /** + * Listener for game loop being scheduled + */ + private GameLoopListener gameLoopListener; + + /** + * Listener for showing scores scene + */ + private ShowScoresSceneListener showScoresListener; + /** * Create a new game with the specified rows and columns. Creates a corresponding grid model. * @param cols number of columns @@ -142,6 +161,55 @@ public class Game { logger.info("Initialising game"); followingPiece = spawnPiece(); nextPiece(); + + scheduleGameLoop(); + } + + /** + * Game loop - ongoing time-based functionality + */ + private void gameLoop() { + logger.info("Executing game loop"); + setLives(getLives() - 1); + nextPiece(); + setMultiplier(1); + Multimedia.playAudio("sounds/lifelose.wav"); + + if(getLives() < 0) { + endGame(); + if (showScoresListener != null) Platform.runLater(() -> showScoresListener.show(this)); + } + else scheduleGameLoop(); + } + + /** + * Start new game loop + */ + private void scheduleGameLoop() { + logger.info("Scheduling game loop"); + + if (gameTimer != null) gameTimer.cancel(); + + TimerTask gameTimerTask = new TimerTask() { + @Override + public void run() { + gameLoop(); + } + }; + gameTimer = new Timer("Timer"); + var timerDelay = getTimerDelay(); + gameTimer.schedule(gameTimerTask, timerDelay); + + if (gameLoopListener != null) gameLoopListener.process(timerDelay); + } + + /** + * End game + */ + public void endGame() { + if (gameTimer != null) gameTimer.cancel(); + Multimedia.playAudio("sounds/explode.wav"); + // TODO: do processing to end game - switch to ScoresScene } /** @@ -166,7 +234,6 @@ public class Game { logger.info("Playing piece at x: {}, y: {}", x, y); grid.playPiece(currentPiece,x,y); afterPiece(); - nextPiece(); Multimedia.playAudio("sounds/place.wav"); } else { @@ -236,6 +303,9 @@ public class Game { for (var block : blocksToRemove) { block.set(0); } + + nextPiece(); + scheduleGameLoop(); } /** @@ -280,6 +350,14 @@ public class Game { if (nextPieceListener != null) nextPieceListener.nextPiece(currentPiece, followingPiece); } + /** + * Get timer delay - amount of time before timer should expire + * @return timer delay + */ + private int getTimerDelay() { + return Math.max(2500, 12000 - 500 * getLevel()); + } + /** * Get the grid model inside this game representing the game state of the board * @return game grid model @@ -412,4 +490,20 @@ public class Game { lineClearedListener = listener; } + /** + * Set listener for game loop being executed + * @param listener listener to set + */ + public void setOnGameLoop(GameLoopListener listener) { + gameLoopListener = listener; + } + + /** + * Set listener for showing scores scene + * @param listener listener to set + */ + public void setShowScoresListener(ShowScoresSceneListener listener) { + showScoresListener = listener; + } + } diff --git a/src/main/java/uk/mgrove/ac/soton/comp1206/scene/ChallengeScene.java b/src/main/java/uk/mgrove/ac/soton/comp1206/scene/ChallengeScene.java index 093f055..eeb5633 100644 --- a/src/main/java/uk/mgrove/ac/soton/comp1206/scene/ChallengeScene.java +++ b/src/main/java/uk/mgrove/ac/soton/comp1206/scene/ChallengeScene.java @@ -1,7 +1,16 @@ package uk.mgrove.ac.soton.comp1206.scene; +import javafx.animation.*; +import javafx.beans.property.IntegerProperty; +import javafx.beans.property.SimpleIntegerProperty; +import javafx.beans.value.ChangeListener; +import javafx.geometry.Pos; import javafx.scene.input.KeyEvent; import javafx.scene.layout.*; +import javafx.scene.paint.Color; +import javafx.scene.shape.Rectangle; +import javafx.scene.text.Text; +import javafx.util.Duration; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import uk.mgrove.ac.soton.comp1206.component.GameBlock; @@ -19,7 +28,14 @@ import uk.mgrove.ac.soton.comp1206.util.Multimedia; */ public class ChallengeScene extends BaseScene { - private static final Logger logger = LogManager.getLogger(MenuScene.class); + /** + * Logger + */ + private static final Logger logger = LogManager.getLogger(ChallengeScene.class); + + /** + * The game that is running + */ protected Game game; /** @@ -37,6 +53,26 @@ public class ChallengeScene extends BaseScene { */ private GameBoard board; + /** + * Progress bar to indicate time left until game loop executes (i.e. life is lost) + */ + private Rectangle timerCountdownBar; + + /** + * Fill transition for timer countdown bar + */ + private FillTransition timerCountdownBarFillTransition; + + /** + * Scale transition for timer countdown bar + */ + private ScaleTransition timerCountdownBarScaleTransition; + + /** + * Top high score property + */ + private final IntegerProperty highScore = new SimpleIntegerProperty(0); + /** * Create a new Single Player challenge scene * @param gameWindow the Game Window @@ -66,7 +102,7 @@ public class ChallengeScene extends BaseScene { var mainPane = new BorderPane(); challengePane.getChildren().add(mainPane); - board = new GameBoard(game.getGrid(),gameWindow.getWidth()/2,gameWindow.getWidth()/2); + board = new GameBoard(game.getGrid(),gameWindow.getWidth()/2f,gameWindow.getWidth()/2f); board.setOnRightClicked(game::rotateCurrentPiece); mainPane.setCenter(board); @@ -77,11 +113,25 @@ public class ChallengeScene extends BaseScene { currentPieceBoard.setOnLeftClicked(game::rotateCurrentPiece); followingPieceBoard = new PieceBoard(72, 72); + var topHighScoreText = new Text(); + topHighScoreText.textProperty().bind(highScore.asString()); + highScore.set(getHighScore()); + + game.scoreProperty().addListener((ChangeListener) (change, oldValue, newValue) -> { + if (newValue.intValue() > highScore.get()) highScore.set(newValue.intValue()); + }); + var rightMenu = new VBox(); - rightMenu.getChildren().addAll(statsMenu,currentPieceBoard,followingPieceBoard); + rightMenu.getChildren().addAll(statsMenu,currentPieceBoard,followingPieceBoard,topHighScoreText); mainPane.setRight(rightMenu); + timerCountdownBar = new Rectangle(gameWindow.getWidth()/2f,48); + BorderPane.setAlignment(timerCountdownBar, Pos.BOTTOM_CENTER); + // TODO: alignment of timer bar + + mainPane.setBottom(timerCountdownBar); + Multimedia.playMusic("music/game.wav"); //Handle block on game board grid being clicked @@ -137,19 +187,54 @@ public class ChallengeScene extends BaseScene { game.setLineClearedListener(board::fadeOut); + game.setOnGameLoop(this::scheduleCountdown); + + game.setShowScoresListener(this::showScores); + game.start(); } private void returnToMenu() { - // TODO: any processing to end game - - + game.endGame(); + gameWindow.startMenu(); } + private void showScores(Game game) { + if (timerCountdownBarFillTransition != null) timerCountdownBarFillTransition.stop(); + if (timerCountdownBarScaleTransition != null) timerCountdownBarScaleTransition.stop(); + gameWindow.startScores(game); + } + private void setCurrentPiece(GamePiece currentPiece, GamePiece followingPiece) { currentPieceBoard.displayPiece(currentPiece); followingPieceBoard.displayPiece(followingPiece); } + /** + * Reset the countdown progress bar with new game timer delay when the game loop is scheduled + * @param timerDelay delay until game loop is executed + */ + private void scheduleCountdown(int timerDelay) { + logger.info("Scheduling UI countdown timer"); + + timerCountdownBar.setArcHeight(32); + timerCountdownBar.setArcWidth(32); + timerCountdownBar.setFill(Color.GREEN); + timerCountdownBarFillTransition = new FillTransition(Duration.millis(timerDelay), timerCountdownBar, Color.GREEN, Color.RED); + timerCountdownBarScaleTransition = new ScaleTransition(Duration.millis(timerDelay), timerCountdownBar); + timerCountdownBarScaleTransition.setFromX(1); + timerCountdownBarScaleTransition.setToX(0); + timerCountdownBarFillTransition.play(); + timerCountdownBarScaleTransition.play(); + } + + /** + * Get top high score + * @return top high score + */ + private int getHighScore() { + return ScoresScene.getScores("scores.txt").get(0).getValue(); + } + } diff --git a/src/main/java/uk/mgrove/ac/soton/comp1206/scene/InstructionsScene.java b/src/main/java/uk/mgrove/ac/soton/comp1206/scene/InstructionsScene.java index 9e59a17..339df12 100644 --- a/src/main/java/uk/mgrove/ac/soton/comp1206/scene/InstructionsScene.java +++ b/src/main/java/uk/mgrove/ac/soton/comp1206/scene/InstructionsScene.java @@ -1,7 +1,6 @@ package uk.mgrove.ac.soton.comp1206.scene; import javafx.geometry.Pos; -import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.input.KeyCode; import javafx.scene.layout.BorderPane; @@ -16,6 +15,9 @@ import uk.mgrove.ac.soton.comp1206.game.GamePiece; import uk.mgrove.ac.soton.comp1206.ui.GamePane; import uk.mgrove.ac.soton.comp1206.ui.GameWindow; +/** + * Scene to show game instructions + */ public class InstructionsScene extends BaseScene { /** diff --git a/src/main/java/uk/mgrove/ac/soton/comp1206/scene/ScoresScene.java b/src/main/java/uk/mgrove/ac/soton/comp1206/scene/ScoresScene.java new file mode 100644 index 0000000..42d47f0 --- /dev/null +++ b/src/main/java/uk/mgrove/ac/soton/comp1206/scene/ScoresScene.java @@ -0,0 +1,216 @@ +package uk.mgrove.ac.soton.comp1206.scene; + +import javafx.beans.property.SimpleListProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.scene.control.Button; +import javafx.scene.control.TextField; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.StackPane; +import javafx.scene.layout.VBox; +import javafx.scene.text.Text; +import javafx.util.Pair; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import uk.mgrove.ac.soton.comp1206.component.ScoresList; +import uk.mgrove.ac.soton.comp1206.game.Game; +import uk.mgrove.ac.soton.comp1206.ui.GamePane; +import uk.mgrove.ac.soton.comp1206.ui.GameWindow; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Scanner; + +/** + * Scene to show scores and record high scores + */ +public class ScoresScene extends BaseScene { + + /** + * Logger + */ + private static final Logger logger = LogManager.getLogger(ScoresScene.class); + + /** + * The game that just finished + */ + private final Game game; + + /** + * List of scores stored locally + */ + private SimpleListProperty> localScores; + + /** + * Root pane in scene inside the GamePane + */ + private StackPane scoresPane; + + /** + * Node to display high scores + */ + private ScoresList scoresUiList; + + /** + * Container for prompting for username when high score achieved + */ + private VBox userNamePrompt; + + /** + * Create a new scores scene + * @param gameWindow the Game Window + * @param game the game that just finished + */ + public ScoresScene(GameWindow gameWindow, Game game) { + super(gameWindow); + logger.info("Creating Scores Scene"); + this.game = game; + } + + /** + * Build the layout of the scene + */ + @Override + public void build() { + logger.info("Building " + this.getClass().getName()); + + root = new GamePane(gameWindow.getWidth(),gameWindow.getHeight()); + + scoresPane = new StackPane(); + scoresPane.setMaxWidth(gameWindow.getWidth()); + scoresPane.setMaxHeight(gameWindow.getHeight()); + scoresPane.getStyleClass().add("menu-background"); + root.getChildren().add(scoresPane); + + var mainPane = new BorderPane(); + scoresPane.getChildren().add(mainPane); + + ArrayList> scoresList = new ArrayList<>(); + ObservableList> observableScoresList = FXCollections.observableArrayList(scoresList); + localScores = new SimpleListProperty<>(observableScoresList); + loadScores("scores.txt"); + if (game.getScore() > localScores.get(localScores.getSize() - 1).getValue()) showHighScorePrompt(game.getScore()); + + scoresUiList = new ScoresList(); + scoresUiList.bindScores(localScores); + mainPane.setCenter(scoresUiList); + } + + /** + * Initialise this scene. Called after creation + */ + @Override + public void initialise() { + } + + /** + * Load high scores from file + * @param filePath file path to load scores from + */ + public void loadScores(String filePath) { + logger.info("Loading scores from file: {}", filePath); + localScores = getScores(filePath); + } + + /** + * Get scores from file + * @param filePath file to load scores from + * @return list of scores + */ + public static SimpleListProperty> getScores(String filePath) { + logger.info("Retrieving scores from file: {}", filePath); + + var scores = new SimpleListProperty>(FXCollections.observableArrayList()); + try { + File scoresFile = new File(filePath); + Scanner scanner = new Scanner(scoresFile); + while (scanner.hasNextLine()) { + var line = scanner.nextLine(); + if (line.matches("^.+:[0-9]+$")) { + int splitIndex = line.lastIndexOf(":"); + String[] info = {line.substring(0,splitIndex), line.substring(splitIndex+1)}; + scores.add(new Pair<>(info[0], Integer.valueOf(info[1]))); + } + } + scanner.close(); + } catch (FileNotFoundException e1) { + logger.error("Unable to load scores file, writing default scores instead: {}", filePath); + + scores.add(new Pair<>("Sam",3000)); + scores.add(new Pair<>("Jane",2000)); + scores.add(new Pair<>("Pete",1000)); + writeScores("scores.txt", scores); + } + logger.info("Retrieved scores: {}", scores); + return scores; + } + + /** + * Write list of scores to file + * @param filePath file to write to + * @param scores scores to write + */ + public static void writeScores(String filePath, SimpleListProperty> scores) { + logger.info("Writing scores to file: {}", filePath); + try { + FileWriter scoresWriter = new FileWriter(filePath); + + for (var pair : scores.get()) { + scoresWriter.write(pair.getKey() + ":" + pair.getValue() + "\n"); + } + + scoresWriter.close(); + } catch (IOException e) { + logger.error("Unable to write scores file: {}", filePath); + } + } + + /** + * Add new high score - prompt user for name and add to saved scores + * @param score new high score to save + */ + private void showHighScorePrompt(int score) { + logger.info("Showing high score username input prompt"); + + userNamePrompt = new VBox(); + var userNameInput = new TextField(); + userNameInput.setPromptText("Enter username..."); + userNameInput.setOnAction((event) -> saveHighScore(userNameInput.getText(), score)); + var userNameSubmit = new Button("Submit"); + userNameSubmit.setOnAction((event) -> saveHighScore(userNameInput.getText(), score)); + userNamePrompt.getChildren().addAll(new Text("Username:"), userNameInput, userNameSubmit); + scoresPane.getChildren().add(userNamePrompt); + } + + /** + * Save new high score + * @param username username of user who set high score + * @param score high score to save + */ + private void saveHighScore(String username, int score) { + logger.info("Saving high score: {} for user: {}", score, username); + + for (var i = 0; i < localScores.getSize(); i++) { + if (localScores.get(i).getValue() < score) { + localScores.add(i, new Pair<>(username, score)); + break; + } + } + // if score isn't higher than last high score then this shouldn't have been triggered + // so while it won't get stored, this isn't an issue + writeScores("scores.txt", localScores); + scoresPane.getChildren().remove(userNamePrompt); + scoresUiList.reveal(); + } + + /** + * Get local scores property + * @return local scores property + */ + public SimpleListProperty> localScoresProperty() { + return localScores; + } +} diff --git a/src/main/java/uk/mgrove/ac/soton/comp1206/ui/GameWindow.java b/src/main/java/uk/mgrove/ac/soton/comp1206/ui/GameWindow.java index d7fd1f6..a5d03a9 100644 --- a/src/main/java/uk/mgrove/ac/soton/comp1206/ui/GameWindow.java +++ b/src/main/java/uk/mgrove/ac/soton/comp1206/ui/GameWindow.java @@ -9,6 +9,7 @@ import javafx.stage.Stage; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import uk.mgrove.ac.soton.comp1206.App; +import uk.mgrove.ac.soton.comp1206.game.Game; import uk.mgrove.ac.soton.comp1206.network.Communicator; import uk.mgrove.ac.soton.comp1206.scene.*; import uk.mgrove.ac.soton.comp1206.scene.BaseScene; @@ -86,7 +87,9 @@ public class GameWindow { /** * Display the single player challenge */ - public void startChallenge() { loadScene(new ChallengeScene(this)); } + public void startChallenge() { + loadScene(new ChallengeScene(this)); + } /** * Display the multiplayer challenge @@ -101,7 +104,12 @@ public class GameWindow { public void startInstructions() { loadScene(new InstructionsScene(this)); } /** - * Setup the default settings for the stage itself (the window), such as the title and minimum width and height. + * Display the single player challenge + */ + public void startScores(Game game) { loadScene(new ScoresScene(this, game)); } + + /** + * Set up the default settings for the stage itself (the window), such as the title and minimum width and height. */ public void setupStage() { stage.setTitle("TetrECS"); diff --git a/src/main/java/uk/mgrove/ac/soton/comp1206/ui/StatsMenu.java b/src/main/java/uk/mgrove/ac/soton/comp1206/ui/StatsMenu.java index ddc1a74..8a4089b 100644 --- a/src/main/java/uk/mgrove/ac/soton/comp1206/ui/StatsMenu.java +++ b/src/main/java/uk/mgrove/ac/soton/comp1206/ui/StatsMenu.java @@ -5,8 +5,6 @@ import javafx.scene.layout.VBox; import javafx.scene.text.Text; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import uk.mgrove.ac.soton.comp1206.component.PieceBoard; -import uk.mgrove.ac.soton.comp1206.game.Game; /** * Stats menu class to show basic stats about game status @@ -16,24 +14,7 @@ public class StatsMenu extends VBox { /** * Logger */ - private static final Logger logger = LogManager.getLogger(Game.class); - - /** - * Player's current score - */ - private final Text score = new Text("0"); - /** - * Player's current level - */ - private final Text level = new Text("0"); - /** - * Player's remaining lives - */ - private final Text lives = new Text("3"); - /** - * Player's current multiplier - */ - private final Text multiplier = new Text("1"); + private static final Logger logger = LogManager.getLogger(StatsMenu.class); /** * Initialise the menu by adding basic stats and binding them to properties @@ -45,17 +26,21 @@ public class StatsMenu extends VBox { public StatsMenu(IntegerProperty score, IntegerProperty level, IntegerProperty lives, IntegerProperty multiplier) { logger.info("Initialising new stats menu with score {}, level {}, lives {}, and multiplier {}", score.get(), level.get(), lives.get(), multiplier.get()); - this.score.textProperty().bind(score.asString()); - this.level.textProperty().bind(level.asString()); - this.lives.textProperty().bind(lives.asString()); - this.multiplier.textProperty().bind(multiplier.asString()); + Text score1 = new Text(); + score1.textProperty().bind(score.asString()); + Text level1 = new Text(); + level1.textProperty().bind(level.asString()); + Text lives1 = new Text(); + lives1.textProperty().bind(lives.asString()); + Text multiplier1 = new Text(); + multiplier1.textProperty().bind(multiplier.asString()); var scoreHeader = new Text("Score"); var levelHeader = new Text("Level"); var livesHeader = new Text("Lives"); var multiplierHeader = new Text("Multiplier"); - getChildren().addAll(scoreHeader,this.score,levelHeader,this.level,livesHeader,this.lives,multiplierHeader,this.multiplier); + getChildren().addAll(scoreHeader, score1,levelHeader, level1,livesHeader, lives1,multiplierHeader, multiplier1); } } diff --git a/src/main/java/uk/mgrove/ac/soton/comp1206/util/Multimedia.java b/src/main/java/uk/mgrove/ac/soton/comp1206/util/Multimedia.java index b4cfe04..d18fdb5 100644 --- a/src/main/java/uk/mgrove/ac/soton/comp1206/util/Multimedia.java +++ b/src/main/java/uk/mgrove/ac/soton/comp1206/util/Multimedia.java @@ -4,14 +4,16 @@ import javafx.scene.media.Media; import javafx.scene.media.MediaPlayer; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import uk.mgrove.ac.soton.comp1206.game.Game; +/** + * Class for static multimedia actions like playing sounds + */ public class Multimedia { /** * Logger */ - private static final Logger logger = LogManager.getLogger(Game.class); + private static final Logger logger = LogManager.getLogger(Multimedia.class); /** * Media player for game music