mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Slightly optimised code style and add more functionality
- optimised UI - check conflicts when change key bind if the key has already been in use - abstract keybind as a separate singleton class so all class can access it - [WIP] turning mode is need to be finished #story[1245]
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
package seng302.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javafx.scene.input.KeyCode;
|
||||
|
||||
public class GameKeyBind {
|
||||
|
||||
private static GameKeyBind instance;
|
||||
private Map<KeyCode, KeyAction> keyToActionMap;
|
||||
private Map<KeyAction, KeyCode> actionToKeyMap;
|
||||
private boolean continuouslyTurning;
|
||||
|
||||
|
||||
private GameKeyBind() {
|
||||
setToDefault();
|
||||
}
|
||||
|
||||
public void setToDefault() {
|
||||
actionToKeyMap = new HashMap<>();
|
||||
keyToActionMap = new HashMap<>();
|
||||
continuouslyTurning = false;
|
||||
// default key bindings
|
||||
ArrayList<KeyCode> keys = new ArrayList<>();
|
||||
keys.add(KeyCode.Z);
|
||||
keys.add(KeyCode.X);
|
||||
keys.add(KeyCode.SPACE);
|
||||
keys.add(KeyCode.SHIFT);
|
||||
keys.add(KeyCode.ENTER);
|
||||
keys.add(KeyCode.PAGE_UP);
|
||||
keys.add(KeyCode.PAGE_DOWN);
|
||||
for (int i = 0; i < 7; i++) {
|
||||
actionToKeyMap.put(KeyAction.getType(i + 1), keys.get(i));
|
||||
keyToActionMap.put(keys.get(i), KeyAction.getType(i + 1));
|
||||
}
|
||||
}
|
||||
|
||||
public static GameKeyBind getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new GameKeyBind();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public KeyCode getKeyCode(KeyAction keyAction) {
|
||||
return instance.actionToKeyMap.get(keyAction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds a key to a key action
|
||||
*
|
||||
* @return true if successfully bind
|
||||
*/
|
||||
public boolean bindKeyToAction(KeyCode keyCode, KeyAction keyAction) {
|
||||
if (instance.keyToActionMap.containsKey(keyCode)) {
|
||||
// if the key has been bound to other action, return false
|
||||
return false;
|
||||
} else {
|
||||
instance.keyToActionMap.put(keyCode, keyAction); // add key -> action
|
||||
KeyCode oldKeyCode = instance.actionToKeyMap
|
||||
.get(keyAction); // get old key for the action
|
||||
instance.keyToActionMap.remove(oldKeyCode); // remove the old key -> action
|
||||
instance.actionToKeyMap
|
||||
.replace(keyAction, keyCode); // replace the old key by the newer one
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void toggleTurningMode() {
|
||||
continuouslyTurning = !continuouslyTurning;
|
||||
}
|
||||
|
||||
public boolean isContinuouslyTurning() {
|
||||
return continuouslyTurning;
|
||||
}
|
||||
|
||||
}
|
||||
+5
-5
@@ -3,7 +3,7 @@ package seng302.model;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum GameClientAction {
|
||||
public enum KeyAction {
|
||||
ZOOM_IN(1),
|
||||
ZOOM_OUT(2),
|
||||
VMG(3),
|
||||
@@ -13,19 +13,19 @@ public enum GameClientAction {
|
||||
DOWNWIND(7);
|
||||
|
||||
private final int type;
|
||||
private static final Map<Integer, GameClientAction> intToTypeMap = new HashMap<>();
|
||||
private static final Map<Integer, KeyAction> intToTypeMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (GameClientAction type : GameClientAction.values()) {
|
||||
for (KeyAction type : KeyAction.values()) {
|
||||
intToTypeMap.put(type.getValue(), type);
|
||||
}
|
||||
}
|
||||
|
||||
GameClientAction(int type) {
|
||||
KeyAction(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public static GameClientAction getType(int value) {
|
||||
public static KeyAction getType(int value) {
|
||||
return intToTypeMap.get(value);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import java.time.ZoneOffset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
@@ -29,7 +28,8 @@ import seng302.gameServer.messages.BoatAction;
|
||||
import seng302.gameServer.messages.BoatStatus;
|
||||
import seng302.gameServer.messages.YachtEventType;
|
||||
import seng302.model.ClientYacht;
|
||||
import seng302.model.GameClientAction;
|
||||
import seng302.model.GameKeyBind;
|
||||
import seng302.model.KeyAction;
|
||||
import seng302.model.RaceState;
|
||||
import seng302.model.stream.packets.StreamPacket;
|
||||
import seng302.model.stream.parser.MarkRoundingData;
|
||||
@@ -67,7 +67,8 @@ public class GameClient {
|
||||
private RaceViewController raceViewController;
|
||||
|
||||
private ArrayList<ClientYacht> finishedBoats = new ArrayList<>();
|
||||
private Map<GameClientAction, KeyCode> keyBind = new HashMap<>();
|
||||
|
||||
private GameKeyBind gameKeyBind; // all the key binding setting.
|
||||
|
||||
private ObservableList<String> clientLobbyList = FXCollections.observableArrayList();
|
||||
|
||||
@@ -78,21 +79,7 @@ public class GameClient {
|
||||
*/
|
||||
public GameClient(Pane holder) {
|
||||
this.holderPane = holder;
|
||||
initialiseKeyBind();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise default keybind.
|
||||
*/
|
||||
private void initialiseKeyBind() {
|
||||
keyBind = new HashMap<>();
|
||||
keyBind.put(GameClientAction.ZOOM_IN, KeyCode.Z);
|
||||
keyBind.put(GameClientAction.ZOOM_OUT, KeyCode.X);
|
||||
keyBind.put(GameClientAction.VMG, KeyCode.SPACE);
|
||||
keyBind.put(GameClientAction.SAILS_STATE, KeyCode.SHIFT);
|
||||
keyBind.put(GameClientAction.TACK_GYBE, KeyCode.ENTER);
|
||||
keyBind.put(GameClientAction.UPWIND, KeyCode.PAGE_UP);
|
||||
keyBind.put(GameClientAction.DOWNWIND, KeyCode.PAGE_DOWN);
|
||||
this.gameKeyBind = GameKeyBind.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -392,13 +379,13 @@ public class GameClient {
|
||||
return;
|
||||
}
|
||||
|
||||
if (keyBind.get(GameClientAction.VMG) == e.getCode()) { // align with vmg
|
||||
if (gameKeyBind.getKeyCode(KeyAction.VMG) == e.getCode()) { // align with vmg
|
||||
socketThread.sendBoatAction(BoatAction.VMG);
|
||||
} else if (keyBind.get(GameClientAction.UPWIND) == e.getCode()) { // upwind
|
||||
} else if (gameKeyBind.getKeyCode(KeyAction.UPWIND) == e.getCode()) { // upwind
|
||||
socketThread.sendBoatAction(BoatAction.UPWIND);
|
||||
} else if (keyBind.get(GameClientAction.DOWNWIND) == e.getCode()) { // downwind
|
||||
} else if (gameKeyBind.getKeyCode(KeyAction.DOWNWIND) == e.getCode()) { // downwind
|
||||
socketThread.sendBoatAction(BoatAction.DOWNWIND);
|
||||
} else if (keyBind.get(GameClientAction.TACK_GYBE) == e.getCode()) { // tack/gybe
|
||||
} else if (gameKeyBind.getKeyCode(KeyAction.TACK_GYBE) == e.getCode()) { // tack/gybe
|
||||
// if chat box is active take whatever is in there and send it to server
|
||||
socketThread.sendBoatAction(BoatAction.TACK_GYBE);
|
||||
}
|
||||
@@ -410,11 +397,11 @@ public class GameClient {
|
||||
return;
|
||||
}
|
||||
|
||||
if (keyBind.get(GameClientAction.SAILS_STATE) == e.getCode()) { // sails in/sails out
|
||||
if (gameKeyBind.getKeyCode(KeyAction.SAILS_STATE) == e.getCode()) { // sails in/sails out
|
||||
socketThread.sendBoatAction(BoatAction.SAILS_IN);
|
||||
allBoatsMap.get(socketThread.getClientId()).toggleSail();
|
||||
} else if (keyBind.get(GameClientAction.UPWIND) == e.getCode()
|
||||
|| keyBind.get(GameClientAction.DOWNWIND) == e.getCode()) {
|
||||
} else if (gameKeyBind.getKeyCode(KeyAction.UPWIND) == e.getCode()
|
||||
|| gameKeyBind.getKeyCode(KeyAction.DOWNWIND) == e.getCode()) {
|
||||
socketThread.sendBoatAction(BoatAction.MAINTAIN_HEADING);
|
||||
}
|
||||
}
|
||||
@@ -473,7 +460,4 @@ public class GameClient {
|
||||
return allBoatsMap;
|
||||
}
|
||||
|
||||
public Map<GameClientAction, KeyCode> getKeyBind() {
|
||||
return keyBind;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import seng302.gameServer.ServerAdvertiser;
|
||||
import seng302.utilities.BonjourInstallChecker;
|
||||
import seng302.utilities.Sounds;
|
||||
import seng302.visualiser.GameClient;
|
||||
import seng302.visualiser.controllers.dialogs.KeyBindingDialogController;
|
||||
|
||||
public class ViewManager {
|
||||
|
||||
@@ -137,7 +136,7 @@ public class ViewManager {
|
||||
showKeyBindingDialog();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.warn("Could not create Key Binding Dialog.");
|
||||
logger.warn("Something went wrong when opening key bind dialog");
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -214,9 +213,6 @@ public class ViewManager {
|
||||
JFXDialog dialog = new JFXDialog((StackPane) node,
|
||||
dialogContent.load(),
|
||||
DialogTransition.CENTER);
|
||||
KeyBindingDialogController keyBindingDialogController = dialogContent
|
||||
.getController();
|
||||
keyBindingDialogController.init(gameClient.getKeyBind(), this);
|
||||
dialog.show();
|
||||
Sounds.playButtonClick();
|
||||
}
|
||||
@@ -229,7 +225,7 @@ public class ViewManager {
|
||||
* @param snackbarText text to be displayed.
|
||||
*/
|
||||
public void showSnackbar(String snackbarText) {
|
||||
jfxSnackbar.show(snackbarText, 1000);
|
||||
jfxSnackbar.show(snackbarText, 1500);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -378,12 +374,4 @@ public class ViewManager {
|
||||
return stage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter to return snackbar object.
|
||||
*
|
||||
* @return snackbar object.
|
||||
*/
|
||||
public JFXSnackbar getJfxSnackbar() {
|
||||
return jfxSnackbar;
|
||||
}
|
||||
}
|
||||
|
||||
+68
-95
@@ -2,19 +2,21 @@ package seng302.visualiser.controllers.dialogs;
|
||||
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
import com.jfoenix.controls.JFXDialogLayout;
|
||||
import com.jfoenix.controls.JFXToggleButton;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import seng302.model.GameClientAction;
|
||||
import seng302.model.GameKeyBind;
|
||||
import seng302.model.KeyAction;
|
||||
import seng302.visualiser.controllers.ViewManager;
|
||||
|
||||
public class KeyBindingDialogController implements Initializable {
|
||||
@@ -38,116 +40,87 @@ public class KeyBindingDialogController implements Initializable {
|
||||
private JFXButton upwindBtn;
|
||||
@FXML
|
||||
private JFXButton downwindBtn;
|
||||
@FXML
|
||||
private JFXButton resetBtn;
|
||||
@FXML
|
||||
private JFXButton confirmBtn;
|
||||
@FXML
|
||||
private JFXToggleButton turningToggle;
|
||||
//---------FXML END---------//
|
||||
|
||||
private ViewManager viewManager; // added viewManager to access snackbar. To be removed.
|
||||
|
||||
private Map<JFXButton, KeyCode> keys;
|
||||
private GameKeyBind gameKeyBind;
|
||||
private List<JFXButton> buttons = new ArrayList<>();
|
||||
private Map<GameClientAction, KeyCode> keyBind;
|
||||
private LinkedHashMap<JFXButton, GameClientAction> buttonAndGameClientActionMap;
|
||||
private Map<Button, KeyAction> buttonActionMap;
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
}
|
||||
|
||||
/**
|
||||
* HAOMING HELP!!! CHANGE FUNCTION NAME PLS :))
|
||||
*
|
||||
* Takes in a map from GameClient and initialise button mapping to the keys.
|
||||
*
|
||||
* @param keyBind a map with GameClientAction and KeyCode pair to be used in GameClient.
|
||||
*/
|
||||
public void init(Map<GameClientAction, KeyCode> keyBind, ViewManager viewManager) {
|
||||
this.keyBind = keyBind;
|
||||
this.viewManager = viewManager;
|
||||
|
||||
gameKeyBind = GameKeyBind.getInstance();
|
||||
buttons = new ArrayList<>();
|
||||
Collections
|
||||
.addAll(buttons, zoomInbtn, zoomOutBtn, vmgBtn, sailInOutBtn, tackGybeBtn, upwindBtn,
|
||||
downwindBtn);
|
||||
Collections.addAll(buttons,
|
||||
zoomInbtn, zoomOutBtn, vmgBtn, sailInOutBtn, tackGybeBtn, upwindBtn, downwindBtn);
|
||||
bindButtonWithAction();
|
||||
loadKeyBind();
|
||||
|
||||
initializeKeys();
|
||||
initializeButtons();
|
||||
buttons.forEach(button -> {
|
||||
button.setOnMouseEntered(event -> mouseEnter(button));
|
||||
button.setOnMousePressed(event -> buttonPressed(button));
|
||||
button.setOnMouseExited(event -> mouseExit(button));
|
||||
button.setOnKeyPressed(event -> keyPressed(event, button));
|
||||
});
|
||||
|
||||
resetBtn.setOnMouseClicked(event -> {
|
||||
gameKeyBind.setToDefault();
|
||||
loadKeyBind();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise default button-keybinding pair if not exist, else rebind the existing keybinding
|
||||
* to the new button which is created when javafx reinitialise a new controller.
|
||||
* Set buttons' label according to GameKeyBind settings
|
||||
*/
|
||||
private void initializeKeys() {
|
||||
initButtonAndGameClientActionMap();
|
||||
initializeDefaultKeys();
|
||||
private void loadKeyBind() {
|
||||
buttons.forEach(
|
||||
button -> button
|
||||
.setText(gameKeyBind.getKeyCode(buttonActionMap.get(button)).getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* HAOMING CHANGE FUNCTION NAME HERE TOO :) OR BETTER, REMOVE THIS FUNCTION
|
||||
*
|
||||
* Link buttons and the GameClientAction to be used in accessing keys.
|
||||
*/
|
||||
private void initButtonAndGameClientActionMap() {
|
||||
buttonAndGameClientActionMap = new LinkedHashMap<>();
|
||||
buttonAndGameClientActionMap.put(zoomInbtn, GameClientAction.ZOOM_IN);
|
||||
buttonAndGameClientActionMap.put(zoomOutBtn, GameClientAction.ZOOM_OUT);
|
||||
buttonAndGameClientActionMap.put(vmgBtn, GameClientAction.VMG);
|
||||
buttonAndGameClientActionMap.put(sailInOutBtn, GameClientAction.SAILS_STATE);
|
||||
buttonAndGameClientActionMap.put(tackGybeBtn, GameClientAction.TACK_GYBE);
|
||||
buttonAndGameClientActionMap.put(upwindBtn, GameClientAction.UPWIND);
|
||||
buttonAndGameClientActionMap.put(downwindBtn, GameClientAction.DOWNWIND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise default keybinding to a button.
|
||||
*/
|
||||
private void initializeDefaultKeys() {
|
||||
keys = new LinkedHashMap<>();
|
||||
keys.put(zoomInbtn, keyBind.get(GameClientAction.ZOOM_IN));
|
||||
keys.put(zoomOutBtn, keyBind.get(GameClientAction.ZOOM_OUT));
|
||||
keys.put(vmgBtn, keyBind.get(GameClientAction.VMG));
|
||||
keys.put(sailInOutBtn, keyBind.get(GameClientAction.SAILS_STATE));
|
||||
keys.put(tackGybeBtn, keyBind.get(GameClientAction.TACK_GYBE));
|
||||
keys.put(upwindBtn, keyBind.get(GameClientAction.UPWIND));
|
||||
keys.put(downwindBtn, keyBind.get(GameClientAction.DOWNWIND));
|
||||
}
|
||||
|
||||
/**
|
||||
* Change button text to match current keybinding. Adds focusedProperty and keyPressed listener
|
||||
* to each buttons.
|
||||
*/
|
||||
private void initializeButtons() {
|
||||
for (JFXButton jfxButton : buttons) {
|
||||
if (keys.get(jfxButton) != null) {
|
||||
jfxButton.setText(keys.get(jfxButton).getName());
|
||||
} else {
|
||||
jfxButton.setText("");
|
||||
}
|
||||
jfxButton.focusedProperty().addListener((observable, oldValue, newValue) -> {
|
||||
jfxButton.setOnKeyPressed(event -> {
|
||||
event.consume();
|
||||
doSomething(event, jfxButton);
|
||||
});
|
||||
});
|
||||
private void bindButtonWithAction() {
|
||||
buttonActionMap = new HashMap<>();
|
||||
for (int i = 0; i < 7; i++) {
|
||||
buttonActionMap.put(buttons.get(i), KeyAction.getType(i + 1));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HAOMING PLEASE CHANGE THIS DOCSTRING AND THE FUNCTION NAME!!!
|
||||
*
|
||||
* @param event BLAH
|
||||
* @param button BLAH
|
||||
*/
|
||||
private void doSomething(KeyEvent event, JFXButton button) {
|
||||
if (keys.containsValue(event.getCode())) {
|
||||
keys.replace(button, null);
|
||||
keyBind.replace(buttonAndGameClientActionMap.get(button), null);
|
||||
button.setText("");
|
||||
viewManager
|
||||
.showSnackbar(button.getId() + " can't be set to " + event.getCode().getName());
|
||||
private void showSnackBar(String message) {
|
||||
ViewManager.getInstance().showSnackbar(message);
|
||||
}
|
||||
|
||||
private void mouseEnter(Button button) {
|
||||
button.setStyle(""
|
||||
+ "-fx-background-color: -fx-pp-theme-color;"
|
||||
+ "-fx-text-fill: -fx-pp-front-color;"
|
||||
+ "-fx-font-size: 15;");
|
||||
}
|
||||
|
||||
private void buttonPressed(Button button) {
|
||||
button.setText("PRESS KEY...");
|
||||
}
|
||||
|
||||
private void mouseExit(Button button) {
|
||||
button.setText(GameKeyBind.getInstance().getKeyCode(buttonActionMap.get(button)).getName());
|
||||
button.setStyle(""
|
||||
+ "-fx-background-color: -fx-pp-front-color; "
|
||||
+ "-fx-text-fill: -fx-pp-theme-color; "
|
||||
+ "-fx-font-size: 13;");
|
||||
}
|
||||
|
||||
private void keyPressed(KeyEvent event, Button button) {
|
||||
KeyAction buttonAction = buttonActionMap.get(button);
|
||||
if (gameKeyBind.bindKeyToAction(event.getCode(), buttonAction)) {
|
||||
showSnackBar(button.getId() + " is set to " + event.getCode().getName());
|
||||
button.setText(gameKeyBind.getKeyCode(buttonAction).getName());
|
||||
} else {
|
||||
keys.replace(button, event.getCode());
|
||||
keyBind.replace(buttonAndGameClientActionMap.get(button), event.getCode());
|
||||
button.setText(event.getCode().getName());
|
||||
viewManager.showSnackbar(button.getId() + " is set to " + event.getCode().getName());
|
||||
showSnackBar(event.getCode().getName() + " is already in use");
|
||||
}
|
||||
event.consume();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user