Skip to content
Snippets Groups Projects
Commit 18f253d9 authored by ayazb7's avatar ayazb7
Browse files

Adding Score scene

parent fe62b10a
No related branches found
No related tags found
No related merge requests found
Showing
with 302 additions and 26 deletions
package uk.ac.soton.comp1206.event;
public interface ScoreUpdatedListener {
void updateHighScore();
}
......@@ -7,10 +7,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import uk.ac.soton.comp1206.component.GameBlock;
import uk.ac.soton.comp1206.component.GameBlockCoordinate;
import uk.ac.soton.comp1206.event.GameLoopListener;
import uk.ac.soton.comp1206.event.GameOverListener;
import uk.ac.soton.comp1206.event.LineClearedListener;
import uk.ac.soton.comp1206.event.NextPieceListener;
import uk.ac.soton.comp1206.event.*;
import uk.ac.soton.comp1206.utility.Multimedia;
import java.util.*;
......@@ -50,6 +47,7 @@ public class Game {
protected LineClearedListener lineClearedListener = null;
protected GameOverListener gameOverListener = null;
protected GameLoopListener gameLoopListener = null;
protected ScoreUpdatedListener scoreUpdatedListener = null;
protected Timer timer;
......@@ -327,6 +325,10 @@ public class Game {
this.gameLoopListener = listener;
}
public void setScoreUpdatedListener(ScoreUpdatedListener listener) {
this.scoreUpdatedListener = listener;
}
public void rotatePiece(int rotations) {
this.currentPiece.rotate(rotations);
}
......@@ -354,6 +356,10 @@ public class Game {
public void setScore(int score) {
logger.info("Score is now " + score);
this.score.set(score);
if (this.scoreUpdatedListener != null) {
scoreUpdatedListener.updateHighScore();
}
}
public void setLevel(int level) {
......
package uk.ac.soton.comp1206.scene;
import javafx.application.Platform;
import javafx.beans.Observable;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Pos;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.*;
import javafx.scene.text.Text;
import javafx.util.Pair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
......@@ -17,6 +22,7 @@ import uk.ac.soton.comp1206.ui.GamePane;
import uk.ac.soton.comp1206.ui.GameWindow;
import uk.ac.soton.comp1206.utility.Multimedia;
import java.util.ArrayList;
import java.util.HashSet;
/**
......@@ -35,6 +41,8 @@ public class ChallengeScene extends BaseScene {
private int keyBoardPosX = 0;
private int keyBoardPosY = 0;
private IntegerProperty hiscore = new SimpleIntegerProperty(0);
/**
* Create a new Single Player challenge scene
*
......@@ -54,9 +62,12 @@ public class ChallengeScene extends BaseScene {
Multimedia.playBackgroundMusic("game_start.wav", false);
Multimedia.getBackgroundPlayer().setOnEndOfMedia(() -> Multimedia.playBackgroundMusic("game.wav", true));
this.hiscore.set(getHighScore());
this.game.setNextPieceListener(this::nextPiece);
this.game.setLineClearedListener(this::lineCleared);
this.game.setGameLoopListener(this::gameTimer);
this.game.setScoreUpdatedListener(this::updateHiScore);
this.scene.setOnKeyPressed(this::keyHandler);
......@@ -70,6 +81,13 @@ public class ChallengeScene extends BaseScene {
game.start();
}
private void updateHiScore() {
if (this.hiscore.get() < this.game.getScore().get()) {
logger.info("Updating Highscore");
this.hiscore.set(this.game.getScore().get());
}
}
private void keyHandler(KeyEvent e) {
this.board.setHover(this.board.getBlock(keyBoardPosX, keyBoardPosY), false);
if (e.getCode().equals(KeyCode.ESCAPE)) {
......@@ -189,7 +207,8 @@ public class ChallengeScene extends BaseScene {
hiScoreTitle.getStyleClass().add("heading");
gameInfo.getChildren().add(hiScoreTitle);
var hiScoreVal = new Text("10000");
var hiScoreVal = new Text();
hiScoreVal.textProperty().bind(this.hiscore.asString());
hiScoreVal.getStyleClass().add("hiscore");
gameInfo.getChildren().add(hiScoreVal);
......@@ -279,6 +298,11 @@ public class ChallengeScene extends BaseScene {
}
}
private int getHighScore() {
ArrayList<Pair<String, Integer>> localScores = ScoresScene.loadScores();
return localScores.get(0).getValue();
}
/**
* Setup the game object and model
*/
......
......@@ -76,12 +76,7 @@ public class MenuScene extends BaseScene {
Text exitLabel = new Text("Exit");
exitLabel.getStyleClass().add("menuItem");
exitLabel.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
App.getInstance().shutdown();
}
});
exitLabel.setOnMouseClicked(e -> shutDown());
menuButtons.getChildren().add(exitLabel);
menuButtons.setAlignment(Pos.CENTER);
......@@ -100,7 +95,8 @@ public class MenuScene extends BaseScene {
*/
@Override
public void initialise() {
Multimedia.playBackgroundMusic("menu.mp3", true);
Multimedia.playBackgroundMusic("menumusic.mp3", true);
this.scene.setOnKeyPressed(e -> shutDown());
}
/**
......@@ -116,4 +112,8 @@ public class MenuScene extends BaseScene {
gameWindow.displayInstructions();
}
private void shutDown() {
App.getInstance().shutdown();
}
}
package uk.ac.soton.comp1206.scene;
import javafx.application.Platform;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
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.ac.soton.comp1206.game.Game;
import uk.ac.soton.comp1206.ui.GamePane;
import uk.ac.soton.comp1206.ui.GameWindow;
import uk.ac.soton.comp1206.ui.ScoresList;
import uk.ac.soton.comp1206.utility.Multimedia;
import java.io.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class ScoresScene extends BaseScene{
private static final Logger logger = LogManager.getLogger(ScoresScene.class);
private final Game game;
private ObservableList<Pair<String, Integer>> localScores;
private Pair<String, Integer> gameScore;
private VBox widgets;
private ScoresList localList;
/**
* Create a new scene, passing in the GameWindow the scene will be displayed in
*
......@@ -25,13 +49,15 @@ public class ScoresScene extends BaseScene{
*/
public ScoresScene(GameWindow gameWindow, Game game) {
super(gameWindow);
this.game = game;
logger.info("Creating Scores Scene");
}
@Override
public void initialise() {
this.scene.setOnKeyPressed(this::escapeToMenu);
this.scene.setOnKeyPressed(e -> {
if (e.getCode().equals(KeyCode.ESCAPE)) escapeToMenu();
});
Multimedia.playSound("explode.wav");
Multimedia.playBackgroundMusic("end.wav", false);
Multimedia.getBackgroundPlayer().setOnEndOfMedia(this.gameWindow::startMenu);
......@@ -43,6 +69,8 @@ public class ScoresScene extends BaseScene{
root = new GamePane(gameWindow.getWidth(), gameWindow.getHeight());
this.localScores = FXCollections.observableArrayList(this.loadScores());
StackPane instructionsPane = new StackPane();
instructionsPane.setMaxWidth(gameWindow.getWidth());
instructionsPane.setMaxHeight(gameWindow.getHeight());
......@@ -52,31 +80,153 @@ public class ScoresScene extends BaseScene{
BorderPane mainPane = new BorderPane();
instructionsPane.getChildren().add(mainPane);
VBox widgets = new VBox();
widgets = new VBox();
ImageView title = new ImageView(getClass().getResource("/images/TetrECS.png").toExternalForm());
title.setPreserveRatio(true);
title.setFitWidth(this.gameWindow.getWidth() / 1.25);
title.setFitWidth(this.gameWindow.getWidth() / 1.75);
widgets.getChildren().add(title);
Text gameOver = new Text("Game Over");
gameOver.getStyleClass().add("bigtitle");
widgets.getChildren().add(gameOver);
Text hiScorestitle = new Text("High Scores");
hiScorestitle.getStyleClass().add("title");
widgets.getChildren().add(hiScorestitle);
localList = new ScoresList("Local Scores");
checkHiScore();
HBox scoreLists = new HBox();
widgets.getChildren().add(scoreLists);
scoreLists.getChildren().add(localList);
Text onlineScoresTitle = new Text("Online Scores");
onlineScoresTitle.getStyleClass().add("heading");
scoreLists.getChildren().add(onlineScoresTitle);
scoreLists.setAlignment(Pos.CENTER);
scoreLists.setSpacing(100);
widgets.setAlignment(Pos.CENTER);
widgets.setSpacing(20);
mainPane.setCenter(widgets);
}
public void checkHiScore() {
boolean isHiScore = false;
int score = this.game.getScore().get();
for (Pair<String, Integer> nameScore : this.localScores) {
if (nameScore.getValue() < score) {
isHiScore = true;
break;
}
}
if (isHiScore) {
logger.info("User has got a high score");
Text hiScoreTitle = new Text("You've got a new High Score!");
hiScoreTitle.getStyleClass().add("title");
widgets.getChildren().add(hiScoreTitle);
TextField usernameEntry = new TextField();
usernameEntry.setPromptText("Enter username");
usernameEntry.requestFocus();
widgets.getChildren().add(usernameEntry);
Button submitBtn = new Button("Submit");
widgets.getChildren().add(submitBtn);
submitBtn.setOnAction(e -> {
this.localScores.add(new Pair<>(usernameEntry.getText(), score));
this.widgets.getChildren().remove(usernameEntry);
this.widgets.getChildren().remove(submitBtn);
this.writeScores((List<Pair<String, Integer>>) localScores);
this.localScores.sort(new Comparator<Pair<String, Integer>>() {
@Override
public int compare(Pair<String, Integer> l1, Pair<String, Integer> l2) {
if (l1.getValue() > l2.getValue()) {
return -1;
} else if (l1.getValue().equals(l2.getValue())) {
return 0;
} else {
return 1;
}
}
});
localList.getScores().bind(new SimpleListProperty<>(this.localScores));
localList.reveal();
Multimedia.playSound("pling.wav");
});
} else {
logger.info("User does not have a high score");
Text hiScoreTitle = new Text("High Scores");
hiScoreTitle.getStyleClass().add("title");
widgets.getChildren().add(hiScoreTitle);
localList.getScores().bind(new SimpleListProperty<>(this.localScores));
localList.reveal();
}
}
private void escapeToMenu(KeyEvent e) {
if (e.getCode().equals(KeyCode.ESCAPE)) {
public static ArrayList<Pair<String, Integer>> loadScores() {
logger.info("Loading scores from file");
ArrayList<Pair<String, Integer>> localScores = new ArrayList<>();
try{
BufferedReader br = new BufferedReader(new FileReader("localscores.txt"));
String line = br.readLine();
while(line != null) {
String[] values = line.split(":");
localScores.add(new Pair<>(values[0], Integer.parseInt(values[1])));
line = br.readLine();
}
br.close();
} catch(IOException e) {
logger.info("Error reading file: " + e.getMessage());
}
localScores.sort(new Comparator<Pair<String, Integer>>() {
@Override
public int compare(Pair<String, Integer> l1, Pair<String, Integer> l2) {
if (l1.getValue() > l2.getValue()) {
return -1;
} else if (l1.getValue().equals(l2.getValue())) {
return 0;
} else {
return 1;
}
}
});
return localScores;
}
public void writeScores(List<Pair<String, Integer>> nameScores) {
logger.info("Writing scores to text file");
try {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("localscores.txt")));
for (Pair<String, Integer> nameScore : nameScores) {
bw.write(nameScore.getKey() + ":" + nameScore.getValue());
bw.newLine();
}
bw.close();
} catch (Exception e) {
logger.info("Error writing to file: " + e.getMessage());
}
}
private void escapeToMenu() {
Multimedia.stopSound();
this.gameWindow.startMenu();
}
}
}
package uk.ac.soton.comp1206.ui;
import javafx.animation.Animation;
import javafx.animation.FadeTransition;
import javafx.animation.SequentialTransition;
import javafx.animation.Transition;
import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.collections.ListChangeListener;
import javafx.geometry.Pos;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import javafx.util.Duration;
import javafx.util.Pair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import uk.ac.soton.comp1206.component.GameBlock;
import java.util.ArrayList;
public class ScoresList extends VBox {
private static final Logger logger = LogManager.getLogger(ScoresList.class);
public final SimpleListProperty<Pair<String, Integer>> scores = new SimpleListProperty();
private ArrayList<Text> nameScores = new ArrayList<>();
private String listName;
public ScoresList(String listName) {
setVisible(false);
getStyleClass().add("scorelist");
this.listName = listName;
setSpacing(5);
setAlignment(Pos.CENTER);
this.scores.addListener((ListChangeListener<? super Pair<String, Integer>>) e -> updateList());
}
public void updateList() {
logger.info("Updating score list");
nameScores.clear();
getChildren().clear();
Text title = new Text(listName);
title.getStyleClass().add("heading");
getChildren().add(title);
int i = 0;
for (Pair<String, Integer> score : scores) {
i++;
if (i > 10) {
break;
}
Text nameScore = new Text(score.getKey() + ": " + score.getValue());
nameScore.setTextAlignment(TextAlignment.CENTER);
nameScore.setFill(GameBlock.COLOURS[i]);
nameScores.add(nameScore);
getChildren().add(nameScore);
}
}
public void reveal() {
logger.info("Playing reveal animations");
setVisible(true);
SequentialTransition sq = new SequentialTransition();
for (Text nameScore : nameScores) {
FadeTransition ft = new FadeTransition(Duration.millis(250), nameScore);
ft.setFromValue(0);
ft.setToValue(1);
sq.getChildren().add(ft);
}
sq.play();
}
public ListProperty<Pair<String, Integer>> getScores() {
return this.scores;
}
}
......@@ -114,7 +114,7 @@
}
.scorelist {
-fx-font-size: 20px;
-fx-font-size: 18px;
-fx-font-family: 'Orbitron';
}
......
No preview for this file type
......@@ -114,7 +114,7 @@
}
.scorelist {
-fx-font-size: 20px;
-fx-font-size: 18px;
-fx-font-family: 'Orbitron';
}
......
No preview for this file type
No preview for this file type
No preview for this file type
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment