From 19b878cb64fd7153355fbdf748707726765a434a Mon Sep 17 00:00:00 2001 From: fredboy Date: Mon, 13 May 2024 20:31:34 +0700 Subject: [PATCH] Add preferences --- android/assets/json/menu_options_buttons.json | 8 +++- .../cavedroid/AndroidLauncher.java | 3 +- .../cavedroid/AndroidPreferencesStore.kt | 26 +++++++++++ .../ru/deadsoftware/cavedroid/CaveGame.java | 21 ++++++++- .../deadsoftware/cavedroid/MainComponent.java | 3 +- .../ru/deadsoftware/cavedroid/MainConfig.java | 44 ++++++++++++++++--- .../handler/mouse/CursorMouseInputHandler.kt | 13 +++++- .../deadsoftware/cavedroid/menu/MenuProc.java | 6 +-- .../menu/objects/BooleanOptionButton.kt | 29 ++++++++++++ .../cavedroid/menu/submenus/Menu.java | 31 ++++++++++--- .../cavedroid/menu/submenus/MenuOptions.kt | 1 - .../cavedroid/prefs/PreferencesStore.kt | 9 ++++ .../cavedroid/desktop/DesktopLauncher.java | 3 +- .../desktop/DesktopPreferencesStore.kt | 18 ++++++++ 14 files changed, 189 insertions(+), 26 deletions(-) create mode 100644 android/src/ru/deadsoftware/cavedroid/AndroidPreferencesStore.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/menu/objects/BooleanOptionButton.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/prefs/PreferencesStore.kt create mode 100644 desktop/src/ru/deadsoftware/cavedroid/desktop/DesktopPreferencesStore.kt diff --git a/android/assets/json/menu_options_buttons.json b/android/assets/json/menu_options_buttons.json index ebe1bf7..bb956cd 100644 --- a/android/assets/json/menu_options_buttons.json +++ b/android/assets/json/menu_options_buttons.json @@ -1,6 +1,12 @@ { "dyncam": { - "label": "Dynamic Camera: %%isUseDynamicCamera%%" + "option_type": "boolean", + "label": "Dynamic Camera: %%value%%" + }, + "fullscreen": { + "option_type": "boolean", + "label": "Fullscreen: %%value%%", + "visible_on_android": false }, "back": { "label": "Back" diff --git a/android/src/ru/deadsoftware/cavedroid/AndroidLauncher.java b/android/src/ru/deadsoftware/cavedroid/AndroidLauncher.java index e7aad50..3f38ad4 100644 --- a/android/src/ru/deadsoftware/cavedroid/AndroidLauncher.java +++ b/android/src/ru/deadsoftware/cavedroid/AndroidLauncher.java @@ -18,7 +18,8 @@ public class AndroidLauncher extends AndroidApplication { e.printStackTrace(); exit(); } - CaveGame caveGame = new CaveGame(gameFolder, true, null); + CaveGame caveGame = new CaveGame(gameFolder, true, + new AndroidPreferencesStore(getApplicationContext()), null); caveGame.setDebug(BuildConfig.DEBUG); initialize(caveGame, config); } diff --git a/android/src/ru/deadsoftware/cavedroid/AndroidPreferencesStore.kt b/android/src/ru/deadsoftware/cavedroid/AndroidPreferencesStore.kt new file mode 100644 index 0000000..4b16659 --- /dev/null +++ b/android/src/ru/deadsoftware/cavedroid/AndroidPreferencesStore.kt @@ -0,0 +1,26 @@ +package ru.deadsoftware.cavedroid + +import android.content.Context +import ru.deadsoftware.cavedroid.prefs.PreferencesStore + +class AndroidPreferencesStore( + private val context: Context +) : PreferencesStore { + + private val sharedPreferences by lazy { context.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE) } + + override fun getPreference(key: String): String? { + return sharedPreferences.getString(key, null) + } + + override fun setPreference(key: String, value: String?) { + with(sharedPreferences.edit()) { + putString(key, value) + apply() + } + } + + private companion object { + private const val SHARED_PREFS_NAME = "cavedroid_prefs" + } +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/CaveGame.java b/core/src/ru/deadsoftware/cavedroid/CaveGame.java index 9340552..9ca34b8 100644 --- a/core/src/ru/deadsoftware/cavedroid/CaveGame.java +++ b/core/src/ru/deadsoftware/cavedroid/CaveGame.java @@ -3,9 +3,11 @@ package ru.deadsoftware.cavedroid; import com.badlogic.gdx.Application; import com.badlogic.gdx.Game; import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Graphics; import ru.deadsoftware.cavedroid.game.GameScreen; import ru.deadsoftware.cavedroid.misc.Assets; import ru.deadsoftware.cavedroid.misc.utils.AssetLoader; +import ru.deadsoftware.cavedroid.prefs.PreferencesStore; import javax.annotation.Nullable; @@ -26,12 +28,19 @@ public class CaveGame extends Game { @Nullable private final String mAssetsPackPath; - public CaveGame(String gameFolder, boolean touch, @Nullable String assetsPackPath) { + public CaveGame(String gameFolder, + boolean touch, + PreferencesStore preferencesStore, + @Nullable String assetsPackPath) { mGameFolder = gameFolder; mTouch = touch; mAssetsPackPath = assetsPackPath; - mMainComponent = DaggerMainComponent.builder().caveGame(this).build(); + mMainComponent = DaggerMainComponent + .builder() + .caveGame(this) + .preferencesStore(preferencesStore) + .build(); mMainConfig = mMainComponent.getMainConfig(); mAssetLoader = mMainComponent.getAssetLoader(); @@ -58,6 +67,14 @@ public class CaveGame extends Game { } else { Gdx.app.setLogLevel(Application.LOG_ERROR); } + + mMainConfig.setFullscreenToggleListener((value) -> { + if (value) { + Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode()); + } else { + Gdx.graphics.setWindowedMode(width, height); + } + }); } public void newGame(int gameMode) { diff --git a/core/src/ru/deadsoftware/cavedroid/MainComponent.java b/core/src/ru/deadsoftware/cavedroid/MainComponent.java index c640fb6..b487c6d 100644 --- a/core/src/ru/deadsoftware/cavedroid/MainComponent.java +++ b/core/src/ru/deadsoftware/cavedroid/MainComponent.java @@ -4,11 +4,12 @@ import dagger.Component; import ru.deadsoftware.cavedroid.game.GameScreen; import ru.deadsoftware.cavedroid.menu.MenuScreen; import ru.deadsoftware.cavedroid.misc.utils.AssetLoader; +import ru.deadsoftware.cavedroid.prefs.PreferencesStore; import javax.inject.Singleton; @Singleton -@Component(dependencies = CaveGame.class) +@Component(dependencies = {CaveGame.class, PreferencesStore.class}) public interface MainComponent { GameScreen getGameScreen(); diff --git a/core/src/ru/deadsoftware/cavedroid/MainConfig.java b/core/src/ru/deadsoftware/cavedroid/MainConfig.java index 64950f2..3ffb506 100644 --- a/core/src/ru/deadsoftware/cavedroid/MainConfig.java +++ b/core/src/ru/deadsoftware/cavedroid/MainConfig.java @@ -2,16 +2,24 @@ package ru.deadsoftware.cavedroid; import ru.deadsoftware.cavedroid.game.GameUiWindow; import ru.deadsoftware.cavedroid.game.input.Joystick; +import ru.deadsoftware.cavedroid.prefs.PreferencesStore; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import javax.inject.Inject; import javax.inject.Singleton; +import java.util.HashMap; @Singleton public class MainConfig { + private final HashMap mPreferencesCache = new HashMap<>(); + + @CheckForNull + private FullscreenToggleListener mFullscreenToggleListener = null; + private final CaveGame mCaveGame; + private final PreferencesStore mPreferencesStore; @CheckForNull private MainComponent mMainComponent; @@ -29,14 +37,13 @@ public class MainConfig { private float mWidth; private float mHeight; - private boolean mUseDynamicCamera = true; - @Nullable private String mAssetsPackPath = null; @Inject - public MainConfig(CaveGame caveGame) { + public MainConfig(CaveGame caveGame, PreferencesStore preferencesStore) { mCaveGame = caveGame; + mPreferencesStore = preferencesStore; mGameUiWindow = GameUiWindow.NONE; mGameFolder = ""; @@ -129,11 +136,36 @@ public class MainConfig { mJoystick = joystick; } + @CheckForNull + public String getPreference(String key) { + if (mPreferencesCache.containsKey(key)) { + return mPreferencesCache.get(key); + } + + String value = mPreferencesStore.getPreference(key); + mPreferencesCache.put(key, value); + + return value; + } + + public void setPreference(String key, String value) { + mPreferencesCache.put(key, value); + mPreferencesStore.setPreference(key, value); + + if (mFullscreenToggleListener != null && key.equals("fullscreen")) { + mFullscreenToggleListener.onFullscreenToggled(Boolean.parseBoolean(value)); + } + } + + public void setFullscreenToggleListener(@Nullable FullscreenToggleListener fullscreenToggleListener) { + mFullscreenToggleListener = fullscreenToggleListener; + } + public boolean isUseDynamicCamera() { - return mUseDynamicCamera; + return Boolean.parseBoolean(getPreference("dyncam")); } - public void setUseDynamicCamera(boolean useDynamicCamera) { - mUseDynamicCamera = useDynamicCamera; + public interface FullscreenToggleListener { + void onFullscreenToggled(boolean value); } } diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CursorMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CursorMouseInputHandler.kt index 585a5ab..454337e 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CursorMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CursorMouseInputHandler.kt @@ -71,7 +71,7 @@ class CursorMouseInputHandler @Inject constructor( } private fun getPlayerHeadRotation(mouseWorldX: Float, mouseWorldY: Float): Float { - val h = mouseWorldX - player.x + val h = mouseWorldX - (player.x + player.width / 2) val v = mouseWorldY - player.y return MathUtils.atan(v / h) * MathUtils.radDeg @@ -88,6 +88,12 @@ class CursorMouseInputHandler @Inject constructor( player.cursorY = worldY.bl player.headRotation = getPlayerHeadRotation(worldX, worldY) + + if (worldX < player.x + player.width / 2) { + player.setDir(Mob.Direction.LEFT) + } else { + player.setDir(Mob.Direction.RIGHT) + } } private fun getCreativeTooltip(action: MouseInputAction): String? { @@ -125,7 +131,10 @@ class CursorMouseInputHandler @Inject constructor( } player.checkCursorBounds(gameWorld) - setPlayerDirectionToCursor() + + if (player.controlMode == Player.ControlMode.WALK && mainConfig.isTouch) { + setPlayerDirectionToCursor() + } if (player.cursorX != pastCursorX || player.cursorY != pastCursorY) { player.blockDamage = 0f diff --git a/core/src/ru/deadsoftware/cavedroid/menu/MenuProc.java b/core/src/ru/deadsoftware/cavedroid/menu/MenuProc.java index 5314809..aa3888a 100644 --- a/core/src/ru/deadsoftware/cavedroid/menu/MenuProc.java +++ b/core/src/ru/deadsoftware/cavedroid/menu/MenuProc.java @@ -10,9 +10,7 @@ import ru.deadsoftware.cavedroid.misc.Renderer; import javax.inject.Inject; -import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -54,8 +52,8 @@ public class MenuProc extends Renderer { mCurrentMenu = mMenuMain; } - public void toggleDynamicCamera() { - mMainConfig.setUseDynamicCamera(!mMainConfig.isUseDynamicCamera()); + public void setPreference(String key, Object value) { + mMainConfig.setPreference(key, value.toString()); } } diff --git a/core/src/ru/deadsoftware/cavedroid/menu/objects/BooleanOptionButton.kt b/core/src/ru/deadsoftware/cavedroid/menu/objects/BooleanOptionButton.kt new file mode 100644 index 0000000..56329d5 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/menu/objects/BooleanOptionButton.kt @@ -0,0 +1,29 @@ +package ru.deadsoftware.cavedroid.menu.objects + +import ru.deadsoftware.cavedroid.MainConfig + +class BooleanOptionButton( + private val mainConfig: MainConfig, + private val optionKey: String, + private val defaultValue: Boolean, + label: String, + x: Int, + y: Int, + type: Int, +) : Button( + label, + x, + y, + type, + { + val current = (mainConfig.getPreference(optionKey)?.toBooleanStrictOrNull()) ?: defaultValue + mainConfig.setPreference(optionKey, (!current).toString()) + } +) { + + override fun getLabel(): String { + val value = (mainConfig.getPreference(optionKey)?.toBooleanStrictOrNull()) ?: defaultValue + return super.getLabel().replace("%%value%%", value.toString()) + } + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/menu/submenus/Menu.java b/core/src/ru/deadsoftware/cavedroid/menu/submenus/Menu.java index 587d0f6..7e793b7 100644 --- a/core/src/ru/deadsoftware/cavedroid/menu/submenus/Menu.java +++ b/core/src/ru/deadsoftware/cavedroid/menu/submenus/Menu.java @@ -1,13 +1,16 @@ package ru.deadsoftware.cavedroid.menu.submenus; +import com.badlogic.gdx.Application; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.utils.ArrayMap; import com.badlogic.gdx.utils.JsonValue; +import kotlin.text.StringsKt; import ru.deadsoftware.cavedroid.MainConfig; import ru.deadsoftware.cavedroid.menu.MenuProc; +import ru.deadsoftware.cavedroid.menu.objects.BooleanOptionButton; import ru.deadsoftware.cavedroid.menu.objects.Button; import ru.deadsoftware.cavedroid.menu.objects.ButtonEventListener; import ru.deadsoftware.cavedroid.menu.objects.ButtonRenderer; @@ -76,13 +79,27 @@ public abstract class Menu { JsonValue json = Assets.jsonReader.parse(jsonFile); int y = (int) mHeight / 4; for (JsonValue key = json.child(); key != null; key = key.next(), y += Button.HEIGHT + 10) { - buttons.put(key.name(), - new Button(Assets.getStringFromJson(key, "label", ""), - (int) mWidth / 2 - Button.WIDTH / 2, - Assets.getIntFromJson(key, "y", y), - Assets.getIntFromJson(key, "type", Button.NORMAL), - eventListeners.containsKey(key.name()) ? eventListeners.get(key.name()) : () -> { - })); + + if (Gdx.app.getType() == Application.ApplicationType.Android && + !Assets.getBooleanFromJson(key, "visible_on_android", true)) { + continue; + } + + String optionType = Assets.getStringFromJson(key, "option_type", ""); + String label = Assets.getStringFromJson(key, "label", ""); + int x = (int) mWidth / 2 - Button.WIDTH / 2; + int type = Assets.getIntFromJson(key, "type", Button.NORMAL); + String defaultValue = Assets.getStringFromJson(key, "default_value", ""); + + + Button button = switch (optionType) { + case "boolean" -> + new BooleanOptionButton(mMainConfig, key.name(), Boolean.parseBoolean(defaultValue), label, x, y, type); + default -> + new Button(label, x, y, type, eventListeners.containsKey(key.name()) ? eventListeners.get(key.name()) : () -> {}); + }; + + buttons.put(key.name(), button); } } diff --git a/core/src/ru/deadsoftware/cavedroid/menu/submenus/MenuOptions.kt b/core/src/ru/deadsoftware/cavedroid/menu/submenus/MenuOptions.kt index 2b72bd6..7cc8a90 100644 --- a/core/src/ru/deadsoftware/cavedroid/menu/submenus/MenuOptions.kt +++ b/core/src/ru/deadsoftware/cavedroid/menu/submenus/MenuOptions.kt @@ -17,7 +17,6 @@ class MenuOptions( override fun getButtonEventListeners(): HashMap { val map = HashMap() - map["dyncam"] = ButtonEventListener { mMenuInput.toggleDynamicCamera() } map["back"] = ButtonEventListener { mMenuInput.backClicked() } return map } diff --git a/core/src/ru/deadsoftware/cavedroid/prefs/PreferencesStore.kt b/core/src/ru/deadsoftware/cavedroid/prefs/PreferencesStore.kt new file mode 100644 index 0000000..edc9517 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/prefs/PreferencesStore.kt @@ -0,0 +1,9 @@ +package ru.deadsoftware.cavedroid.prefs + +interface PreferencesStore { + + fun getPreference(key: String): String? + + fun setPreference(key: String, value: String?) + +} diff --git a/desktop/src/ru/deadsoftware/cavedroid/desktop/DesktopLauncher.java b/desktop/src/ru/deadsoftware/cavedroid/desktop/DesktopLauncher.java index fe78235..146d52a 100644 --- a/desktop/src/ru/deadsoftware/cavedroid/desktop/DesktopLauncher.java +++ b/desktop/src/ru/deadsoftware/cavedroid/desktop/DesktopLauncher.java @@ -34,7 +34,8 @@ class DesktopLauncher { } } - CaveGame caveGame = new CaveGame(System.getProperty("user.home") + "/.cavedroid", touch, assetsPath); + CaveGame caveGame = new CaveGame(System.getProperty("user.home") + "/.cavedroid", touch, + new DesktopPreferencesStore(), assetsPath); caveGame.setDebug(debug); new Lwjgl3Application(caveGame, config); diff --git a/desktop/src/ru/deadsoftware/cavedroid/desktop/DesktopPreferencesStore.kt b/desktop/src/ru/deadsoftware/cavedroid/desktop/DesktopPreferencesStore.kt new file mode 100644 index 0000000..03591bb --- /dev/null +++ b/desktop/src/ru/deadsoftware/cavedroid/desktop/DesktopPreferencesStore.kt @@ -0,0 +1,18 @@ +package ru.deadsoftware.cavedroid.desktop + +import ru.deadsoftware.cavedroid.prefs.PreferencesStore +import java.util.prefs.Preferences + +class DesktopPreferencesStore : PreferencesStore { + + private val prefs = Preferences.userNodeForPackage(DesktopPreferencesStore::class.java) + + override fun getPreference(key: String): String? { + return prefs.get(key, null) + } + + override fun setPreference(key: String, value: String?) { + prefs.put(key, value) + } + +} \ No newline at end of file -- 2.29.2