[FEAT] Show other players' boards in multiplayer

This commit is contained in:
2023-04-22 05:39:25 +01:00
parent cc205f5c6e
commit f10cdec09b
12 changed files with 271 additions and 35 deletions

View File

@@ -70,7 +70,8 @@ public class Chat extends VBox {
messagesContainer.setContent(messages); messagesContainer.setContent(messages);
messagesContainer.setFitToWidth(true); messagesContainer.setFitToWidth(true);
messagesContainer.setFitToHeight(true); messagesContainer.setFitToHeight(true);
messagesContainer.setPrefHeight(320); messagesContainer.setPrefHeight(280);
messagesContainer.setMaxHeight(280);
messagesContainer.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); messagesContainer.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
messagesContainer.setVvalue(1.0); messagesContainer.setVvalue(1.0);
messagesContainer.getStyleClass().add("scroller"); messagesContainer.getStyleClass().add("scroller");

View File

@@ -1,5 +1,7 @@
package uk.mgrove.ac.soton.comp1206.component; package uk.mgrove.ac.soton.comp1206.component;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.scene.input.MouseButton; import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent; import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
@@ -199,6 +201,14 @@ public class GameBoard extends GridPane {
return block; return block;
} }
/**
* Get grid value property
* @return properties for value of block at given location in grid
*/
public IntegerProperty getGridProperty(int x, int y) {
return grid.getGridProperty(x,y);
}
/** /**
* Set the listener to handle an event when a block is clicked * Set the listener to handle an event when a block is clicked
* @param listener listener to add * @param listener listener to add
@@ -305,4 +315,20 @@ public class GameBoard extends GridPane {
currentPiece = newPiece; currentPiece = newPiece;
} }
/**
* Get current game piece
* @return current piece
*/
public GamePiece getCurrentPiece() {
return currentPiece;
}
/**
* Set whether board should be focussable
* @param enableFocus whether board should be focussable
*/
public void enableFocus(boolean enableFocus) {
this.enableFocus = enableFocus;
}
} }

View File

@@ -33,6 +33,7 @@ public class Leaderboard extends ScoresList {
title = new Text(titleText); title = new Text(titleText);
title.getStyleClass().add("heading"); title.getStyleClass().add("heading");
getChildren().add(title); getChildren().add(title);
setSpacing(4);
reveal(); reveal();
scores.addListener((ListChangeListener<? super Pair<String,Pair<Integer, Integer>>>) change -> Platform.runLater(() -> { scores.addListener((ListChangeListener<? super Pair<String,Pair<Integer, Integer>>>) change -> Platform.runLater(() -> {

View File

@@ -0,0 +1,18 @@
package uk.mgrove.ac.soton.comp1206.event;
import javafx.beans.property.SimpleIntegerProperty;
import uk.mgrove.ac.soton.comp1206.component.GameBoard;
/**
* Listener for player game boards
*/
public interface PlayerGameBoardListener {
/**
* Action the listener with details of the board
* @param username player's username
* @param gridProperties properties for board grid contents
*/
void add(String username, SimpleIntegerProperty[][] gridProperties);
}

View File

@@ -4,6 +4,7 @@ import javafx.application.Platform;
import javafx.beans.property.IntegerProperty; import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleListProperty; import javafx.beans.property.SimpleListProperty;
import javafx.beans.property.SimpleMapProperty;
import javafx.util.Pair; import javafx.util.Pair;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@@ -96,7 +97,12 @@ public class Game {
/** /**
* Listener for showing scores scene * Listener for showing scores scene
*/ */
private ShowScoresSceneListener showScoresListener; protected ShowScoresSceneListener showScoresListener;
/**
* Listener for when new player board is added
*/
protected PlayerGameBoardListener playerBoardAddedListener;
/** /**
* Create a new game with the specified rows and columns. Creates a corresponding grid model. * Create a new game with the specified rows and columns. Creates a corresponding grid model.
@@ -167,7 +173,7 @@ public class Game {
/** /**
* Game loop - ongoing time-based functionality * Game loop - ongoing time-based functionality
*/ */
private void gameLoop() { protected void gameLoop() {
logger.info("Executing game loop"); logger.info("Executing game loop");
setLives(getLives() - 1); setLives(getLives() - 1);
nextPiece(); nextPiece();
@@ -512,6 +518,22 @@ public class Game {
return null; return null;
} }
/**
* Get the player boards property - always null in this class
* @return property for player boards
*/
public SimpleMapProperty<String, SimpleIntegerProperty[][]> playerBoardsProperty() {
return null;
}
/**
* Set listener for when new player board is added
* @param listener
*/
public void setOnPlayerBoardAdded(PlayerGameBoardListener listener) {
this.playerBoardAddedListener = listener;
}
/** /**
* Set listener for game failure - but in this class does nothing * Set listener for game failure - but in this class does nothing
* @param listener listener to set * @param listener listener to set

View File

@@ -207,7 +207,7 @@ public class Grid {
* @param y y-coordinate of piece centre * @param y y-coordinate of piece centre
*/ */
public void previewPiece(GamePiece piece, int x, int y) { public void previewPiece(GamePiece piece, int x, int y) {
if (!canPlayPiece(piece, x, y)) return; if (piece == null || !canPlayPiece(piece, x, y)) return;
logger.info("Previewing piece {} at {},{}", piece, x, y); logger.info("Previewing piece {} at {},{}", piece, x, y);
int value = piece.getValue(); int value = piece.getValue();

View File

@@ -1,16 +1,25 @@
package uk.mgrove.ac.soton.comp1206.game; package uk.mgrove.ac.soton.comp1206.game;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleListProperty; import javafx.beans.property.SimpleListProperty;
import javafx.beans.property.SimpleMapProperty;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.geometry.Pos;
import javafx.scene.control.Alert; import javafx.scene.control.Alert;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import javafx.util.Pair; import javafx.util.Pair;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import uk.mgrove.ac.soton.comp1206.event.GameFailureListener; import uk.mgrove.ac.soton.comp1206.event.GameFailureListener;
import uk.mgrove.ac.soton.comp1206.network.Communicator; import uk.mgrove.ac.soton.comp1206.network.Communicator;
import uk.mgrove.ac.soton.comp1206.util.Multimedia;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner; import java.util.Scanner;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
@@ -33,15 +42,20 @@ public class MultiplayerGame extends Game {
private final BlockingQueue<GamePiece> pieceQueue = new LinkedBlockingQueue<>(); private final BlockingQueue<GamePiece> pieceQueue = new LinkedBlockingQueue<>();
/** /**
* Scores for the leaderboard * Scores for the leaderboard, with structure username, score, lives
*/ */
private final SimpleListProperty<Pair<String,Pair<Integer,Integer>>> leaderboardScores = new SimpleListProperty<>(FXCollections.observableArrayList(new ArrayList<>())); private final SimpleListProperty<Pair<String,Pair<Integer,Integer>>> leaderboardScores = new SimpleListProperty<>(FXCollections.observableArrayList());
/** /**
* Listener for game failing * Listener for game failing
*/ */
private GameFailureListener gameFailureListener; private GameFailureListener gameFailureListener;
/**
* Mapping of usernames to player boards
*/
private final SimpleMapProperty<String, SimpleIntegerProperty[][]> playerBoards = new SimpleMapProperty<>(FXCollections.observableHashMap());
/** /**
* Create a new game with the specified rows and columns. Creates a corresponding grid model. * Create a new game with the specified rows and columns. Creates a corresponding grid model.
* *
@@ -125,11 +139,34 @@ public class MultiplayerGame extends Game {
break; break;
} }
} }
} else if (message.startsWith("BOARD ")) {
var info = message.replaceFirst("BOARD ", "").split(":");
var gridValues = info[1].split(" ");
if (playerBoards.containsKey(info[0])) {
logger.info("Updating board for: {}", info[0]);
for (var x = 0; x < playerBoards.get(info[0]).length; x++) {
for (var y = 0; y < playerBoards.get(info[0])[0].length; y++) {
playerBoards.get(info[0])[x][y].set(Integer.parseInt(gridValues[playerBoards.get(info[0])[0].length * x + y]));
}
}
} else {
logger.info("Adding board for: {}", info[0]);
var dimensions = (int) Math.sqrt(gridValues.length);
SimpleIntegerProperty[][] newProperties = new SimpleIntegerProperty[dimensions][dimensions];
for (var x = 0; x < dimensions; x++) {
for (var y = 0; y < dimensions; y++) {
newProperties[x][y] = new SimpleIntegerProperty(Integer.parseInt(gridValues[grid.getCols() * x + y]));
}
}
playerBoards.put(info[0], newProperties);
if (playerBoardAddedListener != null) playerBoardAddedListener.add(info[0], newProperties);
}
logger.info("Player boards: {}", playerBoards.get());
} }
} }
/** /**
* Parse high scores from a string to list property * Parse high scores from a string to list property, with structure username, score, lives
* @param data string to parse from * @param data string to parse from
* @return list property containing scores loaded * @return list property containing scores loaded
*/ */
@@ -141,7 +178,7 @@ public class MultiplayerGame extends Game {
while (scanner.hasNextLine()) { while (scanner.hasNextLine()) {
var line = scanner.nextLine(); var line = scanner.nextLine();
if (line.matches("^.+:[0-9]+:([0-9]+|DEAD)$")) { if (line.matches("^.+:[0-9]+:((-?[0-9]+)|DEAD)$")) {
var info = line.split(":"); var info = line.split(":");
var lives = info[2].equals("DEAD") ? -1 : Integer.parseInt(info[2]); var lives = info[2].equals("DEAD") ? -1 : Integer.parseInt(info[2]);
scores.add(new Pair<>(info[0], new Pair<>(Integer.valueOf(info[1]), lives))); scores.add(new Pair<>(info[0], new Pair<>(Integer.valueOf(info[1]), lives)));
@@ -162,15 +199,41 @@ public class MultiplayerGame extends Game {
} }
/** /**
* End game * Get the player boards property
* @return property for player boards
*/ */
@Override public SimpleMapProperty<String, SimpleIntegerProperty[][]> playerBoardsProperty() {
public void endGame() { return playerBoards;
super.endGame(); }
/**
* Notify server that player is dead
*/
private void die() {
logger.info("Sending die message to server"); logger.info("Sending die message to server");
communicator.send("DIE"); communicator.send("DIE");
} }
/**
* Game loop - ongoing time-based functionality
*/
@Override
protected void gameLoop() {
logger.info("Executing game loop");
setLives(getLives() - 1);
nextPiece();
setMultiplier(1);
Multimedia.playAudio("sounds/lifelose.wav");
if(getLives() < 0) {
die();
logger.info("Ending game");
endGame();
if (showScoresListener != null) Platform.runLater(() -> showScoresListener.show(this));
}
else scheduleGameLoop();
}
/** /**
* Update the score, multiplier, and level depending on the number of lines and blocks that have been cleared * Update the score, multiplier, and level depending on the number of lines and blocks that have been cleared
* @param lines number of lines cleared * @param lines number of lines cleared

View File

@@ -78,6 +78,11 @@ public class ChallengeScene extends BaseScene {
*/ */
protected final IntegerProperty highScore = new SimpleIntegerProperty(0); protected final IntegerProperty highScore = new SimpleIntegerProperty(0);
/**
* Main stack pane for scene
*/
protected StackPane challengePane;
/** /**
* Create a new Single Player challenge scene * Create a new Single Player challenge scene
* @param gameWindow the Game Window * @param gameWindow the Game Window
@@ -98,7 +103,7 @@ public class ChallengeScene extends BaseScene {
root = new GamePane(gameWindow.getWidth(),gameWindow.getHeight()); root = new GamePane(gameWindow.getWidth(),gameWindow.getHeight());
var challengePane = new StackPane(); challengePane = new StackPane();
challengePane.setMaxWidth(gameWindow.getWidth()); challengePane.setMaxWidth(gameWindow.getWidth());
challengePane.setMaxHeight(gameWindow.getHeight()); challengePane.setMaxHeight(gameWindow.getHeight());
challengePane.getStyleClass().add("menu-background"); challengePane.getStyleClass().add("menu-background");
@@ -163,9 +168,21 @@ public class ChallengeScene extends BaseScene {
switch (event.getCode()) { switch (event.getCode()) {
case ESCAPE -> returnToMenu(); case ESCAPE -> returnToMenu();
case ENTER, X -> game.dropPiece(board.getXFocus(),board.getYFocus()); case ENTER, X -> game.dropPiece(board.getXFocus(),board.getYFocus());
case SPACE, R -> game.swapPieces(); case SPACE, R -> {
case OPEN_BRACKET, Q, Z -> game.rotateCurrentPieceAnticlockwise(); game.swapPieces();
case CLOSE_BRACKET, E, C -> game.rotateCurrentPiece(); game.getGrid().clearPreview();
game.getGrid().previewPiece(board.getCurrentPiece(), board.getXFocus(), board.getYFocus());
}
case OPEN_BRACKET, Q, Z -> {
game.rotateCurrentPieceAnticlockwise();
game.getGrid().clearPreview();
game.getGrid().previewPiece(board.getCurrentPiece(), board.getXFocus(), board.getYFocus());
}
case CLOSE_BRACKET, E, C -> {
game.rotateCurrentPiece();
game.getGrid().clearPreview();
game.getGrid().previewPiece(board.getCurrentPiece(), board.getXFocus(), board.getYFocus());
}
case LEFT, A -> board.changeXFocus(-1); case LEFT, A -> board.changeXFocus(-1);
case RIGHT, D -> board.changeXFocus(1); case RIGHT, D -> board.changeXFocus(1);
case DOWN, S -> board.changeYFocus(1); case DOWN, S -> board.changeYFocus(1);

View File

@@ -79,6 +79,11 @@ public class LobbyScene extends BaseScene {
*/ */
private final HBox channelFunctionButtons = new HBox(); private final HBox channelFunctionButtons = new HBox();
/**
* Timer to request list of channels from server
*/
private Timer listChannelsRequest;
/** /**
* Create a new scene, passing in the GameWindow the scene will be displayed in * Create a new scene, passing in the GameWindow the scene will be displayed in
* *
@@ -143,7 +148,7 @@ public class LobbyScene extends BaseScene {
gameWindow.getCommunicator().addListener(this::handleCommunicatorMessage); gameWindow.getCommunicator().addListener(this::handleCommunicatorMessage);
var listChannelsRequest = new Timer("Request list of channels from communicator"); listChannelsRequest = new Timer("Request list of channels from communicator");
listChannelsRequest.schedule(new TimerTask() { listChannelsRequest.schedule(new TimerTask() {
@Override @Override
public void run() { public void run() {
@@ -227,6 +232,7 @@ public class LobbyScene extends BaseScene {
}); });
} else if (message.equals("HOST")) { } else if (message.equals("HOST")) {
logger.info("User is host of current channel"); logger.info("User is host of current channel");
if (!isChannelHost) {
isChannelHost = true; isChannelHost = true;
Platform.runLater(() -> { Platform.runLater(() -> {
logger.info("Current channel host status: {}", isChannelHost); logger.info("Current channel host status: {}", isChannelHost);
@@ -235,6 +241,7 @@ public class LobbyScene extends BaseScene {
startGame.setOnMouseClicked((event) -> gameWindow.getCommunicator().send("START")); startGame.setOnMouseClicked((event) -> gameWindow.getCommunicator().send("START"));
channelFunctionButtons.getChildren().add(0, startGame); channelFunctionButtons.getChildren().add(0, startGame);
}); });
}
} else if (message.matches("^NICK .+:.+$")) { } else if (message.matches("^NICK .+:.+$")) {
Platform.runLater(() -> { Platform.runLater(() -> {
var usernames = message.replaceFirst("NICK ", "").split(":"); var usernames = message.replaceFirst("NICK ", "").split(":");
@@ -255,7 +262,10 @@ public class LobbyScene extends BaseScene {
}); });
} else if (message.equals("START")) { } else if (message.equals("START")) {
logger.info("Starting game"); logger.info("Starting game");
Platform.runLater(gameWindow::startMultiplayerGame); Platform.runLater(() -> {
listChannelsRequest.cancel();
gameWindow.startMultiplayerGame();
});
} }
} }

View File

@@ -1,9 +1,16 @@
package uk.mgrove.ac.soton.comp1206.scene; package uk.mgrove.ac.soton.comp1206.scene;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.property.MapProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleMapProperty;
import javafx.collections.FXCollections;
import javafx.geometry.Pos;
import javafx.scene.control.Separator; import javafx.scene.control.Separator;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.scene.text.Text; import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import uk.mgrove.ac.soton.comp1206.component.*; import uk.mgrove.ac.soton.comp1206.component.*;
@@ -30,6 +37,16 @@ public class MultiplayerScene extends ChallengeScene {
*/ */
private Leaderboard leaderboard; private Leaderboard leaderboard;
/**
* Other players' live boards
*/
private MapProperty<String, SimpleIntegerProperty[][]> playerBoards = new SimpleMapProperty<>(FXCollections.observableHashMap());
/**
* Grid of other players' live boards
*/
private final GridPane playerBoardGrid = new GridPane();
/** /**
* Create a new multiplayer challenge scene * Create a new multiplayer challenge scene
* *
@@ -50,6 +67,36 @@ public class MultiplayerScene extends ChallengeScene {
game = new MultiplayerGame(5, 5, gameWindow.getCommunicator()); game = new MultiplayerGame(5, 5, gameWindow.getCommunicator());
game.setOnGameFail(() -> Platform.runLater(gameWindow::startMenu)); game.setOnGameFail(() -> Platform.runLater(gameWindow::startMenu));
game.setOnPlayerBoardAdded((username, gridProperties) -> {
Platform.runLater(() -> {
var newGameBoard = new GameBoard(gridProperties.length, gridProperties[0].length, 100, 100);
newGameBoard.enableFocus(false);
for (var x = 0; x < gridProperties.length; x++) {
for (var y = 0; y < gridProperties[0].length; y++) {
newGameBoard.getGridProperty(x,y).bindBidirectional(gridProperties[x][y]);
}
}
var leaderboardScores = game.leaderboardScoresProperty();
var boardGridDimensions = (int) Math.sqrt(leaderboardScores.size());
var playerIndex = -1;
for (var player : leaderboardScores) {
playerIndex++;
if (player.getKey().equals(username)) break;
}
var rowIndex = playerIndex / boardGridDimensions;
var columnIndex = playerIndex - rowIndex * boardGridDimensions;
var newBoardTitle = new Text(username);
newBoardTitle.setTextAlignment(TextAlignment.CENTER);
newBoardTitle.getStyleClass().add("heading");
logger.debug("Creating board for: {} at row index: {}, column index: {}", username, rowIndex, columnIndex);
var newBoardContainer = new VBox(newBoardTitle, newGameBoard);
newBoardContainer.setAlignment(Pos.CENTER);
newBoardContainer.setSpacing(4);
playerBoardGrid.add(newBoardContainer, 1, 1);
});
});
gameWindow.getCommunicator().send("SCORES"); gameWindow.getCommunicator().send("SCORES");
} }
@@ -63,12 +110,32 @@ public class MultiplayerScene extends ChallengeScene {
leftMenu.setSpacing(8); leftMenu.setSpacing(8);
leftMenu.setMaxWidth(200); leftMenu.setMaxWidth(200);
leftMenu.setPrefWidth(200); leftMenu.setPrefWidth(200);
var viewOtherBoards = new Text("See others");
viewOtherBoards.getStyleClass().add("channelItem");
viewOtherBoards.setOnMouseClicked((event) -> {
Platform.runLater(() -> {
var returnButton = new Text("Back");
returnButton.getStyleClass().add("channelItem");
var playerBoardTitle = new Text("All Boards");
playerBoardTitle.getStyleClass().add("title");
playerBoardTitle.setTextAlignment(TextAlignment.CENTER);
var playerBoardGridContainer = new VBox(returnButton, playerBoardTitle, playerBoardGrid);
playerBoardGridContainer.setAlignment(Pos.CENTER);
playerBoardGridContainer.setFillWidth(true);
playerBoardGridContainer.setPrefHeight(Double.MAX_VALUE);
playerBoardGridContainer.setSpacing(12);
playerBoardGridContainer.getStyleClass().add("overlay");
returnButton.setOnMouseClicked((returnEvent) -> Platform.runLater(() -> challengePane.getChildren().remove(playerBoardGridContainer)));
playerBoardGrid.setAlignment(Pos.CENTER);
challengePane.getChildren().add(playerBoardGridContainer);
});
});
chat = new Chat(gameWindow.getCommunicator(), true); chat = new Chat(gameWindow.getCommunicator(), true);
chat.setChatFocusTraversable(false); chat.setChatFocusTraversable(false);
leaderboard = new Leaderboard("Leaderboard"); leaderboard = new Leaderboard("Leaderboard");
var chatTitle = new Text("Chat"); var chatTitle = new Text("Chat");
chatTitle.getStyleClass().add("heading"); chatTitle.getStyleClass().add("heading");
leftMenu.getChildren().addAll(leaderboard, new Separator(), chatTitle, chat); leftMenu.getChildren().addAll(viewOtherBoards, leaderboard, new Separator(), chatTitle, chat);
mainPane.setLeft(leftMenu); mainPane.setLeft(leftMenu);
leaderboard.bindLeaderboardScores(game.leaderboardScoresProperty()); leaderboard.bindLeaderboardScores(game.leaderboardScoresProperty());
mainPane.requestFocus(); mainPane.requestFocus();

View File

@@ -299,6 +299,7 @@ public class ScoresScene extends BaseScene {
userNamePrompt.getChildren().addAll(userNameInput, userNameSubmit); userNamePrompt.getChildren().addAll(userNameInput, userNameSubmit);
highScorePromptContainer = new VBox(usernameTitle, userNamePrompt); highScorePromptContainer = new VBox(usernameTitle, userNamePrompt);
highScorePromptContainer.setSpacing(20); highScorePromptContainer.setSpacing(20);
highScorePromptContainer.setAlignment(Pos.CENTER);
scoresPane.getChildren().addAll(highScorePromptContainer); scoresPane.getChildren().addAll(highScorePromptContainer);
StackPane.setAlignment(highScorePromptContainer, Pos.CENTER); StackPane.setAlignment(highScorePromptContainer, Pos.CENTER);
} }
@@ -338,6 +339,7 @@ public class ScoresScene extends BaseScene {
* @param score high score to save * @param score high score to save
*/ */
private void saveHighScore(String username, int score) { private void saveHighScore(String username, int score) {
if (!game.getClass().equals(MultiplayerGame.class)) {
logger.info("Saving high score: {} for user: {}", score, username); logger.info("Saving high score: {} for user: {}", score, username);
for (var i = 0; i <= localScores.getSize(); i++) { for (var i = 0; i <= localScores.getSize(); i++) {
@@ -350,6 +352,7 @@ public class ScoresScene extends BaseScene {
// so while it won't get stored, this isn't an issue // so while it won't get stored, this isn't an issue
writeScores("scores.txt", localScores); writeScores("scores.txt", localScores);
} }
}
private void writeOnlineScore(String username, int score) { private void writeOnlineScore(String username, int score) {
logger.info("Saving online high score: {} for user: {}", score, username); logger.info("Saving online high score: {} for user: {}", score, username);

View File

@@ -6,6 +6,10 @@
-fx-background-color: black; -fx-background-color: black;
} }
.overlay {
-fx-background-color: rgba(0,0,0,0.7);
}
Text { Text {
-fx-fill: white; -fx-fill: white;
-fx-font-family: 'Orbitron'; -fx-font-family: 'Orbitron';
@@ -18,6 +22,9 @@ Label {
.menu-background { .menu-background {
-fx-background-image: url("../images/1.jpg"); -fx-background-image: url("../images/1.jpg");
-fx-background-size: cover; -fx-background-size: cover;
}
BorderPane {
-fx-padding: 20; -fx-padding: 20;
} }
@@ -195,6 +202,7 @@ Label {
} }
TextField, .text-field { TextField, .text-field {
-fx-font-family: 'Orbitron';
-fx-border-color: white; -fx-border-color: white;
-fx-border-width: 1px; -fx-border-width: 1px;
-fx-background-color: rgba(0,0,0,0.5); -fx-background-color: rgba(0,0,0,0.5);