Readded launcher from a67cee242be263e370b4da1c990ae94a9dd0ee11

This commit is contained in:
François Autin 2021-06-24 13:15:03 +02:00
parent 9a8e13bfb5
commit 1b187025e2
4 changed files with 395 additions and 250 deletions

View File

@ -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();
}
}
}

View File

@ -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;
/**
* <p>Game configuration window and engine launcher</p>
* @author François Autin
*/
@SuppressWarnings("unchecked")
public class Launcher extends Application {
public static Launcher pointer;
private static Settings setter;
private HashMap<String, Object> arraysettings;
private static Map<String, Object> 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<String, Object> arraysettings; // Array that allows passing values of UI elements to setter
private static Map<String, Object> 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<String, Object>();
}
/*
/**
* 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<String> cb = (ChoiceBox<String>) namespace.get("resolution");
ObservableList<String> availableres = FXCollections.observableArrayList("640x480", "800x600", "1024x768", "1280x720", "1366x768", "1600x900", "1920x1080");
// Assigning list of possible choices to ChoiceBox
ObservableList<String> 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<String> cbr = (ChoiceBox<String>) namespace.get("rounds");
// Assigning list of possible choices to ChoiceBox
ObservableList<String> 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<String> b1 = (ChoiceBox<String>) v1.getChildren().get(1);
// Getting character 2 ChoiceBox from namespace
VBox v2 = (VBox) namespace.get("p2");
ChoiceBox<String> b2 = (ChoiceBox<String>) v2.getChildren().get(1);
// Assigning list of possible choices to ChoiceBoxes
ObservableList<String> 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<String> cb = (ChoiceBox<String>) 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<String> rnd = (ChoiceBox<String>) namespace.get("rounds");
pointer.arraysettings.put("rounds", rnd.getValue());
VBox vp1 = (VBox) namespace.get("p1");
ChoiceBox<String> p1 = (ChoiceBox<String>) vp1.getChildren().get(1);
pointer.arraysettings.put("character1", p1.getValue().toLowerCase());
VBox vp2 = (VBox) namespace.get("p2");
ChoiceBox<String> p2 = (ChoiceBox<String>) 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<String> cb = (ChoiceBox<String>) 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<String> rnd = (ChoiceBox<String>) namespace.get("rounds");
arraysettings.put("rounds", rnd.getValue());
// Character 1
VBox vp1 = (VBox) namespace.get("p1");
ChoiceBox<String> p1 = (ChoiceBox<String>) vp1.getChildren().get(1);
arraysettings.put("character1", p1.getValue().toLowerCase());
// Character 2
VBox vp2 = (VBox) namespace.get("p2");
ChoiceBox<String> p2 = (ChoiceBox<String>) 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<String> b1 = (ChoiceBox<String>) 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<String> b1 = (ChoiceBox<String>) 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<String> b = (ChoiceBox<String>) 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<String, Object> 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<String, Object> getArraysettings() {
return arraysettings;
}

View File

@ -1,60 +1,239 @@
package launcher;
import java.io.*;
import java.util.HashMap;
import org.json.simple.*;
import org.json.simple.parser.*;
/**
* <p>Allows the launcher to modify the game.set json file</p>
* @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;
/**
* <p>Settings allows manipulating the JSON game.set file.</p>
* <p>The constructor parses the game.set file.</p>
* @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<String, Object> set = Launcher.pointer.getArraysettings();
/**
* <p>Parses the game.set file (creates it if it does not exist).</p>
* <p>Isolates the relevant settings from the game.set JSONFile and puts them in the correct global variables of the Settings class</p>
* @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");
}
}
/**
* <p>Converts user inputed data to settings passable to the write() method</p>
* @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<String, Object> 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();
}
}
/**
* <p>This version of the write method without parameters simply passes the global variables of the Settings class instance to the full write method.</p>
* @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);
}
/**
* <p>Write echoes all user settings to the game.set JSON File</p>
* @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 <p>A boolean:<ul><li>true if fullscreen mode</li><li>false if windowed mode</li></ul></p>
* @author François Autin
*/
public boolean getFullscreen() {
return config.fullscreen;
return fullscreen;
}
/**
* Returns the current hitbox setting
* @return <p>A boolean:<ul><li>true if hitboxes are to be showed</li><li>false if hitboxes are to be hidden</li></ul></p>
* @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;
}
}

View File

@ -1,5 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Launcher FXML
@author François AUTIN
-->
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ChoiceBox?>
<?import javafx.scene.control.CheckBox?>
@ -50,7 +55,7 @@
<CheckBox fx:id="hitboxes"/>
</children>
</HBox>
<Button text="Play" fx:id="btn_launch" onAction="#launch"
<Button text="Play" fx:id="btn_launch" onAction="#runGame"
prefWidth="110" prefHeight="15"/>
<Button text="Quit" fx:id="btn_quit" onAction="#quit"
prefWidth="110" prefHeight="15"/>
@ -94,4 +99,4 @@
</children>
</HBox>
</HBox>