java code
level: beginner
write a method
public void updateTrailColors()
This is a helper method that recolors the non-obstacle shapes in the GUI. This could be used after every move or when we reload the game from Streamline backend. Recall that you have created circles for all spaces without obstacles. So for this method, simply set the fill color to either transparent or the color of your choice (go ahead and change the TRAIL_COLOR constant) depending on game.currentState.board.
public void resetGrid()
When we start the game, we want to make sure that the previous game settings are cleared and the current state is correctly loaded. This function will be useful when the player passes one level and a new game is loaded. In this method:
- Check the instance variables and determine which ones of them should be cleared
- Reset corresponding variables based on the current board stored in Streamline object
public void onLevelLoaded()
This method should be called after a completely new level has been loaded into the game instance variable, including the first level. Before calling this, we either have a blank (or mostly blank scene) or else a scene that doesn't match game.currentState at all (most likely from a previous level). After calling this, the UI should be in agreement with game.currentState.
Notice how resetGrid() would be helpful here.
public void onPlayerMoved(int fromCol, int fromRow, int toCol, int toRow, boolean isUndo)
When a key is pressed by the player, this method will be called by the event handler that you will implement soon. This method is similar to onLevelLoaded() but you only need to update the trail and don't have to reset the whole board.
public void onLevelFinished()
Most of this method is completed, read through it to make sure you understand its' logic. What you will implement is the EventHandler called when the ScaleTransition animation terminates in line 244. Here you will try making use of Lambda Expressions which are a simpler way to define a class that is supposed to override one method in an interface.
Therefore in this block, you will implement the behaviors when the animation is finished. Basically:
- Check if there are more levels of games to read in
- If yes, load next level of game; If not, end the game.
The method onLevelLoaded() should be of help here.
In Sreamline class -
import javafx.scene.; import javafx.scene. shape.*; import javafx.stage.Stage; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javafx.animation.*; import javafx.animation.PathTransition.*; import javafx.application.Application; import javafx.event.EventHandler; import javafx.event.ActionEvent; import javafx.scene.Group; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.paint.*; import javafx.util.Duration; public class Guistreamline extends Application static final double SCENE WIDTH 500; static final double SCENE-HEIGHT = 600; static final String TITLE "CSE 8b Streamline GUI"; static final String USAGE = "Usage: In" + "> java Guistreamline - to start a game with default" + - to start a game by reading g" + "> java Guistreamline
to start a game by reading a"+ the specified directory and "+ " size 6 5 and random obstacles + " java GuiStreamline "ame state from the specified fileln"+ "1l game states from files inln" + "playing them in order n" static final Color TRAIL COLOR Color.PALEVIOLETRED static final Color GOAL_COLOR Color.MEDIUMAQUAMARINE; static final Color OBSTACLE-COLOR = Color. DIMGRAY; Trail radius will be set to this fraction of the size of a board square static final double TRAIL RADIUS FRACTION = 0.1 // Squares wilL be resized to this fraction of the size of a board square static final double SQUAREFRACTION # 0.8; - Scene mainScene; Group leve1Group; Group rootGroup; Player playerRect Roundedsquare goalRect; // For obstacles and trails / Parent group for everything else 7 GUI representation of the player 77 GUI representation of the goal Shape []I] grid; 7 Same dimensions as the game board Streamline game; /The current Level // Future Levels ArrayListstreamline> nextGames; MyKeyHandler mykeyHandler; / for keyboard input /returns the width of the board for the current Level public int getBoardwidth) return game.currentState.board[0].length; // the height of the board for the current Level public int getBoardHeight() return game.currentState.board.length; Find a size for a single square of the board that will fit nicely //in the current scene size. public double getsquaresize)f For example, given a scene size of 1000 by 600 and a board size of 5 by 6, we have room for each square to be 200x100. Since we want squares not rectangles, return the minimum which is 100 in this example. return 1ee; // Destroy and recreate grid and all trail and obstacle shapes. /Assumes the dimensions of the board may have changed public void resetGrid) f TODO/ / Hints: Empty out grid, trailsGroup, and obstaclesGroup. ALso makes sure grid is the right size, in case the size of the // board changed. // Sets the fill color of all trail Circles making them visible or not / depending on if that board position equals TRAIL CHAR public void updateTrailcolors) t TODO/ rooe Coverts the given board column and row into scene coordinates Gives the center of the corresponding tile. @param boardCol a board column to be converted to a scene x @param boardRow a board row to be converted to a sceney , @return scene coordinates as Length 2 array where index S X static final double MIDDLE OFFSET-0.5; public double[] boardIdxToScenePos (int boardCol, int boardRow) f double sceneX ((boardco1 + MIDDLE-OFFSET) * double sceneV = ((boardRow + MIDDLE OFFSET) * return new double[](scenex, sceneYj; (mainScene.getwidth) 1)) / getBoardwidth(): (mainScene.getHeight() 1)) / getBoardHeight); / Makes trail markers visible and changes player position. / To be called when the user moved the player and the GUI needs to be /7 updated to show the new position / Parameters are the old position, new position, and whether it was an // undo movement. public void onPlayerMoved (int fromCol, int fromRow, int toCol, int toRow, boolean isUndo) // If the position is the same, just return if (fromCol - tocol && fromRow toRow) t PT000 / To be called when a key is pressed // To be called whenever the UI needs to be completely redone to reflect // a new Level public void onLevelLoaded () reset rid) double squareSize getSquareSize) SQUARE FRACTION; // Update the player position double[] playerPos boardIdxToscenePos game.currentstate.playerCol, game.currentstate.playerRow playerRect.setSize(squareSize); playerRect.setcenterX(playerPos [e]): playerRect.setCenterY (playerPos [1]); TODO/ ann / Called when the player reaches the goal. Shows the winning animation and Loads the next level if there is one static final double SCALE-TIME-175; // milliseconds for scale animation static final double FADE_TIME 250; milliseconds for fade animation static final double DOUBLE-MULTIPLIER 2; public void onLevelFinished () ( /7Clone the goal rectangle and scale it up until it covers the screen 7Clone the goal rectangle Rectangle animat edGoal = new Rectangle( goalRect.getx) goalRect.getY), goalRect.getwidth(), goalRect.getHeight( animatedGoal.setFill (goalRect.getFill)); // Add the clone to the scene List previousstates; public Streamline()f this.currentState new Gamestate(DEFAULT-HEGHT, DEFAULT-WIDTH, - DEFAULT PLAYERROW, DEFAULT PLAYERCOL DEFAULT GOALROW, DEFAULT GOALCOL); currentstate.addRandomObstacles (DEFAULT_OBSTACLES); this.previousStates new ArrayList); public Streamline (String filename) ( try loadFromFile(filename); ) catch (IOException e) f e.printstackTrace() protected void loadFromFile(String filename) throws IOException t Scanner scannernew Scanner(new File(filename)); int height scanner.nextInt); int width scanner.nextInt); int playerRold scanner.nextInt(); int playerco1 scanner.nextInt(); int goalRow Scanner.nextInt(): int goalcol # scanner.nextInt(); Gamestate gameLoad new GameState (height, width, playerRow, playerCol, goalRow, goalCol) string emptyString = scanner.nextLine(); while (row e) t for (int colone = 0; colone O; //Check if gameover if (goalRow player Row && goalcol -playerCol)f currentState.levelPassed - true; return; void play() while(currentstate.levelPassed !-true) System.out.println(currentstate.toString ()); System.out.print(">) Scanner theUser new Scanner (System.in); string theinput theUser.nextLine(); if ("w".equals (theInput)) t recordAndMove (Direction.UP); else if("a".equals (theInput)) f recordAndMove (Direction. LEFT); else if ("s".equals (theInput)) t recordAndMove (Direction. DOWN); else if ("d".equals (theInput)) t recordAndMove (Direction. RIGHT) else if ("u".equals (theInput)) undo (); else if ("o".equals (theInput)) t this.saveToFile() else if ("q".equals (theInput)) [ return; else System.out.println("Wrong Input, Try Again."); System.out.println(currentstate.tostring)); if (currentstate.levelPassed true) System.out.println("Level Passed!"); return void saveToFile) f try t PrintWriter saveFile new PrintWriter(OUTFILE NAME); String stringone currentstate.board.length SPACE_STRING + currentstate.board[e].length; saveFile.println(stringone); String stringTwo currentState.playerRow SPACE _STRING + currentstate.playerCol; saveFile.println(stringTwo); String stringThree currentState.goalRow SPACE_STRING currentstate.goalcol; saveFile.println (stringThree); for Loop the currentState's board and then print for (int i-e; icurrentState.board.length; H) { for (int j ; jcurrentState.board[e].1ength; j++) { if (currentState.board[i][j]SPACE CHAR){ saveFile.print (SPACE STRING); else ( saveFile.print (currentState.board[i][j]); saveFile.println); saveFile.close(): System.out.println("Saved current state to: saved streamline_game"); throw new IOException ): catch (IOException e) f e.printstackTrace (); import javafx.scene.; import javafx.scene. shape.*; import javafx.stage.Stage; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javafx.animation.*; import javafx.animation.PathTransition.*; import javafx.application.Application; import javafx.event.EventHandler; import javafx.event.ActionEvent; import javafx.scene.Group; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.paint.*; import javafx.util.Duration; public class Guistreamline extends Application static final double SCENE WIDTH 500; static final double SCENE-HEIGHT = 600; static final String TITLE "CSE 8b Streamline GUI"; static final String USAGE = "Usage: In" + "> java Guistreamline - to start a game with default" + - to start a game by reading g" + "> java Guistreamline to start a game by reading a"+ the specified directory and "+ " size 6 5 and random obstacles + " java GuiStreamline "ame state from the specified fileln"+ "1l game states from files inln" + "playing them in order n" static final Color TRAIL COLOR Color.PALEVIOLETRED static final Color GOAL_COLOR Color.MEDIUMAQUAMARINE; static final Color OBSTACLE-COLOR = Color. DIMGRAY; Trail radius will be set to this fraction of the size of a board square static final double TRAIL RADIUS FRACTION = 0.1 // Squares wilL be resized to this fraction of the size of a board square static final double SQUAREFRACTION # 0.8; - Scene mainScene; Group leve1Group; Group rootGroup; Player playerRect Roundedsquare goalRect; // For obstacles and trails / Parent group for everything else 7 GUI representation of the player 77 GUI representation of the goal Shape []I] grid; 7 Same dimensions as the game board Streamline game; /The current Level // Future Levels ArrayListstreamline> nextGames; MyKeyHandler mykeyHandler; / for keyboard input /returns the width of the board for the current Level public int getBoardwidth) return game.currentState.board[0].length; // the height of the board for the current Level public int getBoardHeight() return game.currentState.board.length; Find a size for a single square of the board that will fit nicely //in the current scene size. public double getsquaresize)f For example, given a scene size of 1000 by 600 and a board size of 5 by 6, we have room for each square to be 200x100. Since we want squares not rectangles, return the minimum which is 100 in this example. return 1ee; // Destroy and recreate grid and all trail and obstacle shapes. /Assumes the dimensions of the board may have changed public void resetGrid) f TODO/ / Hints: Empty out grid, trailsGroup, and obstaclesGroup. ALso makes sure grid is the right size, in case the size of the // board changed. // Sets the fill color of all trail Circles making them visible or not / depending on if that board position equals TRAIL CHAR public void updateTrailcolors) t TODO/ rooe Coverts the given board column and row into scene coordinates Gives the center of the corresponding tile. @param boardCol a board column to be converted to a scene x @param boardRow a board row to be converted to a sceney , @return scene coordinates as Length 2 array where index S X static final double MIDDLE OFFSET-0.5; public double[] boardIdxToScenePos (int boardCol, int boardRow) f double sceneX ((boardco1 + MIDDLE-OFFSET) * double sceneV = ((boardRow + MIDDLE OFFSET) * return new double[](scenex, sceneYj; (mainScene.getwidth) 1)) / getBoardwidth(): (mainScene.getHeight() 1)) / getBoardHeight); / Makes trail markers visible and changes player position. / To be called when the user moved the player and the GUI needs to be /7 updated to show the new position / Parameters are the old position, new position, and whether it was an // undo movement. public void onPlayerMoved (int fromCol, int fromRow, int toCol, int toRow, boolean isUndo) // If the position is the same, just return if (fromCol - tocol && fromRow toRow) t PT000 / To be called when a key is pressed // To be called whenever the UI needs to be completely redone to reflect // a new Level public void onLevelLoaded () reset rid) double squareSize getSquareSize) SQUARE FRACTION; // Update the player position double[] playerPos boardIdxToscenePos game.currentstate.playerCol, game.currentstate.playerRow playerRect.setSize(squareSize); playerRect.setcenterX(playerPos [e]): playerRect.setCenterY (playerPos [1]); TODO/ ann / Called when the player reaches the goal. Shows the winning animation and Loads the next level if there is one static final double SCALE-TIME-175; // milliseconds for scale animation static final double FADE_TIME 250; milliseconds for fade animation static final double DOUBLE-MULTIPLIER 2; public void onLevelFinished () ( /7Clone the goal rectangle and scale it up until it covers the screen 7Clone the goal rectangle Rectangle animat edGoal = new Rectangle( goalRect.getx) goalRect.getY), goalRect.getwidth(), goalRect.getHeight( animatedGoal.setFill (goalRect.getFill)); // Add the clone to the scene List previousstates; public Streamline()f this.currentState new Gamestate(DEFAULT-HEGHT, DEFAULT-WIDTH, - DEFAULT PLAYERROW, DEFAULT PLAYERCOL DEFAULT GOALROW, DEFAULT GOALCOL); currentstate.addRandomObstacles (DEFAULT_OBSTACLES); this.previousStates new ArrayList); public Streamline (String filename) ( try loadFromFile(filename); ) catch (IOException e) f e.printstackTrace() protected void loadFromFile(String filename) throws IOException t Scanner scannernew Scanner(new File(filename)); int height scanner.nextInt); int width scanner.nextInt); int playerRold scanner.nextInt(); int playerco1 scanner.nextInt(); int goalRow Scanner.nextInt(): int goalcol # scanner.nextInt(); Gamestate gameLoad new GameState (height, width, playerRow, playerCol, goalRow, goalCol) string emptyString = scanner.nextLine(); while (row e) t for (int colone = 0; colone O; //Check if gameover if (goalRow player Row && goalcol -playerCol)f currentState.levelPassed - true; return; void play() while(currentstate.levelPassed !-true) System.out.println(currentstate.toString ()); System.out.print(">) Scanner theUser new Scanner (System.in); string theinput theUser.nextLine(); if ("w".equals (theInput)) t recordAndMove (Direction.UP); else if("a".equals (theInput)) f recordAndMove (Direction. LEFT); else if ("s".equals (theInput)) t recordAndMove (Direction. DOWN); else if ("d".equals (theInput)) t recordAndMove (Direction. RIGHT) else if ("u".equals (theInput)) undo (); else if ("o".equals (theInput)) t this.saveToFile() else if ("q".equals (theInput)) [ return; else System.out.println("Wrong Input, Try Again."); System.out.println(currentstate.tostring)); if (currentstate.levelPassed true) System.out.println("Level Passed!"); return void saveToFile) f try t PrintWriter saveFile new PrintWriter(OUTFILE NAME); String stringone currentstate.board.length SPACE_STRING + currentstate.board[e].length; saveFile.println(stringone); String stringTwo currentState.playerRow SPACE _STRING + currentstate.playerCol; saveFile.println(stringTwo); String stringThree currentState.goalRow SPACE_STRING currentstate.goalcol; saveFile.println (stringThree); for Loop the currentState's board and then print for (int i-e; icurrentState.board.length; H) { for (int j ; jcurrentState.board[e].1ength; j++) { if (currentState.board[i][j]SPACE CHAR){ saveFile.print (SPACE STRING); else ( saveFile.print (currentState.board[i][j]); saveFile.println); saveFile.close(): System.out.println("Saved current state to: saved streamline_game"); throw new IOException ): catch (IOException e) f e.printstackTrace ()