From 1b187025e27cda4d0200ba76c528849b005e6d47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Autin?= Date: Thu, 24 Jun 2021 13:15:03 +0200 Subject: [PATCH] Readded launcher from a67cee242be263e370b4da1c990ae94a9dd0ee11 --- src/launcher/Config.java | 118 --------------- src/launcher/Launcher.java | 295 +++++++++++++++++++++++-------------- src/launcher/Settings.java | 223 +++++++++++++++++++++++++--- src/launcher/launcher.fxml | 9 +- 4 files changed, 395 insertions(+), 250 deletions(-) delete mode 100644 src/launcher/Config.java diff --git a/src/launcher/Config.java b/src/launcher/Config.java deleted file mode 100644 index 9d95420..0000000 --- a/src/launcher/Config.java +++ /dev/null @@ -1,118 +0,0 @@ -package launcher; - -import java.io.*; -import org.json.simple.*; -import org.json.simple.parser.*; - -public class Config { - - public int width, height, rounds; - public boolean fullscreen, hitboxes; - public String stage; - public String p1, p2; - - public Config() throws FileNotFoundException { - parse(); - } - - public void parse() throws FileNotFoundException { - - // initialize the parser - JSONParser jsonP = new JSONParser(); - try { - // read the json document - JSONObject jsonO = (JSONObject) jsonP.parse(new FileReader("game.set")); - - // to print all values - // System.out.println(jsonO.values()); - - // isolate the "test" part and print it - // String test = (String) jsonO.get("test"); - // System.out.println("ceci est un test :" + test); - - - JSONArray game = (JSONArray) jsonO.get("game"); - JSONObject settings = (JSONObject) game.get(0); - - // print a case of this element - stage = (String) settings.get("stage"); - - // rounds - rounds = Integer.parseInt((String) settings.get("rounds")); - - // character selection - p1 = (String) settings.get("character1"); - p2 = (String) settings.get("character2"); - - height = Integer.parseInt((String) settings.get("height")); // String to int - width = Integer.parseInt((String) settings.get("width")); - - // fullscreen - String fs = (String) settings.get("fullscreen"); - if (fs.equals("true")) { - fullscreen = true; - } else fullscreen = false; - - String hb = (String) settings.get("hitboxes"); - if (hb == null) hb = "false"; - if (hb.equals("true")) { - hitboxes = true; - } else hitboxes = false; - - // rounds - String temprounds = (String) settings.get("rounds"); - switch (temprounds) { - case "1": rounds = 1; - case "3": rounds = 3; - case "5": rounds = 5; - default: rounds = 1; - } - - } catch (FileNotFoundException e) { - File f = new File("game.set"); - try { - f.createNewFile(); - } catch (IOException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - System.exit(1); - } - parse(); - } catch (IOException e) { - e.printStackTrace(); - } catch (ParseException e) { - System.out.println("Empty config file"); - } - } - - @SuppressWarnings("unchecked") - public void write(int width, int height, int rounds, boolean fullscreen, boolean hitboxes, String character1, String character2, String stage) throws Exception { - - JSONObject metafile = new JSONObject(); - JSONArray array = new JSONArray(); - - JSONObject set = new JSONObject(); - set.put("width", Integer.toString(width)); - set.put("height", Integer.toString(height)); - set.put("rounds", Integer.toString(rounds)); - set.put("fullscreen", Boolean.toString(fullscreen)); - set.put("hitboxes", Boolean.toString(hitboxes)); - set.put("character1", character1); - set.put("character2", character2); - set.put("stage", stage); - - array.add(set); - - metafile.put("game", array); - - try (FileWriter file = new FileWriter("game.set", false)) { - file.write(metafile.toJSONString()); - file.close(); - - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } -} diff --git a/src/launcher/Launcher.java b/src/launcher/Launcher.java index 947f61e..a7b2dea 100644 --- a/src/launcher/Launcher.java +++ b/src/launcher/Launcher.java @@ -1,12 +1,3 @@ -/** - * CLASS LAUNCHER - * - * Fenêtre de configuration du jeu préalablement au lancement d'une partie - * - * @author François Autin - * - */ - package launcher; import gameplay.match.*; @@ -23,19 +14,27 @@ import javafx.scene.control.CheckBox; import javafx.stage.Stage; import javafx.stage.StageStyle; import javafx.fxml.*; + +import java.io.IOException; import java.util.HashMap; import java.util.Map; +/** + *

Game configuration window and engine launcher

+ * @author François Autin + */ @SuppressWarnings("unchecked") public class Launcher extends Application { - public static Launcher pointer; - private static Settings setter; - private HashMap arraysettings; - private static Map namespace; + //public static Launcher pointer; // Self pointer, required to regain context if ever exited + private static Settings setter; // Settings class allows manipulation of settings + protected static HashMap arraysettings; // Array that allows passing values of UI elements to setter + private static Map namespace; // Namespace containing all elements from UI + /** + * Starts the Launcher thread + */ public Launcher() { - pointer = this; try { setter = new Settings(); } catch (Exception e) { @@ -45,189 +44,269 @@ public class Launcher extends Application { arraysettings = new HashMap(); } - /* + /** * Start method is used by Launcher as an implementation of the Application class to create a JavaFX thread to display the GUI window + * @param primaryStage the base Stage on which to place UI elements + * @throws IOException if the FXMLLoader fails to find or parse the launcher.fxml file + * @author François Autin */ - - public void start(Stage primaryStage) throws Exception { + public void start(Stage primaryStage) throws IOException { + // Loading UI from FXML file FXMLLoader loader = new FXMLLoader(getClass().getResource("launcher.fxml")); - Parent root = loader.load(); - Scene main = new Scene(root); + // Assigning pointer to namespace namespace = loader.getNamespace(); + /******************/ + /* Resolution box */ + /******************/ + + // Getting resolution ChoiceBox object from namespace ChoiceBox cb = (ChoiceBox) namespace.get("resolution"); - ObservableList availableres = FXCollections.observableArrayList("640x480", "800x600", "1024x768", "1280x720", "1366x768", "1600x900", "1920x1080"); + // Assigning list of possible choices to ChoiceBox + ObservableList availableres = FXCollections.observableArrayList("320x240", "640x480", "800x600", "1024x768", "1280x720", "1366x768", "1600x900", "1920x1080"); cb.setItems(availableres); + // Setting default ChoiceBox value to the one already in the config file if (!availableres.contains(setter.getResolution())) { cb.setValue("640x480"); } else { cb.setValue(setter.getResolution()); } + /******************/ + /* Fullscreen box */ + /******************/ + + // Getting fullscreen CheckBox object from namespace CheckBox fs = (CheckBox) namespace.get("fullscreen"); + // Setting default CheckBox value to the one already in the config file if(setter.getFullscreen()) { fs.setSelected(true); } else { fs.setSelected(false); } + /**************/ + /* Rounds box */ + /**************/ + + // Getting rounds ChoiceBox object from namespace ChoiceBox cbr = (ChoiceBox) namespace.get("rounds"); + // Assigning list of possible choices to ChoiceBox ObservableList nbrounds = FXCollections.observableArrayList("1", "3", "5", "7", "9"); cbr.setItems(nbrounds); + // Setting default ChoiceBox value to the one already in the config file if (!nbrounds.contains(setter.getRounds())) { - cb.setValue("3"); + cbr.setValue("3"); } else { - cb.setValue(setter.getRounds()); + cbr.setValue(setter.getRounds()); } + /****************/ + /* Hitboxes box */ + /****************/ + + // Getting hitboxes CheckBox from namespace CheckBox hb = (CheckBox) namespace.get("hitboxes"); + // Setting default CheckBox value to the one already in the config file if (setter.getHitboxes()) { hb.setSelected(true); } else { hb.setSelected(false); } + + /********************/ + /* Character select */ + /********************/ + + // Getting character 1 ChoiceBox from namespace VBox v1 = (VBox) namespace.get("p1"); ChoiceBox b1 = (ChoiceBox) v1.getChildren().get(1); + // Getting character 2 ChoiceBox from namespace VBox v2 = (VBox) namespace.get("p2"); ChoiceBox b2 = (ChoiceBox) v2.getChildren().get(1); + // Assigning list of possible choices to ChoiceBoxes ObservableList availablechar = FXCollections.observableArrayList("Blue"); b1.setItems(availablechar); b2.setItems(availablechar); - + // Setting default ChoiceBoxes values to the ones already in the config file if(setter.getChar1().equals("blue")) { b1.setValue("Blue"); } - if(setter.getChar2().equals("blue")) { b2.setValue("Blue"); } + /*******************/ + /* Window settings */ + /*******************/ + + // Removing window decorations primaryStage.initStyle(StageStyle.UNDECORATED); + // Setting window title primaryStage.setTitle("Boulevard Combattant"); + // Assinging main scene to primaryStage primaryStage.setScene(main); + // Showing the stage to the user primaryStage.show(); } + /** + * saves all settings to game.set and then launches the Engine thread + * @author François Autin + */ @FXML - public void runGame() { + private void runGame() { + try { - int width, height; - ChoiceBox cb = (ChoiceBox) namespace.get("resolution"); - switch (cb.getValue()) { - case "640x480": - width = 640; - height = 480; - break; - case "800x600": - width = 800; - height = 600; - break; - case "1024x768": - width = 1024; - height = 768; - break; - case "1280x720": - width = 1280; - height = 720; - break; - case "1366x768": - width = 1366; - height = 768; - break; - case "1600x900": - width = 1600; - height = 900; - break; - case "1920x1080": - width = 1920; - height = 1080; - break; - default: - width = 640; - height = 480; - break; - } - pointer.arraysettings.put("width", width); - pointer.arraysettings.put("height", height); - - CheckBox fs = (CheckBox) namespace.get("fullscreen"); - pointer.arraysettings.put("fullscreen", fs.isSelected()); - CheckBox hb = (CheckBox) namespace.get("hitboxes"); - pointer.arraysettings.put("hitboxes", hb.isSelected()); - - ChoiceBox rnd = (ChoiceBox) namespace.get("rounds"); - pointer.arraysettings.put("rounds", rnd.getValue()); - - VBox vp1 = (VBox) namespace.get("p1"); - ChoiceBox p1 = (ChoiceBox) vp1.getChildren().get(1); - pointer.arraysettings.put("character1", p1.getValue().toLowerCase()); - - VBox vp2 = (VBox) namespace.get("p2"); - ChoiceBox p2 = (ChoiceBox) vp2.getChildren().get(1); - pointer.arraysettings.put("character2", p2.getValue().toLowerCase()); - - pointer.arraysettings.put("stage", "default"); + fillArraySettings(); setter.setSettings(); match.main(null); - } catch (Exception e) { e.printStackTrace(); System.exit(1); } } - @FXML - public void launch() { - this.runGame(); + /** + * fills the array bridging between the launcher and the setter class + * @throws NullPointerException if namespace does not contain required classes + * @author François Autin + */ + private void fillArraySettings() throws NullPointerException { + // Converting the choice of resolution to two workable variables + int width, height; + ChoiceBox cb = (ChoiceBox) namespace.get("resolution"); + switch (cb.getValue()) { + case "320x240": + width = 320; + height = 240; + break; + case "800x600": + width = 800; + height = 600; + break; + case "1024x768": + width = 1024; + height = 768; + break; + case "1280x720": + width = 1280; + height = 720; + break; + case "1366x768": + width = 1366; + height = 768; + break; + case "1600x900": + width = 1600; + height = 900; + break; + case "1920x1080": + width = 1920; + height = 1080; + break; + default: + width = 640; + height = 480; + break; + } + arraysettings.put("width", width); + arraysettings.put("height", height); + + // Fullscreen + CheckBox fs = (CheckBox) namespace.get("fullscreen"); + arraysettings.put("fullscreen", fs.isSelected()); + + // Hitboxes + CheckBox hb = (CheckBox) namespace.get("hitboxes"); + arraysettings.put("hitboxes", hb.isSelected()); + + // Number of rounds + ChoiceBox rnd = (ChoiceBox) namespace.get("rounds"); + arraysettings.put("rounds", rnd.getValue()); + + // Character 1 + VBox vp1 = (VBox) namespace.get("p1"); + ChoiceBox p1 = (ChoiceBox) vp1.getChildren().get(1); + arraysettings.put("character1", p1.getValue().toLowerCase()); + + // Character 2 + VBox vp2 = (VBox) namespace.get("p2"); + ChoiceBox p2 = (ChoiceBox) vp2.getChildren().get(1); + arraysettings.put("character2", p2.getValue().toLowerCase()); + + // Stage + arraysettings.put("stage", "default"); } - + + /** + * quits the launcher and the game + */ @FXML - public void quit() { + private void quit() { System.exit(0); } + /** + * links to the gitlab project page + */ @FXML - public void website() { + private void website() { getHostServices().showDocument("https://gitlab.istic.univ-rennes1.fr/fautin/jeu-de-combat"); } + /** + * changes the character image of the player 1 depending on its character selection + */ @FXML - public void chp1() { - VBox v1 = (VBox) namespace.get("p1"); - ImageView iv1 = (ImageView) v1.getChildren().get(0); - ChoiceBox b1 = (ChoiceBox) v1.getChildren().get(1); - switch (b1.getValue()) { - case "Blue": - iv1.setImage(new Image("/launcher/charfaces/blue.png")); - break; - default: - iv1.setImage(new Image("/launcher/default.png")); - break; - } + private void chp1() { + chp(1); } + /** + * changes the character image of the player 1 depending on its character selection + */ @FXML - public void chp2() { - VBox v1 = (VBox) namespace.get("p2"); - ImageView iv1 = (ImageView) v1.getChildren().get(0); - ChoiceBox b1 = (ChoiceBox) v1.getChildren().get(1); - switch (b1.getValue()) { + private void chp2() { + chp(2); + } + + /** + * changes the character image of the player n depending on its character selection + */ + @FXML + private void chp(int n) { + // if we try to change the character image of a player who does not exist, we simply return without doing anything + if(n > 2 || n < 1) { + return; + } + // getting the corresponding VBox + VBox v = (VBox) namespace.get("p" + Integer.toString(n)); + // getting the first child of the VBox (the imageview containing the character image + ImageView iv = (ImageView) v.getChildren().get(0); + // Evaluating the new character choice in order to change the image accordingly + ChoiceBox b = (ChoiceBox) v.getChildren().get(1); + switch (b.getValue()) { case "Blue": - iv1.setImage(new Image("/launcher/charfaces/blue.png")); + iv.setImage(new Image("/launcher/charfaces/blue.png")); break; default: - iv1.setImage(new Image("/launcher/default.png")); + iv.setImage(new Image("/launcher/default.png")); break; } } - public HashMap getArraysettings() { + /** + * Returns the hashmap containing all settings inputed in the launcher by the user + * @return the hashmap containing all settings inputed in the launcher by the user + */ + protected static HashMap getArraysettings() { return arraysettings; } diff --git a/src/launcher/Settings.java b/src/launcher/Settings.java index 51ca2b8..08610f6 100644 --- a/src/launcher/Settings.java +++ b/src/launcher/Settings.java @@ -1,60 +1,239 @@ package launcher; +import java.io.*; import java.util.HashMap; +import org.json.simple.*; +import org.json.simple.parser.*; + +/** + *

Allows the launcher to modify the game.set json file

+ * @author François Autin + * @author Indy Boyeau + */ public class Settings { - private Config config; + private int width, height, rounds; + private boolean fullscreen, hitboxes; + private String stage, p1, p2; + /** + *

Settings allows manipulating the JSON game.set file.

+ *

The constructor parses the game.set file.

+ * @author François Autin + */ public Settings() { try { - config = new Config(); + parse(); } catch (Exception e) { e.printStackTrace(); System.exit(1); } } - public void setSettings() throws Exception { - HashMap set = Launcher.pointer.getArraysettings(); + /** + *

Parses the game.set file (creates it if it does not exist).

+ *

Isolates the relevant settings from the game.set JSONFile and puts them in the correct global variables of the Settings class

+ * @throws FileNotFoundException if the game.set file does not exist + * @throws IOException in case of IO error + * @throws ParseException if the JSON file is invalid + * @throws Exception for any other unaccounted for exception + * @author François Autin + * @author Indy Boyeau + */ + private void parse() throws Exception { + + // Initializing the parser + JSONParser jsonP = new JSONParser(); + try { - int width = (Integer) set.get("width"); - int height = (Integer) set.get("height"); - int rounds = (Integer) set.get("rounds"); - boolean fullscreen = (Boolean) set.get("fullscreen"); - boolean hitboxes = (Boolean) set.get("hitboxes"); - String character1 = (String) set.get("character1"); - String character2 = (String) set.get("character2"); - String stage = (String) set.get("stage"); - config.write(width, height, rounds, fullscreen, hitboxes, character1, character2, stage); - } catch (Exception e) { - config.write(800, 600, 3, false, false, "blue", "blue", "default"); - System.out.println("Incorrect config file"); + + // Loading the json document into memory + JSONObject jsonO = (JSONObject) jsonP.parse(new FileReader("game.set")); + // Getting the primary node (game) + JSONArray root = (JSONArray) jsonO.get("game"); + JSONObject settings = (JSONObject) root.get(0); + + // Rounds + rounds = Integer.parseInt((String) settings.get("rounds")); + + // Character selection + p1 = (String) settings.get("character1"); + p2 = (String) settings.get("character2"); + + // Resolution + height = Integer.parseInt((String) settings.get("height")); + width = Integer.parseInt((String) settings.get("width")); + + // Fullscreen + String fs = (String) settings.get("fullscreen"); + if (fs.equals("true")) { + fullscreen = true; + } else fullscreen = false; + + // Hitboxes + String hb = (String) settings.get("hitboxes"); + if (hb.equals("true")) { + hitboxes = true; + } else hitboxes = false; + + // Stage + stage = (String) settings.get("stage"); + + } catch (FileNotFoundException e) { + // If the file does not exist, we create it + File f = new File("game.set"); + try { + f.createNewFile(); + parse(); + } catch (IOException e1) { + e1.printStackTrace(); + System.exit(1); + } + } catch (IOException e) { + e.printStackTrace(); + System.exit(1); + } catch (ParseException e) { + System.out.println("Invalid config file"); } } + /** + *

Converts user inputed data to settings passable to the write() method

+ * @throws Exception any exception caused by write(...) + * @author François Autin + */ + protected void setSettings() throws Exception { + + // Getting the HashMap arraysettings containing all user inputed settings + HashMap arraysettings = Launcher.getArraysettings(); + + try { + // Putting arraysettings content in global variables + width = (Integer) arraysettings.get("width"); + height = (Integer) arraysettings.get("height"); + rounds = Integer.parseInt((String) arraysettings.get("rounds")); + fullscreen = (Boolean) arraysettings.get("fullscreen"); + hitboxes = (Boolean) arraysettings.get("hitboxes"); + p1 = (String) arraysettings.get("character1"); + p2 = (String) arraysettings.get("character2"); + stage = (String) arraysettings.get("stage"); + // Writing to file + write(); + } catch (Exception e) { + // Failsafe in case of Exception + write(800, 600, 3, false, false, "blue", "blue", "default"); + e.printStackTrace(); + } + } + + /** + *

This version of the write method without parameters simply passes the global variables of the Settings class instance to the full write method.

+ * @throws Exception any exception caused by write(...) + * @author François Autin + */ + private void write() throws Exception { + write(width, height, rounds, fullscreen, hitboxes, p1, p2, stage); + } + + /** + *

Write echoes all user settings to the game.set JSON File

+ * @param width the width of the game window + * @param height the height of the game window + * @param rounds the number of rounds to be played + * @param fullscreen whether or not to show the window fullscreen + * @param hitboxes whether or not to display the hitboxes + * @param character1 the name of the character chosen by player 1 + * @param character2 the name of the character chosen by player 2 + * @param stage the name of the stage + * @throws FileNotFoundException if the game.set file does not exist + * @throws IOException in case of IO error + * @throws Exception for any other unaccounted for exception + * @author François Autin + */ + @SuppressWarnings("unchecked") + private void write(int width, int height, int rounds, boolean fullscreen, boolean hitboxes, String character1, String character2, String stage) throws Exception { + + JSONObject metafile = new JSONObject(); + JSONArray array = new JSONArray(); + + JSONObject set = new JSONObject(); + set.put("width", Integer.toString(width)); + set.put("height", Integer.toString(height)); + set.put("rounds", Integer.toString(rounds)); + set.put("fullscreen", Boolean.toString(fullscreen)); + set.put("hitboxes", Boolean.toString(hitboxes)); + set.put("character1", character1); + set.put("character2", character2); + set.put("stage", stage); + + array.add(set); + + metafile.put("game", array); + + try (FileWriter file = new FileWriter("game.set", false)) { + file.write(metafile.toJSONString()); + file.close(); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Returns the current resolution setting + * @return a string of the (width)x(height) format + * @author François Autin + */ public String getResolution() { - return "" + Integer.toString(config.width) + "x" + Integer.toString(config.height); + return "" + Integer.toString(width) + "x" + Integer.toString(height); } + /** + * Returns the current fullscreen setting + * @return

A boolean:

  • true if fullscreen mode
  • false if windowed mode

+ * @author François Autin + */ public boolean getFullscreen() { - return config.fullscreen; + return fullscreen; } + /** + * Returns the current hitbox setting + * @return

A boolean:

  • true if hitboxes are to be showed
  • false if hitboxes are to be hidden

+ * @author François Autin + */ public boolean getHitboxes() { - return config.hitboxes; + return hitboxes; } + /** + * Returns the current rounds setting + * @return The number of rounds to be played + * @author François Autin + */ public String getRounds() { - return Integer.toString(config.rounds); + return Integer.toString(rounds); } + /** + * Returns the current fullscreen setting + * @return the name of the character chosen by player 1 + * @author François Autin + */ public String getChar1() { - return config.p1; + return p1; } + /** + * Returns the current fullscreen setting + * @return the name of the character chosen by player 2 + * @author François Autin + */ public String getChar2() { - return config.p2; + return p2; } } diff --git a/src/launcher/launcher.fxml b/src/launcher/launcher.fxml index c8a3caa..bddce39 100644 --- a/src/launcher/launcher.fxml +++ b/src/launcher/launcher.fxml @@ -1,5 +1,10 @@ + + @@ -50,7 +55,7 @@ -