diff --git a/src/main/java/project_16x16/Options.java b/src/main/java/project_16x16/Options.java index d571ed0..54e592e 100644 --- a/src/main/java/project_16x16/Options.java +++ b/src/main/java/project_16x16/Options.java @@ -3,78 +3,178 @@ import java.awt.event.KeyEvent; import java.util.prefs.BackingStoreException; import java.util.prefs.Preferences; - import project_16x16.ui.Notifications; /** - * Handle loading/saving of player settings (game options) + * Handle loading/saving of player settings (game options). */ public class Options { + // preferences are stored in the Windows Registry private static final Preferences options = Preferences.userNodeForPackage(Options.class); + /* + * TODO might be best to combine the key name (see current enum) with the + * default key value and the current/live value into one object. this way, + * string values in buttons can update live and one could call .save(), which + * would save the new mapping AND set the in-game mapping in one operation! + */ + /** - * Define the option as an enum, then create the variable. + * Defines all configurable options in the game */ public static enum Option { - moveLeftKey, moveRightKey, jumpKey, dashKey, targetFPS, snapSize, debugMode, gainBGM, gainSFX, muteBGM, muteSFX , testKey; + // @formatter:off + // Movement controls + MOVE_LEFT_KEY, + MOVE_RIGHT_KEY, + JUMP_KEY, + DASH_KEY, + + // Debug and development controls + FRAME_RATE_LOW_KEY, + FRAME_RATE_HIGH_KEY, + FRAME_RATE_DEFAULT_KEY, + TOGGLE_DEADZONE_KEY, + TOGGLE_DEBUG_KEY, + + // Camera controls + CAMERA_TO_MOUSE_KEY, + CAMERA_TO_PLAYER_KEY, + CAMERA_SHAKE_KEY, + + // UI controls + NOTIFY_KEY, + TOGGLE_FULLSCREEN_KEY, + + // Life system controls + LIFE_CAP_INCREASE_KEY, + LIFE_CAP_DECREASE_KEY, + LIFE_INCREASE_KEY, + LIFE_DECREASE_KEY, + + // Other settings + TARGET_FPS, + SNAP_SIZE, + DEBUG_MODE, + GAIN_BGM, + GAIN_SFX, + MUTE_BGM, + MUTE_SFX, + + TEST_KEY, + // @formatter:on } - public static int moveLeftKey = options.getInt(Option.moveLeftKey.toString(), KeyEvent.VK_A); - public static int moveRightKey = options.getInt(Option.moveRightKey.toString(), KeyEvent.VK_D); - public static int jumpKey = options.getInt(Option.jumpKey.toString(), KeyEvent.VK_SPACE); - public static int dashKey = options.getInt(Option.dashKey.toString(), KeyEvent.VK_SHIFT); - - public static int targetFrameRate = options.getInt(Option.targetFPS.toString(), 60); - public static int snapSize = options.getInt(Option.snapSize.toString(), 32); - public static int debugMode = options.getInt(Option.debugMode.toString(), 2); - - public static float gainBGM = options.getFloat(Option.gainBGM.toString(), 0); - public static float gainSFX = options.getFloat(Option.gainSFX.toString(), 0); - public static boolean muteBGM = options.getBoolean(Option.muteBGM.toString(), false); - public static boolean muteSFX = options.getBoolean(Option.muteSFX.toString(), false); - - protected static final int frameRateLow = KeyEvent.VK_X; - protected static final int frameRateHigh = KeyEvent.VK_Z; - protected static final int frameRateDefault = KeyEvent.VK_N; - protected static final int toggleDeadzone = KeyEvent.VK_V; - protected static final int toggleDebug = KeyEvent.VK_TAB; - protected static final int cameraToMouse = KeyEvent.VK_C; - protected static final int cameraToPlayer = KeyEvent.VK_F; - protected static final int shake = KeyEvent.VK_G; - protected static final int notify = KeyEvent.VK_H; - - public static final int lifeCapInc = KeyEvent.VK_P; - public static final int lifeCapDec = KeyEvent.VK_O; - public static final int lifeDec = KeyEvent.VK_K; - public static final int lifeInc = KeyEvent.VK_L; - public static final int fullscreen = KeyEvent.VK_F11; - - public static void save(Option Option, float value) { - options.putFloat(Option.toString(), value); - try { - options.flush(); - } catch (BackingStoreException e) { - Notifications.addNotification("Options Error", "Could not flush user preferences to registry."); - } + /** + * Defines default key mappings and their associated actions + */ + public static class DefaultKeys { + // Movement controls + public static final int MOVE_LEFT = KeyEvent.VK_A; + public static final int MOVE_RIGHT = KeyEvent.VK_D; + public static final int JUMP = KeyEvent.VK_SPACE; + public static final int DASH = KeyEvent.VK_SHIFT; + + // Debug and development controls + public static final int FRAME_RATE_LOW = KeyEvent.VK_X; + public static final int FRAME_RATE_HIGH = KeyEvent.VK_Z; + public static final int FRAME_RATE_DEFAULT = KeyEvent.VK_N; + public static final int TOGGLE_DEADZONE = KeyEvent.VK_V; + public static final int TOGGLE_DEBUG = KeyEvent.VK_TAB; + + // Camera controls + public static final int CAMERA_TO_MOUSE = KeyEvent.VK_C; + public static final int CAMERA_TO_PLAYER = KeyEvent.VK_F; + public static final int CAMERA_SHAKE = KeyEvent.VK_G; + + // UI controls + public static final int NOTIFY = KeyEvent.VK_H; + public static final int TOGGLE_FULLSCREEN = KeyEvent.VK_F11; + + // Life system controls + public static final int LIFE_CAP_INCREASE = KeyEvent.VK_P; + public static final int LIFE_CAP_DECREASE = KeyEvent.VK_O; + public static final int LIFE_INCREASE = KeyEvent.VK_L; + public static final int LIFE_DECREASE = KeyEvent.VK_K; } - public static void save(Option Option, int value) { - options.putInt(Option.toString(), value); - try { - options.flush(); - } catch (BackingStoreException e) { - Notifications.addNotification("Options Error", "Could not flush user preferences to registry."); - } + /** + * Game settings with their default values + */ + // Movement key bindings + public static int moveLeftKey = options.getInt(Option.MOVE_LEFT_KEY.toString(), DefaultKeys.MOVE_LEFT); + public static int moveRightKey = options.getInt(Option.MOVE_RIGHT_KEY.toString(), DefaultKeys.MOVE_RIGHT); + public static int jumpKey = options.getInt(Option.JUMP_KEY.toString(), DefaultKeys.JUMP); + public static int dashKey = options.getInt(Option.DASH_KEY.toString(), DefaultKeys.DASH); + + // Debug and development key bindings + public static int frameRateLowKey = options.getInt(Option.FRAME_RATE_LOW_KEY.toString(), DefaultKeys.FRAME_RATE_LOW); + public static int frameRateHighKey = options.getInt(Option.FRAME_RATE_HIGH_KEY.toString(), DefaultKeys.FRAME_RATE_HIGH); + public static int frameRateDefaultKey = options.getInt(Option.FRAME_RATE_DEFAULT_KEY.toString(), + DefaultKeys.FRAME_RATE_DEFAULT); + public static int toggleDeadzoneKey = options.getInt(Option.TOGGLE_DEADZONE_KEY.toString(), DefaultKeys.TOGGLE_DEADZONE); + public static int toggleDebugKey = options.getInt(Option.TOGGLE_DEBUG_KEY.toString(), DefaultKeys.TOGGLE_DEBUG); + + // Camera key bindings + public static int cameraToMouseKey = options.getInt(Option.CAMERA_TO_MOUSE_KEY.toString(), DefaultKeys.CAMERA_TO_MOUSE); + public static int cameraToPlayerKey = options.getInt(Option.CAMERA_TO_PLAYER_KEY.toString(), DefaultKeys.CAMERA_TO_PLAYER); + public static int cameraShakeKey = options.getInt(Option.CAMERA_SHAKE_KEY.toString(), DefaultKeys.CAMERA_SHAKE); + + // UI key bindings + public static int notifyKey = options.getInt(Option.NOTIFY_KEY.toString(), DefaultKeys.NOTIFY); + public static int toggleFullscreenKey = options.getInt(Option.TOGGLE_FULLSCREEN_KEY.toString(), + DefaultKeys.TOGGLE_FULLSCREEN); + + // Life system key bindings + public static int lifeCapIncreaseKey = options.getInt(Option.LIFE_CAP_INCREASE_KEY.toString(), DefaultKeys.LIFE_CAP_INCREASE); + public static int lifeCapDecreaseKey = options.getInt(Option.LIFE_CAP_DECREASE_KEY.toString(), DefaultKeys.LIFE_CAP_DECREASE); + public static int lifeIncreaseKey = options.getInt(Option.LIFE_INCREASE_KEY.toString(), DefaultKeys.LIFE_INCREASE); + public static int lifeDecreaseKey = options.getInt(Option.LIFE_DECREASE_KEY.toString(), DefaultKeys.LIFE_DECREASE); + + // Game settings + public static int targetFrameRate = options.getInt(Option.TARGET_FPS.toString(), 60); + public static int snapSize = options.getInt(Option.SNAP_SIZE.toString(), 32); + public static int debugMode = options.getInt(Option.DEBUG_MODE.toString(), 2); + + // Audio settings + public static float gainBGM = options.getFloat(Option.GAIN_BGM.toString(), 0); + public static float gainSFX = options.getFloat(Option.GAIN_SFX.toString(), 0); + public static boolean muteBGM = options.getBoolean(Option.MUTE_BGM.toString(), false); + public static boolean muteSFX = options.getBoolean(Option.MUTE_SFX.toString(), false); + + /** + * Saves a float value to the preferences + */ + public static void save(Option option, float value) { + options.putFloat(option.toString(), value); + flushOptions(); + } + + /** + * Saves an integer value to the preferences + */ + public static void save(Option option, int value) { + options.putInt(option.toString(), value); + flushOptions(); + } + + /** + * Saves a boolean value to the preferences + */ + public static void save(Option option, boolean value) { + options.putBoolean(option.toString(), value); + flushOptions(); } - public static void save(Option Option, boolean value) { - options.putBoolean(Option.toString(), value); + /** + * Flushes changes to the system's preference store + */ + private static void flushOptions() { try { options.flush(); } catch (BackingStoreException e) { Notifications.addNotification("Options Error", "Could not flush user preferences to registry."); } } - } \ No newline at end of file diff --git a/src/main/java/project_16x16/SideScroller.java b/src/main/java/project_16x16/SideScroller.java index 7466b14..687b25b 100644 --- a/src/main/java/project_16x16/SideScroller.java +++ b/src/main/java/project_16x16/SideScroller.java @@ -59,8 +59,7 @@ public static DebugType get(int value) { // Game Rendering private PVector windowSize = new PVector(1280, 720); // Game window size -- to be set via options - public PVector gameResolution = new PVector(1280, 720); // Game rendering resolution -- to be set - // via options + public PVector gameResolution = new PVector(1280, 720); // Game rendering resolution // Font Resources private static PFont font_pixel; @@ -72,16 +71,19 @@ public static DebugType get(int value) { private static GameplayScene game; private static PauseMenu pmenu; private static Settings settings; + private static MultiplayerMenu mMenu; private static MultiplayerHostMenu mHostMenu; private static MultiplayerClientMenu mClientMenu; + private static GraphicsSettings graphicsSettings; private static AudioSettings audioSettings; private static ControlsSettings controlsSettings; public enum GameScenes { MAIN_MENU(menu), GAME(game), PAUSE_MENU(pmenu), SETTINGS_MENU(settings), MULTIPLAYER_MENU(mMenu), - HOST_MENU(mHostMenu), CLIENT_MENU(mClientMenu), GRAPHICS_SETTINGS(graphicsSettings), AUDIO_SETTINGS(audioSettings), CONTROLS_SETTINGS(controlsSettings); + HOST_MENU(mHostMenu), CLIENT_MENU(mClientMenu), GRAPHICS_SETTINGS(graphicsSettings), AUDIO_SETTINGS(audioSettings), + CONTROLS_SETTINGS(controlsSettings), CONFIRMATION(null); PScene scene; @@ -92,6 +94,12 @@ private GameScenes(PScene scene) { public PScene getScene() { return scene; } + + // confirmation menus ("are you sure...") can be created ad-hoc, unlike other named scenes like "GAME" + public static GameScenes makeConfirmation(ConfirmationMenu newScene) { + GameScenes.CONFIRMATION.scene = newScene; + return GameScenes.CONFIRMATION; + } } // Events @@ -145,7 +153,7 @@ protected PSurface initSurface() { scene = canvas.getScene(); stage = (Stage) scene.getWindow(); stage.setTitle("Project-16x16"); - stage.setResizable(false); // prevent abitrary user resize + stage.setResizable(false); // prevent arbitrary user resize stage.setFullScreenExitHint(""); // disable fullscreen toggle hint stage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH); // prevent ESC toggling fullscreen scene.getWindow().addEventFilter(WindowEvent.WINDOW_CLOSE_REQUEST, this::closeWindowEvent); @@ -227,7 +235,7 @@ private void load() { } /** - * Use this method or {@link #returnScene()} to change the running game scene. + * Use this method or {@link #returnScene()} to change the running game scene to a named scene. * * @param newScene * @see #returnScene() @@ -338,45 +346,34 @@ public void keyReleased(processing.event.KeyEvent event) { keysDown.remove(event.getKeyCode()); keyReleaseEvent = true; - switch (event.getKeyCode()) { - case Options.frameRateHigh : - frameRate(5000); - break; - case Options.frameRateLow : - frameRate(20); - break; - case Options.frameRateDefault : - frameRate(Options.frameRateDefault); - break; - case Options.toggleDeadzone : - camera.toggleDeadZone(); - break; - case Options.cameraToMouse : - camera.setCameraPosition(camera.getMouseCoord()); - break; - case Options.cameraToPlayer : - camera.setFollowObject(game.getPlayer()); - camera.setZoomScale(1.0f); - break; - case Options.shake : - camera.shake(0.4f); - break; - case Options.notify : - Notifications.addNotification("Hello", "World"); - break; - case Options.fullscreen : - noLoop(); - stage.setFullScreen(!stage.isFullScreen()); - scaleResolution(); - loop(); - break; - case Options.toggleDebug : - debug = debug.next(); - Options.save(Option.debugMode, debug.ordinal()); - break; - default : - break; + final int keyCode = event.getKeyCode(); + if (keyCode == Options.frameRateHighKey) { + frameRate(5000); + } else if (keyCode == Options.frameRateLowKey) { + frameRate(20); + } else if (keyCode == Options.frameRateDefaultKey) { + frameRate(60); + } else if (keyCode == Options.toggleDeadzoneKey) { + camera.toggleDeadZone(); + } else if (keyCode == Options.cameraToMouseKey) { + camera.setCameraPosition(camera.getMouseCoord()); + } else if (keyCode == Options.cameraToPlayerKey) { + camera.setFollowObject(game.getPlayer()); + camera.setZoomScale(1.0f); + } else if (keyCode == Options.cameraShakeKey) { + camera.shake(0.4f); + } else if (keyCode == Options.notifyKey) { + Notifications.addNotification("Hello", "World"); + } else if (keyCode == Options.toggleFullscreenKey) { + noLoop(); + stage.setFullScreen(!stage.isFullScreen()); + scaleResolution(); + loop(); + } else if (keyCode == Options.toggleDebugKey) { + debug = debug.next(); + Options.save(Option.DEBUG_MODE, debug.ordinal()); } + } /** @@ -483,11 +480,13 @@ private void scaleResolution() { } private void displayDebugInfo() { + pushStyle(); final int lineOffset = 12; // vertical offset final int yOffset = 1; final int labelPadding = 225; // label -x offset (from screen width) final int ip = 1; // infoPadding -xoffset (from screen width) final Player player = game.getPlayer(); + PVector velocity = player.getVelocity(); fill(0, 50); noStroke(); @@ -539,17 +538,17 @@ private void displayDebugInfo() { lineOffset * 7 + yOffset); text("[" + "?" + "]", width - ip, lineOffset * 8 + yOffset); // TODO expose - text("['" + (char) Options.frameRateHigh + "']", width - ip, lineOffset * 12 + yOffset); - text("['" + (char) Options.frameRateLow + "']", width - ip, lineOffset * 13 + yOffset); - text("['" + (char) Options.toggleDeadzone + "']", width - ip, lineOffset * 14 + yOffset); - text("['" + (char) Options.cameraToMouse + "']", width - ip, lineOffset * 15 + yOffset); - text("['" + (char) Options.cameraToPlayer + "']", width - ip, lineOffset * 16 + yOffset); - text("['" + (char) Options.shake + "']", width - ip, lineOffset * 17 + yOffset); - text("['" + (char) Options.notify + "']", width - ip, lineOffset * 18 + yOffset); - text("['" + (char) Options.lifeCapInc + "']", width - ip, lineOffset * 19 + yOffset); - text("['" + (char) Options.lifeCapDec + "']", width - ip, lineOffset * 20 + yOffset); - text("['" + (char) Options.lifeInc + "']", width - ip, lineOffset * 21 + yOffset); - text("['" + (char) Options.lifeDec + "']", width - ip, lineOffset * 22 + yOffset); + text("['" + (char) Options.frameRateHighKey + "']", width - ip, lineOffset * 12 + yOffset); + text("['" + (char) Options.frameRateLowKey + "']", width - ip, lineOffset * 13 + yOffset); + text("['" + (char) Options.toggleDeadzoneKey + "']", width - ip, lineOffset * 14 + yOffset); + text("['" + (char) Options.cameraToMouseKey + "']", width - ip, lineOffset * 15 + yOffset); + text("['" + (char) Options.cameraToPlayerKey + "']", width - ip, lineOffset * 16 + yOffset); + text("['" + (char) Options.cameraShakeKey + "']", width - ip, lineOffset * 17 + yOffset); + text("['" + (char) Options.notifyKey + "']", width - ip, lineOffset * 18 + yOffset); + text("['" + (char) Options.lifeCapIncreaseKey + "']", width - ip, lineOffset * 19 + yOffset); + text("['" + (char) Options.lifeCapDecreaseKey + "']", width - ip, lineOffset * 20 + yOffset); + text("['" + (char) Options.lifeIncreaseKey + "']", width - ip, lineOffset * 21 + yOffset); + text("['" + (char) Options.lifeDecreaseKey + "']", width - ip, lineOffset * 22 + yOffset); text("['F11']", width - ip, lineOffset * 23 + yOffset); text("['TAB']", width - ip, lineOffset * 24 + yOffset); @@ -560,6 +559,7 @@ private void displayDebugInfo() { fill(255, 0, 0); } text("[" + round(frameRate) + "]", width - ip, lineOffset * 9 + yOffset); + popStyle(); } /** diff --git a/src/main/java/project_16x16/Utility.java b/src/main/java/project_16x16/Utility.java index ba1e3a9..64dbfc4 100644 --- a/src/main/java/project_16x16/Utility.java +++ b/src/main/java/project_16x16/Utility.java @@ -381,6 +381,21 @@ public static void convertTiledLevel(String filePath, String mapName) { Utility.saveFile("src/main/resources/Storage/Game/Maps/save/" + mapName + ".dat", Utility.encrypt(levelSave.toString())); } } + + public static String charToStr(int charCode) { + switch (charCode) { + case 32: + return "space"; + case 16: + return "shift"; + case 10: + return "newline"; + case 9: + return "tab"; + default: + return Character.toString((char) charCode); + } + } } /** diff --git a/src/main/java/project_16x16/scene/AudioSettings.java b/src/main/java/project_16x16/scene/AudioSettings.java index c2fd717..f1a2583 100644 --- a/src/main/java/project_16x16/scene/AudioSettings.java +++ b/src/main/java/project_16x16/scene/AudioSettings.java @@ -108,8 +108,8 @@ void mouseReleased(MouseEvent e) { if (apply.hover()) { float volBGM = 20 * (float) Math.log(volumeBGM.getValue()); float volSFX = 20 * (float) Math.log(volumeSFX.getValue()); - Options.save(Option.gainBGM, volBGM); - Options.save(Option.gainSFX, volSFX); + Options.save(Option.GAIN_BGM, volBGM); + Options.save(Option.GAIN_SFX, volSFX); Options.gainBGM = volBGM; Options.gainSFX = volSFX; Notifications.addNotification("Sound Settings Applied", "Your configuration has been successfully applied."); diff --git a/src/main/java/project_16x16/scene/ConfirmationMenu.java b/src/main/java/project_16x16/scene/ConfirmationMenu.java new file mode 100644 index 0000000..64b2315 --- /dev/null +++ b/src/main/java/project_16x16/scene/ConfirmationMenu.java @@ -0,0 +1,98 @@ +package project_16x16.scene; + +import processing.core.PImage; +import processing.event.MouseEvent; +import project_16x16.SideScroller; +import project_16x16.Utility; +import project_16x16.ui.Button; + +/** + * Confirmation menus offer the user a chance to confirm or cancel their + * proposed changes. The design is such that clicking "yes" should apply + * proposed changes (runs the given Runnable); clicking "no" is functionless, + * and merely goes back to the previous menu. + * + * @author micycle1 + * + */ +public class ConfirmationMenu extends PScene { + + private final Runnable onConfirm; + private final String menutext; + + private PImage cache; + + private Button yes; + private Button no; + + /** + * + * @param sideScroller + * @param onConfirm the code that runs if "yes" is clicked + * @param menutext + */ + public ConfirmationMenu(SideScroller sideScroller, Runnable onConfirm, String menutext) { + super(sideScroller); + this.onConfirm = onConfirm; + this.menutext = menutext; + + yes = new Button(applet); + yes.setText("Yes!"); + yes.setPosition(sideScroller.width / 2 - 100, sideScroller.height / 2); + yes.setSize(300, 100); + yes.setTextSize(40); + + no = new Button(applet); + no.setText("No!"); + no.setPosition(sideScroller.width / 2 + 100, sideScroller.height / 2); + no.setSize(300, 100); + no.setTextSize(40); + } + + public ConfirmationMenu(SideScroller sideScroller, Runnable onConfirm) { + this(sideScroller, onConfirm, null); + } + + @Override + public void drawUI() { + applet.image(cache, applet.width / 2, applet.height / 2); // draw cached & blurred game + + applet.textSize(60); + if (menutext != null) { + applet.text(menutext, applet.width / 2, 200); + applet.textSize(30); + applet.text("Are you sure?", applet.width / 2, 250); + } else { + applet.text("Are you sure?", applet.width / 2, 200); + } + + yes.display(); + no.display(); + } + + @Override + void mouseReleased(MouseEvent e) { + yes.update(); + no.update(); + + if (yes.hover()) { + onConfirm.run(); + applet.returnScene(); + return; + } + + if (no.hover()) { + applet.returnScene(); + return; + } + + } + + @Override + public void switchTo() { + super.switchTo(); + cache = applet.get(); // when game is paused, cache the game screen. + cache = Utility.blur(cache, 6, 2); // blur game screen + } + +} diff --git a/src/main/java/project_16x16/scene/ControlsSettings.java b/src/main/java/project_16x16/scene/ControlsSettings.java index 4ac9145..63a28d7 100644 --- a/src/main/java/project_16x16/scene/ControlsSettings.java +++ b/src/main/java/project_16x16/scene/ControlsSettings.java @@ -1,17 +1,15 @@ package project_16x16.scene; -import processing.core.PApplet; +import static project_16x16.Utility.charToStr; + import processing.core.PConstants; import processing.event.KeyEvent; import processing.event.MouseEvent; -import project_16x16.Audio; -import project_16x16.Constants; import project_16x16.Options; import project_16x16.Options.Option; import project_16x16.SideScroller; import project_16x16.ui.Button; import project_16x16.ui.Notifications; -import project_16x16.ui.Slider; public final class ControlsSettings extends PScene { @@ -19,6 +17,7 @@ public final class ControlsSettings extends PScene { private Button quit; private Button apply; + private Button reset; private Button changeJumpKey; private Button changeDashKey; private Button changeMoveLeftKey; @@ -41,34 +40,42 @@ public ControlsSettings(SideScroller a) { super(a); game = a; + initButtons(); + + newJumpKey = Options.jumpKey; + newDashKey = Options.dashKey; + newMoveLeftKey = Options.moveLeftKey; + newMoveRightKey = Options.moveRightKey; + } + + void initButtons() { apply = new Button(applet); apply.setText("Apply"); - apply.setPosition(a.width / 2, 500); + apply.setPosition(applet.width / 2, 500); - quit = new Button(a); + quit = new Button(applet); quit.setText("Quit"); - quit.setPosition(a.width / 2, 600); - - changeJumpKey = new Button(a); - changeJumpKey.setText("Change Jump Key: " + PApplet.str(Options.jumpKey)); - changeJumpKey.setPosition(a.width / 2, 150); + quit.setPosition(applet.width / 2, 600); - changeDashKey = new Button(a); - changeDashKey.setText("Change Dash Key: " + PApplet.str(Options.dashKey)); - changeDashKey.setPosition(a.width / 2, 200); + changeJumpKey = new Button(applet); + changeJumpKey.setText("Change Jump Key: " + charToStr(Options.jumpKey)); + changeJumpKey.setPosition(applet.width / 2, 150); - changeMoveLeftKey = new Button(a); - changeMoveLeftKey.setText("Change Move Left Key: " + PApplet.str(Options.moveLeftKey)); - changeMoveLeftKey.setPosition(a.width / 2, 250); + changeDashKey = new Button(applet); + changeDashKey.setText("Change Dash Key: " + charToStr(Options.dashKey)); + changeDashKey.setPosition(applet.width / 2, 200); - changeMoveRightKey = new Button(a); - changeMoveRightKey.setText("Change Move Right Key: " + PApplet.str(Options.moveRightKey)); - changeMoveRightKey.setPosition(a.width / 2, 300); + changeMoveLeftKey = new Button(applet); + changeMoveLeftKey.setText("Change Move Left Key: " + charToStr(Options.moveLeftKey)); + changeMoveLeftKey.setPosition(applet.width / 2, 250); - newJumpKey = Options.jumpKey; - newDashKey = Options.dashKey; - newMoveLeftKey = Options.moveLeftKey; - newMoveRightKey = Options.moveRightKey; + changeMoveRightKey = new Button(applet); + changeMoveRightKey.setText("Change Move Right Key: " + charToStr(Options.moveRightKey)); + changeMoveRightKey.setPosition(applet.width / 2, 300); + + reset = new Button(applet); + reset.setText("Reset All"); + reset.setPosition(applet.width / 2, 400); activeButton = null; } @@ -87,6 +94,7 @@ public void drawUI() { displayWindow(); apply.display(); quit.display(); + reset.display(); changeJumpKey.display(); changeDashKey.display(); @@ -99,7 +107,7 @@ public void drawUI() { game.text("Press a key to change the control!", game.width / 2, 100); } } - + private void displayWindow() { background(19, 23, 35); applet.fill(29, 33, 45); @@ -113,6 +121,7 @@ private void displayWindow() { void mouseReleased(MouseEvent e) { apply.update(); quit.update(); + reset.update(); changeJumpKey.update(); changeDashKey.update(); changeMoveLeftKey.update(); @@ -123,19 +132,19 @@ void mouseReleased(MouseEvent e) { newDashKey = originalDashKey; newMoveLeftKey = originalMoveLeftKey; newMoveRightKey = originalMoveRightKey; - changeJumpKey.setText("Change Jump Key: " + PApplet.str(originalJumpKey)); - changeDashKey.setText("Change Dash Key: " + PApplet.str(originalDashKey)); - changeMoveLeftKey.setText("Change Move Left Key: " + PApplet.str(originalMoveLeftKey)); - changeMoveRightKey.setText("Change Move Right Key: " + PApplet.str(originalMoveRightKey)); + changeJumpKey.setText("Change Jump Key: " + charToStr(originalJumpKey)); + changeDashKey.setText("Change Dash Key: " + charToStr(originalDashKey)); + changeMoveLeftKey.setText("Change Move Left Key: " + charToStr(originalMoveLeftKey)); + changeMoveRightKey.setText("Change Move Right Key: " + charToStr(originalMoveRightKey)); game.returnScene(); return; } if (apply.hover()) { - Options.save(Option.jumpKey, newJumpKey); - Options.save(Option.dashKey, newDashKey); - Options.save(Option.moveLeftKey, newMoveLeftKey); - Options.save(Option.moveRightKey, newMoveRightKey); + Options.save(Option.JUMP_KEY, newJumpKey); + Options.save(Option.DASH_KEY, newDashKey); + Options.save(Option.MOVE_LEFT_KEY, newMoveLeftKey); + Options.save(Option.MOVE_RIGHT_KEY, newMoveRightKey); Options.jumpKey = newJumpKey; Options.dashKey = newDashKey; Options.moveLeftKey = newMoveLeftKey; @@ -144,6 +153,22 @@ void mouseReleased(MouseEvent e) { Notifications.addNotification("Controls Settings Applied", "Your configuration has been successfully applied."); game.returnScene(); } + if (reset.hover()) { + ConfirmationMenu confirmReset = new ConfirmationMenu(game, () -> { + Options.save(Option.JUMP_KEY, Options.DefaultKeys.JUMP); + Options.save(Option.DASH_KEY, Options.DefaultKeys.DASH); + Options.save(Option.MOVE_LEFT_KEY, Options.DefaultKeys.MOVE_LEFT); + Options.save(Option.MOVE_RIGHT_KEY, Options.DefaultKeys.MOVE_RIGHT); + Options.jumpKey = Options.DefaultKeys.JUMP; + Options.dashKey = Options.DefaultKeys.DASH; + Options.moveLeftKey = Options.DefaultKeys.MOVE_LEFT; + Options.moveRightKey = Options.DefaultKeys.MOVE_RIGHT; + initButtons(); // remake buttons with new labels + Notifications.addNotification("Control Settings Reset", "Reset all control settings to default"); + }); + var c = SideScroller.GameScenes.makeConfirmation(confirmReset); + game.swapToScene(c); + } if (changeJumpKey.hover()) { activeButton = changeJumpKey; @@ -164,16 +189,16 @@ void keyReleased(KeyEvent e) { int key = e.getKeyCode(); if (activeButton == changeJumpKey) { newJumpKey = key; - changeJumpKey.setText("Change Jump Key: " + PApplet.str(key)); + changeJumpKey.setText("Change Jump Key: " + charToStr(key)); } else if (activeButton == changeDashKey) { newDashKey = key; - changeDashKey.setText("Change Dash Key: " + PApplet.str(key)); + changeDashKey.setText("Change Dash Key: " + charToStr(key)); } else if (activeButton == changeMoveLeftKey) { newMoveLeftKey = key; - changeMoveLeftKey.setText("Change Move Left Key: " + PApplet.str(key)); + changeMoveLeftKey.setText("Change Move Left Key: " + charToStr(key)); } else if (activeButton == changeMoveRightKey) { newMoveRightKey = key; - changeMoveRightKey.setText("Change Move Right Key: " + PApplet.str(key)); + changeMoveRightKey.setText("Change Move Right Key: " + charToStr(key)); } activeButton = null; } else if (e.getKeyCode() == PConstants.ESC) { diff --git a/src/main/java/project_16x16/scene/GameplayScene.java b/src/main/java/project_16x16/scene/GameplayScene.java index 3728be5..3c1d47c 100644 --- a/src/main/java/project_16x16/scene/GameplayScene.java +++ b/src/main/java/project_16x16/scene/GameplayScene.java @@ -525,24 +525,17 @@ public void mouseWheel(MouseEvent event) { @Override protected void keyReleased(processing.event.KeyEvent e) { - switch (e.getKeyCode()) { // Global gameplay hotkeys - case PConstants.ESC: // Pause - applet.swapToScene(GameScenes.PAUSE_MENU); - break; - case Options.lifeCapInc: - localPlayer.lifeCapacity++; - break; - case Options.lifeCapDec: - localPlayer.lifeCapacity--; - break; - case Options.lifeInc: - localPlayer.life++; - break; - case Options.lifeDec: - localPlayer.life--; - break; - default: - break; + final int keyCode = e.getKeyCode(); + if (keyCode == PConstants.ESC) { + applet.swapToScene(GameScenes.PAUSE_MENU); + } else if (keyCode == Options.lifeCapIncreaseKey) { + localPlayer.lifeCapacity++; + } else if (keyCode == Options.lifeCapDecreaseKey) { + localPlayer.lifeCapacity--; + } else if (keyCode == Options.lifeIncreaseKey) { + localPlayer.life++; + } else if (keyCode == Options.lifeDecreaseKey) { + localPlayer.life--; } currentMode.keyReleasedEvent(e); diff --git a/src/main/java/project_16x16/ui/Notifications.java b/src/main/java/project_16x16/ui/Notifications.java index 15bb0d0..fb43026 100644 --- a/src/main/java/project_16x16/ui/Notifications.java +++ b/src/main/java/project_16x16/ui/Notifications.java @@ -12,7 +12,9 @@ import project_16x16.Utility; /** - * Handles both drawing and logic of notifications. + * Handles both drawing and logic of notifications. Use + * {@link #addNotification(String, String) addNotification()} from anywhere + * within game code to display a notification to the user. * * @author micycle1 */ @@ -22,7 +24,8 @@ public class Notifications { private static PImage background; private static PVector positionTarget; - private static final int notificationWidth = 275, notificationHeight = 125, notificationTextPadding = 10, notificationLifetime = 240, notificationLifetimeFast = 150, notificationLifetimeVeryFast = 60; + private static final int notificationWidth = 275, notificationHeight = 125, notificationTextPadding = 10, + notificationLifetime = 240, notificationLifetimeFast = 150, notificationLifetimeVeryFast = 60; private final PVector position = new PVector(game.width - notificationWidth, game.height); private final String title, message; @@ -85,12 +88,10 @@ private void draw() { if (notifications.size() > 2) { if (notifications.size() < 6) { lifetime = notificationLifetimeFast; - } - else { + } else { lifetime = notificationLifetimeVeryFast; } - } - else { + } else { lifetime = notificationLifetime; } } diff --git a/src/test/java/project_16x16/OptionsTest.java b/src/test/java/project_16x16/OptionsTest.java index b1334b1..50eba09 100644 --- a/src/test/java/project_16x16/OptionsTest.java +++ b/src/test/java/project_16x16/OptionsTest.java @@ -15,9 +15,9 @@ public void callingSaveWithIntShouldUpdateOptions() { int expected = 5; Preferences options = Preferences.userNodeForPackage(Options.class); - Options.save(Options.Option.testKey, expected); + Options.save(Options.Option.TEST_KEY, expected); - assertEquals(expected, options.getInt(Options.Option.testKey.toString(), 0)); + assertEquals(expected, options.getInt(Options.Option.TEST_KEY.toString(), 0)); } @Test @@ -25,18 +25,18 @@ public void callingSaveWithFloatShouldUpdateOptions() { float expected = 5.5f; Preferences options = Preferences.userNodeForPackage(Options.class); - Options.save(Options.Option.testKey, expected); + Options.save(Options.Option.TEST_KEY, expected); - assertEquals(expected, options.getFloat(Options.Option.testKey.toString(), 0)); + assertEquals(expected, options.getFloat(Options.Option.TEST_KEY.toString(), 0)); } @Test public void callingSaveWithBooleanShouldUpdateOptions() { Preferences options = Preferences.userNodeForPackage(Options.class); - Options.save(Options.Option.testKey, true); + Options.save(Options.Option.TEST_KEY, true); - assertEquals(true, options.getBoolean(Options.Option.testKey.toString(), false)); + assertEquals(true, options.getBoolean(Options.Option.TEST_KEY.toString(), false)); } }