[FEAT] Add basic instructions and show current piece during game
This commit is contained in:
@@ -122,11 +122,11 @@ public class GameBlock extends Canvas {
|
|||||||
gc.clearRect(0,0,width,height);
|
gc.clearRect(0,0,width,height);
|
||||||
|
|
||||||
//Fill
|
//Fill
|
||||||
gc.setFill(Color.WHITE);
|
gc.setFill(Color.web("111111",0.5));
|
||||||
gc.fillRect(0,0, width, height);
|
gc.fillRect(0,0, width, height);
|
||||||
|
|
||||||
//Border
|
//Border
|
||||||
gc.setStroke(Color.BLACK);
|
gc.setStroke(Color.GRAY);
|
||||||
gc.strokeRect(0,0,width,height);
|
gc.strokeRect(0,0,width,height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ public class GameBlock extends Canvas {
|
|||||||
gc.fillRect(0,0, width, height);
|
gc.fillRect(0,0, width, height);
|
||||||
|
|
||||||
//Border
|
//Border
|
||||||
gc.setStroke(Color.BLACK);
|
gc.setStroke(Color.GRAY);
|
||||||
gc.strokeRect(0,0,width,height);
|
gc.strokeRect(0,0,width,height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public class GameBoard extends GridPane {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new GameBoard with it's own internal grid, specifying the number of columns and rows, along with the
|
* Create a new GameBoard with its own internal grid, specifying the number of columns and rows, along with the
|
||||||
* visual width and height.
|
* visual width and height.
|
||||||
*
|
*
|
||||||
* @param cols number of columns for internal grid
|
* @param cols number of columns for internal grid
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package uk.mgrove.ac.soton.comp1206.component;
|
||||||
|
|
||||||
|
import uk.mgrove.ac.soton.comp1206.game.GamePiece;
|
||||||
|
import uk.mgrove.ac.soton.comp1206.game.Grid;
|
||||||
|
|
||||||
|
public class PieceBoard extends GameBoard {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new GameBoard with it's own internal grid, specifying the number of columns and rows, along with the
|
||||||
|
* visual width and height.
|
||||||
|
*
|
||||||
|
* @param width the visual width
|
||||||
|
* @param height the visual height
|
||||||
|
*/
|
||||||
|
public PieceBoard(double width, double height) {
|
||||||
|
super(3, 3, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void displayPiece(GamePiece piece) {
|
||||||
|
grid.clearGrid();
|
||||||
|
grid.playPiece(piece,1,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package uk.mgrove.ac.soton.comp1206.event;
|
||||||
|
|
||||||
|
import uk.mgrove.ac.soton.comp1206.game.GamePiece;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Next Piece Listener is used for listening for new pieces being provided to the game.
|
||||||
|
*/
|
||||||
|
public interface NextPieceListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a new piece being received by the game
|
||||||
|
* @param piece the piece that was received
|
||||||
|
*/
|
||||||
|
public void nextPiece(GamePiece piece);
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import javafx.beans.property.SimpleIntegerProperty;
|
|||||||
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.GameBlock;
|
import uk.mgrove.ac.soton.comp1206.component.GameBlock;
|
||||||
|
import uk.mgrove.ac.soton.comp1206.event.NextPieceListener;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -61,6 +62,11 @@ public class Game {
|
|||||||
*/
|
*/
|
||||||
protected IntegerProperty multiplier = new SimpleIntegerProperty(1);
|
protected IntegerProperty multiplier = new SimpleIntegerProperty(1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener for when new piece is received by the game
|
||||||
|
*/
|
||||||
|
private NextPieceListener nextPieceListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
* @param cols number of columns
|
* @param cols number of columns
|
||||||
@@ -88,6 +94,7 @@ public class Game {
|
|||||||
*/
|
*/
|
||||||
public GamePiece nextPiece() {
|
public GamePiece nextPiece() {
|
||||||
currentPiece = spawnPiece();
|
currentPiece = spawnPiece();
|
||||||
|
if (nextPieceListener != null) nextPieceListener.nextPiece(currentPiece);
|
||||||
logger.info("Next piece is: {}", currentPiece);
|
logger.info("Next piece is: {}", currentPiece);
|
||||||
return currentPiece;
|
return currentPiece;
|
||||||
}
|
}
|
||||||
@@ -317,4 +324,13 @@ public class Game {
|
|||||||
public IntegerProperty scoreProperty() {
|
public IntegerProperty scoreProperty() {
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set next piece listener
|
||||||
|
* @param listener listener to set
|
||||||
|
*/
|
||||||
|
public void setNextPieceListener(NextPieceListener listener) {
|
||||||
|
nextPieceListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,6 +147,16 @@ public class Grid {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearGrid() {
|
||||||
|
for (var x = 0; x < getCols(); x++) {
|
||||||
|
for (var y = 0; y < getRows(); y++) {
|
||||||
|
if (get(x,y) != 0) {
|
||||||
|
set(x,y,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number of columns in this game
|
* Get the number of columns in this game
|
||||||
* @return number of columns
|
* @return number of columns
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
package uk.mgrove.ac.soton.comp1206.scene;
|
package uk.mgrove.ac.soton.comp1206.scene;
|
||||||
|
|
||||||
|
import javafx.scene.input.KeyCode;
|
||||||
import javafx.scene.layout.*;
|
import javafx.scene.layout.*;
|
||||||
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.GameBlock;
|
import uk.mgrove.ac.soton.comp1206.component.GameBlock;
|
||||||
import uk.mgrove.ac.soton.comp1206.component.GameBoard;
|
import uk.mgrove.ac.soton.comp1206.component.GameBoard;
|
||||||
|
import uk.mgrove.ac.soton.comp1206.component.PieceBoard;
|
||||||
|
import uk.mgrove.ac.soton.comp1206.event.NextPieceListener;
|
||||||
import uk.mgrove.ac.soton.comp1206.game.Game;
|
import uk.mgrove.ac.soton.comp1206.game.Game;
|
||||||
|
import uk.mgrove.ac.soton.comp1206.game.GamePiece;
|
||||||
import uk.mgrove.ac.soton.comp1206.ui.GamePane;
|
import uk.mgrove.ac.soton.comp1206.ui.GamePane;
|
||||||
import uk.mgrove.ac.soton.comp1206.ui.GameWindow;
|
import uk.mgrove.ac.soton.comp1206.ui.GameWindow;
|
||||||
import uk.mgrove.ac.soton.comp1206.ui.StatsMenu;
|
import uk.mgrove.ac.soton.comp1206.ui.StatsMenu;
|
||||||
@@ -19,6 +23,11 @@ public class ChallengeScene extends BaseScene {
|
|||||||
private static final Logger logger = LogManager.getLogger(MenuScene.class);
|
private static final Logger logger = LogManager.getLogger(MenuScene.class);
|
||||||
protected Game game;
|
protected Game game;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PieceBoard to display current piece
|
||||||
|
*/
|
||||||
|
private PieceBoard currentPieceBoard;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new Single Player challenge scene
|
* Create a new Single Player challenge scene
|
||||||
* @param gameWindow the Game Window
|
* @param gameWindow the Game Window
|
||||||
@@ -52,7 +61,13 @@ public class ChallengeScene extends BaseScene {
|
|||||||
mainPane.setCenter(board);
|
mainPane.setCenter(board);
|
||||||
|
|
||||||
var statsMenu = new StatsMenu(game.scoreProperty(),game.levelProperty(),game.livesProperty(),game.multiplierProperty());
|
var statsMenu = new StatsMenu(game.scoreProperty(),game.levelProperty(),game.livesProperty(),game.multiplierProperty());
|
||||||
mainPane.setRight(statsMenu);
|
|
||||||
|
currentPieceBoard = new PieceBoard(100, 100);
|
||||||
|
|
||||||
|
var rightMenu = new VBox();
|
||||||
|
rightMenu.getChildren().addAll(statsMenu,currentPieceBoard);
|
||||||
|
|
||||||
|
mainPane.setRight(rightMenu);
|
||||||
|
|
||||||
Multimedia.playMusic("music/game.wav");
|
Multimedia.playMusic("music/game.wav");
|
||||||
|
|
||||||
@@ -84,7 +99,28 @@ public class ChallengeScene extends BaseScene {
|
|||||||
@Override
|
@Override
|
||||||
public void initialise() {
|
public void initialise() {
|
||||||
logger.info("Initialising Challenge");
|
logger.info("Initialising Challenge");
|
||||||
|
|
||||||
|
// exit challenge when escape key pressed
|
||||||
|
scene.setOnKeyPressed((event) -> {
|
||||||
|
if (event.getCode() == KeyCode.ESCAPE) {
|
||||||
|
returnToMenu();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
game.setNextPieceListener(this::setCurrentPiece);
|
||||||
|
|
||||||
game.start();
|
game.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void returnToMenu() {
|
||||||
|
// TODO: any processing to end game
|
||||||
|
|
||||||
|
|
||||||
|
gameWindow.startMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setCurrentPiece(GamePiece piece) {
|
||||||
|
currentPieceBoard.displayPiece(piece);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
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;
|
||||||
|
import javafx.scene.layout.GridPane;
|
||||||
|
import javafx.scene.layout.StackPane;
|
||||||
|
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.GamePiece;
|
||||||
|
import uk.mgrove.ac.soton.comp1206.ui.GamePane;
|
||||||
|
import uk.mgrove.ac.soton.comp1206.ui.GameWindow;
|
||||||
|
|
||||||
|
public class InstructionsScene extends BaseScene {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logger
|
||||||
|
*/
|
||||||
|
private static final Logger logger = LogManager.getLogger(InstructionsScene.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new scene, passing in the GameWindow the scene will be displayed in
|
||||||
|
*
|
||||||
|
* @param gameWindow the game window
|
||||||
|
*/
|
||||||
|
public InstructionsScene(GameWindow gameWindow) {
|
||||||
|
super(gameWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise this scene. Called after creation
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void initialise() {
|
||||||
|
logger.info("Initialising Instructions");
|
||||||
|
|
||||||
|
// exit challenge when escape key pressed
|
||||||
|
scene.setOnKeyPressed((event) -> {
|
||||||
|
if (event.getCode() == KeyCode.ESCAPE) {
|
||||||
|
gameWindow.startMenu();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the layout of the scene
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void build() {
|
||||||
|
logger.info("Building " + this.getClass().getName());
|
||||||
|
|
||||||
|
root = new GamePane(gameWindow.getWidth(),gameWindow.getHeight());
|
||||||
|
|
||||||
|
var menuPane = new StackPane();
|
||||||
|
menuPane.setMaxWidth(gameWindow.getWidth());
|
||||||
|
menuPane.setMaxHeight(gameWindow.getHeight());
|
||||||
|
menuPane.getStyleClass().add("menu-background");
|
||||||
|
root.getChildren().add(menuPane);
|
||||||
|
|
||||||
|
var mainPane = new BorderPane();
|
||||||
|
menuPane.getChildren().add(mainPane);
|
||||||
|
|
||||||
|
//Awful title
|
||||||
|
var title = new Text("How to Play");
|
||||||
|
title.getStyleClass().add("title");
|
||||||
|
mainPane.setTop(title);
|
||||||
|
BorderPane.setAlignment(title, Pos.TOP_CENTER);
|
||||||
|
|
||||||
|
var instructions = new ImageView(getClass().getResource("/images/Instructions.png").toExternalForm());
|
||||||
|
instructions.setPreserveRatio(true);
|
||||||
|
instructions.setFitHeight(gameWindow.getHeight()*0.55);
|
||||||
|
mainPane.setCenter(instructions);
|
||||||
|
|
||||||
|
var pieceGrid = new GridPane();
|
||||||
|
pieceGrid.setVgap(8);
|
||||||
|
pieceGrid.setHgap(8);
|
||||||
|
for (var i = 0; i < GamePiece.PIECES; i++) {
|
||||||
|
var pieceBoard = new PieceBoard(48, 48);
|
||||||
|
pieceBoard.displayPiece(GamePiece.createPiece(i));
|
||||||
|
pieceGrid.add(pieceBoard, i % 5, Math.floorDiv(i,5));
|
||||||
|
}
|
||||||
|
|
||||||
|
var allPieces = new VBox();
|
||||||
|
var piecesHeader = new Text("Game Pieces");
|
||||||
|
piecesHeader.getStyleClass().add("title");
|
||||||
|
allPieces.getChildren().addAll(piecesHeader,pieceGrid);
|
||||||
|
allPieces.setAlignment(Pos.BOTTOM_CENTER);
|
||||||
|
pieceGrid.setAlignment(Pos.BOTTOM_CENTER);
|
||||||
|
|
||||||
|
mainPane.setBottom(allPieces);
|
||||||
|
BorderPane.setAlignment(allPieces, Pos.BOTTOM_CENTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -15,6 +15,9 @@ import uk.mgrove.ac.soton.comp1206.util.Multimedia;
|
|||||||
*/
|
*/
|
||||||
public class MenuScene extends BaseScene {
|
public class MenuScene extends BaseScene {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logger
|
||||||
|
*/
|
||||||
private static final Logger logger = LogManager.getLogger(MenuScene.class);
|
private static final Logger logger = LogManager.getLogger(MenuScene.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -49,14 +52,22 @@ public class MenuScene extends BaseScene {
|
|||||||
title.getStyleClass().add("title");
|
title.getStyleClass().add("title");
|
||||||
mainPane.setTop(title);
|
mainPane.setTop(title);
|
||||||
|
|
||||||
//For now, let us just add a button that starts the game. I'm sure you'll do something way better.
|
var menuItems = new VBox();
|
||||||
var button = new Button("Play");
|
var singlePlayerButton = new Button("Single Player");
|
||||||
mainPane.setCenter(button);
|
var multiPlayerButton = new Button("Multi Player");
|
||||||
|
var howToPlayButton = new Button("How to Play");
|
||||||
|
var exitButton = new Button("Exit");
|
||||||
|
menuItems.getChildren().addAll(singlePlayerButton,multiPlayerButton,howToPlayButton,exitButton);
|
||||||
|
mainPane.setCenter(menuItems);
|
||||||
|
|
||||||
|
// TOOD: window animations
|
||||||
|
|
||||||
Multimedia.playMusic("music/menu.mp3");
|
Multimedia.playMusic("music/menu.mp3");
|
||||||
|
|
||||||
//Bind the button action to the startGame method in the menu
|
//Bind the button action to the startGame method in the menu
|
||||||
button.setOnAction(this::startGame);
|
singlePlayerButton.setOnAction(this::startSinglePlayer);
|
||||||
|
multiPlayerButton.setOnAction(this::startMultiPlayer);
|
||||||
|
howToPlayButton.setOnAction(this::showInstructions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -68,11 +79,27 @@ public class MenuScene extends BaseScene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle when the Start Game button is pressed
|
* Handle when the Start Single Player Game button is pressed
|
||||||
* @param event event
|
* @param event event
|
||||||
*/
|
*/
|
||||||
private void startGame(ActionEvent event) {
|
private void startSinglePlayer(ActionEvent event) {
|
||||||
gameWindow.startChallenge();
|
gameWindow.startChallenge();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle when the Start Multiplayer Game button is pressed
|
||||||
|
* @param event event
|
||||||
|
*/
|
||||||
|
private void startMultiPlayer(ActionEvent event) {
|
||||||
|
gameWindow.startMultiplayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle when the How to Play button is pressed
|
||||||
|
* @param event event
|
||||||
|
*/
|
||||||
|
private void showInstructions(ActionEvent event) {
|
||||||
|
gameWindow.startInstructions();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,6 +88,18 @@ public class GameWindow {
|
|||||||
*/
|
*/
|
||||||
public void startChallenge() { loadScene(new ChallengeScene(this)); }
|
public void startChallenge() { loadScene(new ChallengeScene(this)); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the multiplayer challenge
|
||||||
|
*/
|
||||||
|
public void startMultiplayer() {
|
||||||
|
// TODO: load multiplayer scene
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the instructions
|
||||||
|
*/
|
||||||
|
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.
|
* Setup the default settings for the stage itself (the window), such as the title and minimum width and height.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import javafx.scene.layout.VBox;
|
|||||||
import javafx.scene.text.Text;
|
import javafx.scene.text.Text;
|
||||||
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.PieceBoard;
|
||||||
import uk.mgrove.ac.soton.comp1206.game.Game;
|
import uk.mgrove.ac.soton.comp1206.game.Game;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,6 +54,7 @@ public class StatsMenu extends VBox {
|
|||||||
var levelHeader = new Text("Level");
|
var levelHeader = new Text("Level");
|
||||||
var livesHeader = new Text("Lives");
|
var livesHeader = new Text("Lives");
|
||||||
var multiplierHeader = new Text("Multiplier");
|
var multiplierHeader = new Text("Multiplier");
|
||||||
|
|
||||||
getChildren().addAll(scoreHeader,this.score,levelHeader,this.level,livesHeader,this.lives,multiplierHeader,this.multiplier);
|
getChildren().addAll(scoreHeader,this.score,levelHeader,this.level,livesHeader,this.lives,multiplierHeader,this.multiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user