package finalproject.system;
import finalproject.*;
import finalproject.tiles.*;
Copyright By PowCoder代写 加微信 powcoder
import javafx.animation.*;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.CheckMenuItem;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.*;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.paint.Color;
import javafx.scene.paint.ImagePattern;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.util.Duration;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Random;
public class Controller {
@FXML VBox root;
@FXML VBox textPanel;
@FXML Pane mapPanel;
@FXML HBox commandPanel;
@FXML ScrollPane messagePanel;
@FXML HBox interfacePanel;
@FXML CheckMenuItem systemLogToggle;
@FXML CheckMenuItem tileTextToggle;
@FXML TextField healthInput;
int tileSize = 100;
int stroke = 0;
ArrayList
ArrayList
MediaPlayer mediaPlayer;
MediaPlayer BGplayer;
MediaPlayer deathPlayer;
MediaPlayer yellMusic1Player;
MediaPlayer yellMusic2Player;
MediaPlayer yellMusic3Player;
MediaPlayer yellMusic4Player;
MediaPlayer arrivePlayer;
MediaPlayer metroTransPlayer;
MediaPlayer letsgoPlayer;
Random rng = new Random(260877596);
public void initialize() {
System.out.println(“init”);
StateManager.getInstance().registerController(this);
systemLogToggle.selectedProperty().addListener((ov, old_val, new_val) -> {
//show system log
Logger.getInstance().toggleSystemLog();
Logger.getInstance().logSystemMessage(systemLogToggle.getText() + ” set to ” + new_val);
tileTextToggle.selectedProperty().addListener((ov, old_val, new_val) -> {
StateManager.getInstance().isTileTextEnabled.set(new_val);
for (Node n : mapPanel.getChildren()) {
if (n instanceof TileComponent)
((TileComponent)n).enableText(new_val);
Logger.getInstance().logSystemMessage(tileTextToggle.getText() + ” set to ” + new_val);
tileTextToggle.selectedProperty().set(StateManager.getInstance().isTileTextEnabled.get());
Logger.getInstance().init(textPanel, messagePanel);
mapPanel.prefWidthProperty().bind(root.widthProperty()); //bind width to its parent’s width
mapPanel.prefHeightProperty().bind(root.heightProperty().multiply(0.85)); //bind height to its parent’s height
interfacePanel.prefWidthProperty().bind(root.widthProperty());
interfacePanel.prefHeightProperty().bind(root.heightProperty().multiply(0.15));
commandPanel.prefWidthProperty().bind(((HBox)commandPanel.getParent()).widthProperty().multiply(0.5)); //bind width to its parent’s width
commandPanel.prefHeightProperty().bind(((HBox)commandPanel.getParent()).heightProperty()); //bind height to its parent’s height
messagePanel.prefWidthProperty().bind(((HBox)commandPanel.getParent()).widthProperty().multiply(0.5)); //bind width to its parent’s width
messagePanel.prefHeightProperty().bind(((HBox)commandPanel.getParent()).heightProperty()); //bind height to its parent’s height
StateManager.getInstance().isInWaypointSelection.addListener((ov, oldVal, newVal)-> {
if (newVal)
onAddingWaypoint();
doneAddingWaypoint();
root.onMouseClickedProperty().set(event -> {
if (StateManager.getInstance().isInWaypointSelection.get() && event.getButton() == MouseButton.SECONDARY) {
StateManager.getInstance().isInWaypointSelection.set(false);
//sound effect set up
String musicFile = “resource/BG_music.wav”; // For example
Media sound = new Media(new File(musicFile).toURI().toString());
BGplayer = new MediaPlayer(sound);
BGplayer.setVolume(0.3);
musicFile = “resource/death.wav”; // For example
Media deathMuisc = new Media(new File(musicFile).toURI().toString());
deathPlayer = new MediaPlayer(deathMuisc);
deathPlayer.setVolume(0.7);
musicFile = “resource/success.mp3”; // For example
Media arrive = new Media(new File(musicFile).toURI().toString());
arrivePlayer = new MediaPlayer(arrive);
arrivePlayer.setVolume(0.3);
musicFile = “resource/yell4.mp3”; // For example
Media yellMusic4 = new Media(new File(musicFile).toURI().toString());
yellMusic4Player = new MediaPlayer(yellMusic4);
yellMusic4Player.setVolume(0.5);
musicFile = “resource/yell3.mp3”; // For example
Media yellMusic3 = new Media(new File(musicFile).toURI().toString());
yellMusic3Player = new MediaPlayer(yellMusic3);
yellMusic3Player.setVolume(0.5);
musicFile = “resource/yell2.mp3”; // For example
Media yellMusic2 = new Media(new File(musicFile).toURI().toString());
yellMusic2Player = new MediaPlayer(yellMusic2);
yellMusic2Player.setVolume(0.5);
musicFile = “resource/yell1.mp3”; // For example
Media yellMusic1 = new Media(new File(musicFile).toURI().toString());
yellMusic1Player = new MediaPlayer(yellMusic1);
yellMusic1Player.setVolume(0.5);
musicFile = “resource/lets_go_mario.mp3”; // For example
Media letsgo = new Media(new File(musicFile).toURI().toString());
letsgoPlayer = new MediaPlayer(letsgo);
letsgoPlayer.setVolume(0.5);
musicFile = “resource/metro_switch.wav”; // For example
Media metroTrans = new Media(new File(musicFile).toURI().toString());
metroTransPlayer = new MediaPlayer(metroTrans);
metroTransPlayer.setVolume(0.5);
musicFile = “resource/flip.mp3”; // For example
Media flipSound = new Media(new File(musicFile).toURI().toString());
mediaPlayer = new MediaPlayer(flipSound);
mediaPlayer.setVolume(1);
public void startSimulation() {
if (!StateManager.getInstance().isMapInitialized.get()) return;
if (StateManager.getInstance().currentPath == null) return;
StateManager.getInstance().isInSimulation.set(true);
Logger.getInstance().logSystemMessage(“start simulation”);
ArrayList
//spawn a agent that follows the current path based on the cost
//setup animation
int agentWidth = 50;
int agentHeight = 50;
Rectangle agent = new Rectangle(agentWidth,agentHeight);
mapPanel.getChildren().add(agent);
ArrayList
//Setting Color and Stroke properties for the polygon
Image img = new Image(“file:./resource/hiker.png”);
agent.setFill(new ImagePattern(img));
int currentHealth = Integer.parseInt(healthInput.getText());
//Setting durations for the transitions
Duration dur1 = Duration.millis(1000);
Duration dur2 = Duration.millis(500);
//Setting Rotate Transition
RotateTransition rotate = new RotateTransition(dur2);
rotate.setFromAngle(-20);
rotate.setToAngle(20);
rotate.setCycleCount(50);
rotate.setAutoReverse(true);
FadeTransition death = new FadeTransition(dur2);
death.setFromValue(1.0f);
death.setToValue(0.0f);
death.setCycleCount(1);
death.setAutoReverse(false);
//Instantiating Sequential Transition class by passing the list of transitions into its constructor
int offset = (tileSize+stroke)/2;
SequentialTransition seqT = new SequentialTransition (agent);
PauseTransition initPause = new PauseTransition(Duration.millis(500));
seqT.getChildren().add(initPause);
initPause.onFinishedProperty().set((status)-> {
BGplayer.seek(Duration.ZERO);
BGplayer.setCycleCount(10);
BGplayer.play();
boolean dangerComputationEnabled = StateManager.getInstance().isDangerFactorEnabled.get();
boolean safePath = true;
for (int i=0; i
if (newVal == Animation.Status.RUNNING) {
metroTransPlayer.play();
//set pause
PauseTransition pause = new PauseTransition(Duration.millis(500));
seqT.getChildren().add(pause);
if (dangerComputationEnabled) {
//compute risk
double damage = t2.damageCost;
if (damage > 0) {
currentHealth -= damage;
FadeTransition takeD = new FadeTransition(Duration.millis(200));
takeD.setToValue(0.0);
takeD.setCycleCount(2);
takeD.setAutoReverse(true);
//play get hit sound
takeD.statusProperty().addListener((status, oldVal, newVal) -> {
if (newVal == Animation.Status.RUNNING) {
int res = Math.abs(rng.nextInt()) % 7;
if (res < 4) {
yellSoundList.get(res).seek(Duration.ZERO);
yellSoundList.get(res).play();
seqT.getChildren().add(takeD);
if (currentHealth <= 0) {
//not safe path
safePath = false;
seqT.getChildren().add(death);
ParallelTransition parT = new ParallelTransition(agent, seqT, rotate);
seqT.statusProperty().addListener((state, oldVal, newVal)-> {
if (newVal == Animation.Status.STOPPED) {
parT.stop();
mapPanel.getChildren().remove(agent);
StateManager.getInstance().isInSimulation.set(false);
if (safePath) {
seqT.setOnFinished((val)-> {
Logger.getInstance().logMessage(“Your agent has reached its destination safely.”);
// arrivePlayer.setVolume(10);
arrivePlayer.seek(Duration.ZERO);
arrivePlayer.play();
BGplayer.stop();
seqT.setOnFinished((val)-> {
Logger.getInstance().logMessage(“Your agent has died on its way….”);
deathPlayer.seek(Duration.ZERO);
deathPlayer.play();
seqT.statusProperty().addListener((state, oldVal, newVal)-> {
if (newVal == Animation.Status.STOPPED) {
BGplayer.stop();
//playing the transition
animationCache.add(parT);
//add music
letsgoPlayer.seek(Duration.ZERO);
letsgoPlayer.play();
parT.play();
public void resetAnimation() {
for (Transition t : animationCache)
StateManager.getInstance().isInSimulation.set(false);
public void reset() {
Logger.getInstance().logSystemMessage(“reset”);
resetAnimation();
resetWaypoints();
StateManager.getInstance().currentPath = null;
mapPanel.getChildren().clear();
StateManager.getInstance().isMapInitialized.set(false);
public void resetPath() {
Logger.getInstance().logSystemMessage(“reset path”);
mapPanel.getChildren().removeAll(lineCache);
resetAnimation();
lineCache.clear();
public void resetWaypoints() {
Logger.getInstance().logSystemMessage(“reset waypoints”);
resetAnimation();
for (Tile t : StateManager.getInstance().currentWaypoints) {
t.setWaypoint(false);
StateManager.getInstance().currentWaypoints.clear();
public void exit() {
System.exit(0);
public void drawMap1() {
char[][] map =
{‘s’, ‘p’, ‘p’},
{‘d’, ‘m’, ‘d’},
{‘p’, ‘p’, ‘e’},
drawMap(map);
public void drawMap2() {
char[][] map =
{‘s’, ‘d’, ‘d’, ‘p’, ‘m’},
{‘d’, ‘d’, ‘m’, ‘p’, ‘m’},
{‘d’, ‘p’, ‘d’, ‘d’, ‘m’},
{‘p’, ‘d’, ‘p’, ‘d’, ‘p’},
{‘d’, ‘p’, ‘p’, ‘p’, ‘e’},
drawMap(map);
public void drawMap3() {
char[][] map =
{‘s’, ‘d’, ‘d’, ‘M’, ‘d’},
{‘d’, ‘d’, ‘m’, ‘p’, ‘p’},
{‘p’, ‘m’, ‘d’, ‘d’, ‘p’},
{‘m’, ‘M’, ‘p’, ‘d’, ‘d’},
{‘p’, ‘d’, ‘p’, ‘p’, ‘e’},
drawMap(map);
public void drawMap4() {
char[][] map =
{‘p’, ‘p’, ‘r’, ‘r’, ‘x’, ‘x’, ‘x’, ‘x’,’x’},
{‘f’, ‘s’, ‘r’, ‘r’, ‘d’, ‘d’, ‘p’, ‘p’,’p’},
{‘d’, ‘p’, ‘p’, ‘x’, ‘x’, ‘p’, ‘x’, ‘d’,’r’},
{‘d’, ‘d’, ‘p’, ‘p’, ‘p’, ‘r’, ‘r’, ‘d’,’p’},
{‘f’, ‘d’, ‘p’, ‘x’, ‘x’, ‘r’, ‘x’, ‘r’,’e’},
drawMap(map);
public void onBFSButtonClick(){
if(!StateManager.getInstance().isMapInitialized.get()) return;
if(StateManager.getInstance().isInSimulation.get()) return;
StateManager.getInstance().isDangerFactorEnabled.set(false);
StateManager.getInstance().isInComputation.set(true);
resetPath();
// System.out.println(StateManager.getInstance().getCurrentMap());
Tile parentNode = StateManager.getInstance().getCurrentMap();
// System.out.println(parentNode.getCoord());
ArrayList
//visualize the path
visualizePath(path);
StateManager.getInstance().isInComputation.set(false);
public void onDFSButtonClick(){
if(!StateManager.getInstance().isMapInitialized.get()) return;
if(StateManager.getInstance().isInSimulation.get()) return;
StateManager.getInstance().isDangerFactorEnabled.set(false);
StateManager.getInstance().isInComputation.set(true);
resetPath();
System.out.println(StateManager.getInstance().getCurrentMap());
Tile parentNode = StateManager.getInstance().getCurrentMap();
System.out.println(parentNode.getNodeID());
ArrayList
//visualize the path
visualizePath(path);
StateManager.getInstance().isInComputation.set(false);
public void onFastestPathButtonClick() {
if (!StateManager.getInstance().isMapInitialized.get()) return;
if(StateManager.getInstance().isInSimulation.get()) return;
StateManager.getInstance().isDangerFactorEnabled.set(true);
StateManager.getInstance().isInComputation.set(true);
resetPath();
ArrayList
PathFindingService pf = new FastestPath(StateManager.getInstance().getCurrentMap());
LinkedList
path = pf.findPath(StateManager.getInstance().getCurrentMap(), waypoints);
//visualize the path if available
visualizePath(path);
StateManager.getInstance().isInComputation.set(false);
public void onShortestPathButtonClick() {
if(!StateManager.getInstance().isMapInitialized.get()) return;
if(StateManager.getInstance().isInSimulation.get()) return;
StateManager.getInstance().isDangerFactorEnabled.set(true);
StateManager.getInstance().isInComputation.set(true);
resetPath();
//main logic for calling pathfinding algorithm
ArrayList
PathFindingService pf = new ShortestPath(StateManager.getInstance().getCurrentMap());
// USE THIS TO TEST LEVEL 4
//path = pf.findPath(StateManager.getInstance().getCurrentMap());
// USE THIS TO TEST LEVEL 5
LinkedList
path = pf.findPath(StateManager.getInstance().getCurrentMap(), waypoints);
//visualize the path if available
visualizePath(path);
StateManager.getInstance().isInComputation.set(false);
public void onSafestPathButtonClick() {
if(!StateManager.getInstance().isMapInitialized.get()) return;
if(StateManager.getInstance().isInSimulation.get()) return;
StateManager.getInstance().isDangerFactorEnabled.set(true);
StateManager.getInstance().isInComputation.set(true);
resetPath();
//main logic for calling pathfinding algorithm
ArrayList
PathFindingService pf = new SafestShortestPath(StateManager.getInstance().getCurrentMap(), Integer.parseInt(healthInput.getText()));
LinkedList
path = pf.findPath(StateManager.getInstance().getCurrentMap(), waypoints);
//visualize the path if available
visualizePath(path);
StateManager.getInstance().isInComputation.set(false);
private void visualizePath(ArrayList
if (path != null && path.size() > 1) {
int offset = (tileSize+stroke)/2;
int dist = 0, time = 0;
double risk = 0;
for (int i=0; i