From: fredboy Date: Tue, 23 Apr 2024 02:10:52 +0000 (+0700) Subject: Refactor input handrling X-Git-Tag: alpha0.6.2~7 X-Git-Url: https://deadsoftware.ru/gitweb?p=cavedroid.git;a=commitdiff_plain;h=cf4113d5bfd3fca7c3815bf14a214eebd822216c Refactor input handrling --- diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameComponent.java b/core/src/ru/deadsoftware/cavedroid/game/GameComponent.java index 058c8b2..2dafcd5 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameComponent.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameComponent.java @@ -5,6 +5,8 @@ import ru.deadsoftware.cavedroid.MainComponent; import ru.deadsoftware.cavedroid.game.actions.PlaceBlockActionsModule; import ru.deadsoftware.cavedroid.game.actions.UpdateBlockActionsModule; import ru.deadsoftware.cavedroid.game.actions.UseItemActionsModule; +import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandlersModule; +import ru.deadsoftware.cavedroid.game.input.MouseInputHandlersModule; import ru.deadsoftware.cavedroid.game.render.RenderModule; @GameScope @@ -13,11 +15,12 @@ import ru.deadsoftware.cavedroid.game.render.RenderModule; UseItemActionsModule.class, UpdateBlockActionsModule.class, PlaceBlockActionsModule.class, - RenderModule.class}) + RenderModule.class, + KeyboardInputHandlersModule.class, + MouseInputHandlersModule.class + }) public interface GameComponent { GameProc getGameProc(); - GameInputProcessor getGameInputProcessor(); - GameItemsHolder getGameItemsHolder(); } diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameInput.java b/core/src/ru/deadsoftware/cavedroid/game/GameInput.java deleted file mode 100644 index 85fd63b..0000000 --- a/core/src/ru/deadsoftware/cavedroid/game/GameInput.java +++ /dev/null @@ -1,516 +0,0 @@ -package ru.deadsoftware.cavedroid.game; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.Input; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.math.Intersector; -import com.badlogic.gdx.math.MathUtils; -import com.badlogic.gdx.utils.TimeUtils; -import com.google.common.collect.Range; -import ru.deadsoftware.cavedroid.MainConfig; -import ru.deadsoftware.cavedroid.game.actions.CommonBlockActionUtilsKt; -import ru.deadsoftware.cavedroid.game.actions.placeblock.IPlaceBlockAction; -import ru.deadsoftware.cavedroid.game.actions.useitem.IUseItemAction; -import ru.deadsoftware.cavedroid.game.mobs.Mob; -import ru.deadsoftware.cavedroid.game.mobs.MobsController; -import ru.deadsoftware.cavedroid.game.mobs.Pig; -import ru.deadsoftware.cavedroid.game.mobs.Player; -import ru.deadsoftware.cavedroid.game.model.item.Item; -import ru.deadsoftware.cavedroid.game.objects.DropController; -import ru.deadsoftware.cavedroid.game.world.GameWorld; -import ru.deadsoftware.cavedroid.misc.Assets; -import ru.deadsoftware.cavedroid.misc.ControlMode; - -import javax.annotation.CheckForNull; -import javax.inject.Inject; - -import java.util.Map; - -@GameScope -public class GameInput { - - private static final String TAG = "GameInput"; - - private final MainConfig mMainConfig; - private final GameWorld mGameWorld; - private final DropController mDropController; - private final MobsController mMobsController; - private final GameItemsHolder mGameItemsHolder; - private final Map mUseItemActionMap; - private final Map mPlaceBlockActionMap; - - private final Player mPlayer; - - private ControlMode mControlMode; - - private boolean mKeyDown; - private boolean mTouchedDown; - private boolean mDragging; - - private int mKeyDownCode; - private int mTouchDownBtn; - private float mTouchDownX; - private float mTouchDownY; - private long mTouchDownTime; - - private int mCreativeScroll; - - @Inject - public GameInput(MainConfig mainConfig, - GameWorld gameWorld, - DropController dropController, - MobsController mobsController, - GameItemsHolder gameItemsHolder, - Map useItemActionMap, - Map placeBlockActionMap) { - mMainConfig = mainConfig; - mGameWorld = gameWorld; - mDropController = dropController; - mMobsController = mobsController; - mGameItemsHolder = gameItemsHolder; - mUseItemActionMap = useItemActionMap; - mPlaceBlockActionMap = placeBlockActionMap; - - mPlayer = mMobsController.getPlayer(); - - mControlMode = mMainConfig.isTouch() ? ControlMode.WALK : ControlMode.CURSOR; - } - - private boolean checkSwim() { - return mGameWorld.getForeMap(mPlayer.getMapX(), mPlayer.getLowerMapY()).isFluid(); - } - - private void goUpwards() { - if (checkSwim()) { - mPlayer.swim = true; - } else if (mPlayer.canJump()) { - mPlayer.jump(); - } else if (!mPlayer.isFlyMode() && mPlayer.gameMode == 1) { - mPlayer.setFlyMode(true); - mPlayer.getVelocity().y = 0; - } else if (mPlayer.isFlyMode()) { - mPlayer.getVelocity().y = -mPlayer.getSpeed(); - } - } - - @SuppressWarnings("IntegerDivisionInFloatingPointContext") - private boolean insideCreativeInv(float screenX, float screenY) { - TextureRegion creative = Assets.textureRegions.get("creative"); - return (screenX > mMainConfig.getWidth() / 2 - creative.getRegionWidth() / 2 && - screenX < mMainConfig.getWidth() / 2 + creative.getRegionWidth() / 2 && - screenY > mMainConfig.getHeight() / 2 - creative.getRegionHeight() / 2 && - screenY < mMainConfig.getHeight() / 2 + creative.getRegionHeight() / 2); - } - - private void wasdPressed(int keycode) { - if (mControlMode == ControlMode.WALK || !mMainConfig.isTouch()) { - switch (keycode) { - case Input.Keys.A: - mPlayer.getVelocity().x = -mPlayer.getSpeed(); - mPlayer.setDir(Mob.Direction.LEFT); - if (mMainConfig.isTouch() && checkSwim()) { - mPlayer.swim = true; - } - break; - case Input.Keys.D: - mPlayer.getVelocity().x = mPlayer.getSpeed(); - mPlayer.setDir(Mob.Direction.RIGHT); - if (mMainConfig.isTouch() && checkSwim()) { - mPlayer.swim = true; - } - break; - case Input.Keys.W: - case Input.Keys.SPACE: - goUpwards(); - break; - case Input.Keys.S: - case Input.Keys.CONTROL_LEFT: - mPlayer.getVelocity().y = mPlayer.getSpeed(); - break; - } - } else { - switch (keycode) { - case Input.Keys.A: - mPlayer.cursorX--; - break; - case Input.Keys.D: - mPlayer.cursorX++; - break; - case Input.Keys.W: - mPlayer.cursorY--; - break; - case Input.Keys.S: - mPlayer.cursorY++; - break; - } - mPlayer.blockDamage = 0; - } - } - - private boolean isNotAutoselectable(int x, int y) { - return (!mGameWorld.hasForeAt(x, y) || !mGameWorld.getForeMap(x, y).hasCollision()); - } - - private void checkCursorBounds() { - if (mPlayer.cursorY < 0) { - mPlayer.cursorY = 0; - } else if (mPlayer.cursorY >= mGameWorld.getHeight()) { - mPlayer.cursorY = mGameWorld.getHeight() - 1; - } - - if (mControlMode == ControlMode.CURSOR) { - if (mPlayer.cursorX * 16 + 8 < mPlayer.getX() + mPlayer.getWidth() / 2) { - mPlayer.setDir(Mob.Direction.LEFT); - } else { - mPlayer.setDir(Mob.Direction.RIGHT); - } - } - } - - public void moveCursor(GameRenderer gameRenderer) { - int pastX = mPlayer.cursorX; - int pastY = mPlayer.cursorY; - - if (mControlMode == ControlMode.WALK && mMainConfig.isTouch()) { - mPlayer.cursorX = mPlayer.getMapX() + (mPlayer.looksLeft() ? -1 : 1); - mPlayer.cursorY = mPlayer.getUpperMapY(); - for (int i = 0; i < 2 && isNotAutoselectable(mPlayer.cursorX, mPlayer.cursorY); i++) { - mPlayer.cursorY++; - } - if (isNotAutoselectable(mPlayer.cursorX, mPlayer.cursorY)) { - mPlayer.cursorX += mPlayer.looksLeft() ? 1 : -1; - } - } else if (!mMainConfig.isTouch()) { - final int tmpX = (int) (Gdx.input.getX() * (mMainConfig.getWidth() / - Gdx.graphics.getWidth()) + gameRenderer.getCamX()); - mPlayer.cursorX = tmpX / 16; - - final int tmpY = (int) (Gdx.input.getY() * (mMainConfig.getHeight() / - Gdx.graphics.getHeight()) + gameRenderer.getCamY()); - mPlayer.cursorY = tmpY / 16; - - if (tmpX < 0) { - mPlayer.cursorX--; - } - - final double a = tmpX - mPlayer.x; - final double b = tmpY - mPlayer.y; - - mPlayer.headRotation = (float) Math.atan(b / a) * MathUtils.radDeg; - } - - if (pastX != mPlayer.cursorX || pastY != mPlayer.cursorY) { - mPlayer.blockDamage = 0; - } - - checkCursorBounds(); - } - - private void useItem(int x, int y, @CheckForNull Item item, boolean bg) { - mPlayer.startHitting(); - - if (item == null) { - return; - } - - if (item instanceof Item.Placeable) { - if (!bg) { - CommonBlockActionUtilsKt.placeToForegroundAction(mPlaceBlockActionMap, (Item.Placeable) item, x, y); - } else { - CommonBlockActionUtilsKt.placeToBackgroundAction(mPlaceBlockActionMap, (Item.Placeable) item, x, y); - } - } else if (item instanceof Item.Usable) { - final String actionKey = ((Item.Usable) item).getUseActionKey(); - final IUseItemAction useItemAction = mUseItemActionMap.get(actionKey); - - if (useItemAction != null) { - useItemAction.perform((Item.Usable) item, x, y); - } else { - Gdx.app.error(TAG, "use item action " + actionKey + " not found"); - } - } - } - - private void hitMobs() { - final Player player = mMobsController.getPlayer(); - mMobsController.getMobs().forEach((mob) -> { - if (Intersector.overlaps(mob, player)) { - mob.damage(5); - mob.jump(); - } - }); - } - - private void pressLMB() { - if (mMainConfig.checkGameUiWindow(GameUiWindow.NONE)) { - mPlayer.startHitting(); - - if ((mGameWorld.hasForeAt(mPlayer.cursorX, mPlayer.cursorY) && mGameWorld.getForeMap(mPlayer.cursorX, mPlayer.cursorY).getHp() >= 0) || - (!mGameWorld.hasForeAt(mPlayer.cursorX, mPlayer.cursorY) && mGameWorld.hasBackAt(mPlayer.cursorX, mPlayer.cursorY) && - mGameWorld.getBackMap(mPlayer.cursorX, mPlayer.cursorY).getHp() >= 0)) { - if (mPlayer.gameMode == 0) { - if (mGameWorld.hasForeAt(mPlayer.cursorX, mPlayer.cursorY)) { - if (mPlayer.blockDamage >= mGameWorld.getForeMap(mPlayer.cursorX, mPlayer.cursorY).getHp()) { - mGameWorld.destroyForeMap(mPlayer.cursorX, mPlayer.cursorY); - mPlayer.blockDamage = 0; - } - } else if (mGameWorld.hasBackAt(mPlayer.cursorX, mPlayer.cursorY)) { - if (mPlayer.blockDamage >= mGameWorld.getBackMap(mPlayer.cursorX, mPlayer.cursorY).getHp()) { - mGameWorld.destroyBackMap(mPlayer.cursorX, mPlayer.cursorY); - mPlayer.blockDamage = 0; - } - } - } else { - if (mGameWorld.hasForeAt(mPlayer.cursorX, mPlayer.cursorY)) { - mGameWorld.placeToForeground(mPlayer.cursorX, mPlayer.cursorY, mGameItemsHolder.getFallbackBlock()); - } else if (mGameWorld.hasBackAt(mPlayer.cursorX, mPlayer.cursorY)) { - mGameWorld.placeToBackground(mPlayer.cursorX, mPlayer.cursorY, mGameItemsHolder.getFallbackBlock()); - } - mTouchedDown = false; - } - } else { - hitMobs(); - mTouchedDown = false; - } - } - } - - private boolean insideHotbar(float x, float y) { - TextureRegion hotbar = Assets.textureRegions.get("hotbar"); - return y < hotbar.getRegionHeight() && - Range.open(mMainConfig.getWidth() / 2 - (float) hotbar.getRegionWidth() / 2, - mMainConfig.getWidth() / 2 + (float) hotbar.getRegionWidth() / 2).contains(x); - } - - private void openInventory() { - switch (mPlayer.gameMode) { - case 0: - mMainConfig.setGameUiWindow(GameUiWindow.SURVIVAL_INVENTORY); - break; - case 1: - mMainConfig.setGameUiWindow(GameUiWindow.CREATIVE_INVENTORY); - break; - } - } - - private void holdMB() { - if (mTouchDownBtn == Input.Buttons.RIGHT) { - useItem(mPlayer.cursorX, mPlayer.cursorY, mPlayer.inventory[mPlayer.slot].getItem(), true); - mTouchedDown = false; - } else { - if (insideHotbar(mTouchDownX, mTouchDownY)) { - openInventory(); - mTouchedDown = false; - } - } - } - - public void keyDown(int keycode) { - mKeyDown = true; - mKeyDownCode = keycode; - switch (keycode) { - case Input.Keys.A: - case Input.Keys.D: - case Input.Keys.W: - case Input.Keys.S: - case Input.Keys.SPACE: - case Input.Keys.CONTROL_LEFT: - wasdPressed(keycode); - break; - - case Input.Keys.ALT_LEFT: - if (mMainConfig.isTouch()) { - mControlMode = mControlMode == ControlMode.WALK ? ControlMode.CURSOR : ControlMode.WALK; - } - break; - - case Input.Keys.E: - if (mMainConfig.checkGameUiWindow(GameUiWindow.NONE)) { - openInventory(); - } else { - mMainConfig.setGameUiWindow(GameUiWindow.NONE); - } - break; - - case Input.Keys.G: - final Mob pig = new Pig(mPlayer.cursorX * 16, mPlayer.cursorY * 16); - pig.attachToController(mMobsController); - break; - - case Input.Keys.GRAVE: - mMobsController.getPlayer().gameMode = (mMobsController.getPlayer().gameMode + 1) % 2; - break; - - case Input.Keys.ESCAPE: - case Input.Keys.BACK: - GameSaver.save(mMainConfig, mDropController, mMobsController, mGameWorld); - mMainConfig.getCaveGame().quitGame(); - break; - - case Input.Keys.F1: - mMainConfig.setShowInfo(!mMainConfig.isShowInfo()); - break; - - case Input.Keys.M: - mMainConfig.setShowMap(!mMainConfig.isShowMap()); - break; - } - } - - public void keyUp(int keycode) { - switch (keycode) { - case Input.Keys.A: - case Input.Keys.D: - mPlayer.getVelocity().x = 0; - if (mMainConfig.isTouch() && mPlayer.swim) { - mPlayer.swim = false; - } - break; - - case Input.Keys.W: - case Input.Keys.S: - case Input.Keys.SPACE: - case Input.Keys.CONTROL_LEFT: - if (mPlayer.isFlyMode()) { - mPlayer.getVelocity().y = 0; - } - if (mPlayer.swim) { - mPlayer.swim = false; - } - break; - } - } - - public void touchDown(float touchX, float touchY, int button) { - mTouchDownTime = TimeUtils.millis(); - mTouchedDown = true; - mTouchDownBtn = button; - mTouchDownX = touchX; - mTouchDownY = touchY; - } - - public void touchUp(float screenX, float screenY, int button) { - if (mDragging) { - mDragging = false; - return; - } - - if (mMainConfig.isTouch() && mKeyDown) { - keyUp(mKeyDownCode); - mKeyDown = false; - } - TextureRegion hotbar = Assets.textureRegions.get("hotbar"); - TextureRegion creative = Assets.textureRegions.get("creative"); - if (mTouchedDown) { - if (mMainConfig.checkGameUiWindow(GameUiWindow.CREATIVE_INVENTORY) && insideCreativeInv(screenX, screenY)) { - int ix = (int) (screenX - (mMainConfig.getWidth() / 2 - creative.getRegionWidth() / 2 + 8)) / 18; - int iy = (int) (screenY - (mMainConfig.getHeight() / 2 - creative.getRegionHeight() / 2 + 18)) / 18; - int itemPos = mCreativeScroll * 8 + (ix + iy * 8); - if (ix >= 8 || ix < 0 || iy < 0 || iy >= 5) { - itemPos = -1; - } - - System.arraycopy(mPlayer.inventory, 0, mPlayer.inventory, 1, 8); - final Item newItem = mGameItemsHolder.getItemFromCreativeInventory(itemPos); - mPlayer.inventory[0] = newItem.toInventoryItem(newItem.getParams().getMaxStack()); - } else if (mMainConfig.checkGameUiWindow(GameUiWindow.CREATIVE_INVENTORY)) { - mMainConfig.setGameUiWindow(GameUiWindow.NONE); - } else if (screenY < hotbar.getRegionHeight() && - screenX > mMainConfig.getWidth() / 2 - (float) hotbar.getRegionWidth() / 2 && - screenX < mMainConfig.getWidth() / 2 + (float) hotbar.getRegionWidth() / 2) { - mPlayer.slot = (int) ((screenX - (mMainConfig.getWidth() / 2 - hotbar.getRegionWidth() / 2)) / 20); - } else if (button == Input.Buttons.RIGHT) { - useItem(mPlayer.cursorX, mPlayer.cursorY, - mPlayer.inventory[mPlayer.slot].getItem(), false); - } else if (button == Input.Buttons.LEFT) { - mPlayer.stopHitting(); - mPlayer.blockDamage = 0; - } - } - mTouchedDown = false; - } - - public void touchDragged(float screenX, float screenY) { - if (Math.abs(screenX - mTouchDownX) < 16 && Math.abs(screenY - mTouchDownY) < 16) { - return; - } - - mDragging = true; - if (mMainConfig.checkGameUiWindow(GameUiWindow.CREATIVE_INVENTORY) && Math.abs(screenY - mTouchDownY) > 16) { - if (insideCreativeInv(screenX, screenY)) { - mCreativeScroll -= (screenY - mTouchDownY) / 16; - mTouchDownX = screenX; - mTouchDownY = screenY; - if (mCreativeScroll < 0) { - mCreativeScroll = 0; - } - - final int maxScroll = mGameItemsHolder.getCreativeScrollAmount(); - if (mCreativeScroll > maxScroll) { - mCreativeScroll = maxScroll; - } - } - } - } - - public void scrolled(float amountX, float amountY) { - switch (mMainConfig.getGameUiWindow()) { - case NONE: - mPlayer.slot += (int) amountY; - if (mPlayer.slot < 0) { - mPlayer.slot = 8; - } - if (mPlayer.slot > 8) { - mPlayer.slot = 0; - } - break; - case CREATIVE_INVENTORY: - mCreativeScroll += (int) amountY; - if (mCreativeScroll < 0) { - mCreativeScroll = 0; - } - - final int maxScroll = mGameItemsHolder.getCreativeScrollAmount(); - if (mCreativeScroll > maxScroll) { - mCreativeScroll = maxScroll; - } - break; - } - } - - public int getKeyDownCode() { - return mKeyDownCode; - } - - public boolean isKeyDown() { - return mKeyDown; - } - - public int getCreativeScroll() { - return mCreativeScroll; - } - - public ControlMode getControlMode() { - return mControlMode; - } - - public void setControlMode(ControlMode controlMode) { - mControlMode = controlMode; - } - - void update() { - if (!mTouchedDown) { - mPlayer.stopHitting(); - return; - } - - if (mTouchDownBtn == Input.Buttons.LEFT) { - pressLMB(); - } - - if (mTouchedDown && TimeUtils.timeSinceMillis(mTouchDownTime) > 500) { - holdMB(); - } - } - -} diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameInputProcessor.java b/core/src/ru/deadsoftware/cavedroid/game/GameInputProcessor.java deleted file mode 100644 index 7eb35bd..0000000 --- a/core/src/ru/deadsoftware/cavedroid/game/GameInputProcessor.java +++ /dev/null @@ -1,163 +0,0 @@ -package ru.deadsoftware.cavedroid.game; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.Input; -import com.badlogic.gdx.InputAdapter; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.utils.JsonValue; -import ru.deadsoftware.cavedroid.MainConfig; -import ru.deadsoftware.cavedroid.game.objects.TouchButton; -import ru.deadsoftware.cavedroid.misc.Assets; -import ru.deadsoftware.cavedroid.misc.utils.AssetLoader; - -import javax.inject.Inject; - -import static com.badlogic.gdx.utils.ObjectMap.Entry; - -@GameScope -public class GameInputProcessor extends InputAdapter { - - private static final TouchButton nullButton = new TouchButton(null, -1, true); - - private final GameInput mGameInput; - private final GameRenderer mGameRenderer; - private final MainConfig mMainConfig; - private final AssetLoader mAssetLoader; - - @Inject - public GameInputProcessor(GameInput gameInput, - GameRenderer gameRenderer, - MainConfig mainConfig, - AssetLoader assetLoader) { - mGameInput = gameInput; - mGameRenderer = gameRenderer; - mMainConfig = mainConfig; - mAssetLoader = assetLoader; - - loadTouchButtonsFromJSON(); - } - - private int getMouseKey(String name) { - switch (name) { - case "Left": - return Input.Buttons.LEFT; - case "Right": - return Input.Buttons.RIGHT; - case "Middle": - return Input.Buttons.MIDDLE; - case "Back": - return Input.Buttons.BACK; - case "Forward": - return Input.Buttons.FORWARD; - default: - return -1; - } - } - - private void loadTouchButtonsFromJSON() { - JsonValue json = Assets.jsonReader.parse(mAssetLoader.getAssetHandle("json/touch_buttons.json")); - for (JsonValue key = json.child(); key != null; key = key.next()) { - float x = key.getFloat("x"); - float y = key.getFloat("y"); - float w = key.getFloat("w"); - float h = key.getFloat("h"); - boolean mouse = Assets.getBooleanFromJson(key, "mouse", false); - String name = key.getString("key"); - int code = mouse ? getMouseKey(name) : Input.Keys.valueOf(name); - if (x < 0) { - x = mGameRenderer.getWidth() + x; - } - if (y < 0) { - y = mGameRenderer.getHeight() + y; - } - Assets.guiMap.put(key.name(), new TouchButton(new Rectangle(x, y, w, h), code, mouse)); - } - - } - - private float transformScreenX(int screenX) { - return mGameRenderer.getWidth() / Gdx.graphics.getWidth() * screenX; - } - - private float transformScreenY(int screenY) { - return mGameRenderer.getHeight() / Gdx.graphics.getHeight() * screenY; - } - - private TouchButton getTouchedKey(float touchX, float touchY) { - for (Entry entry : Assets.guiMap) { - TouchButton button = entry.value; - if (button.getRect().contains(touchX, touchY)) { - return button; - } - } - return nullButton; - } - - @Override - public boolean keyDown(int keycode) { - mGameInput.keyDown(keycode); - return false; - } - - @Override - public boolean keyUp(int keycode) { - mGameInput.keyUp(keycode); - return false; - } - - @Override - public boolean touchDown(int screenX, int screenY, int pointer, int button) { - float touchX = transformScreenX(screenX); - float touchY = transformScreenY(screenY); - - if (mMainConfig.isTouch()) { - TouchButton touchedKey = getTouchedKey(touchX, touchY); - if (touchedKey.isMouse()) { - mGameInput.touchDown(touchX, touchY, touchedKey.getCode()); - } else { - mGameInput.keyDown(touchedKey.getCode()); - } - } else { - mGameInput.touchDown(touchX, touchY, button); - } - return false; - } - - @Override - public boolean touchUp(int screenX, int screenY, int pointer, int button) { - float touchX = transformScreenX(screenX); - float touchY = transformScreenY(screenY); - - if (mMainConfig.isTouch()) { - TouchButton touchedKey = getTouchedKey(touchX, touchY); - if (touchedKey.isMouse()) { - mGameInput.touchUp(touchX, touchY, touchedKey.getCode()); - } else { - mGameInput.keyUp(mGameInput.getKeyDownCode()); - } - } else { - mGameInput.touchUp(touchX, touchY, button); - } - return false; - } - - @Override - public boolean touchDragged(int screenX, int screenY, int pointer) { - float touchX = transformScreenX(screenX); - float touchY = transformScreenY(screenY); - if (mMainConfig.isTouch() && mGameInput.isKeyDown()) { - if (getTouchedKey(touchX, touchY).getCode() == -1) { - mGameInput.keyUp(mGameInput.getKeyDownCode()); - } - } else { - mGameInput.touchDragged(touchX, touchY); - } - return false; - } - - @Override - public boolean scrolled(float amountX, float amountY) { - mGameInput.scrolled(amountX, amountY); - return false; - } -} diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameItemsHolder.kt b/core/src/ru/deadsoftware/cavedroid/game/GameItemsHolder.kt index 7a7ccab..1fbcd3d 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameItemsHolder.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/GameItemsHolder.kt @@ -118,7 +118,7 @@ class GameItemsHolder @Inject constructor( } } - fun getCreativeScrollAmount(): Int = itemsMap.size / 8 + fun getMaxCreativeScrollAmount(): Int = itemsMap.size / 8 fun getBlocksByType(type: Class): List { return blocksMap.values.filterIsInstance(type) diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameProc.java b/core/src/ru/deadsoftware/cavedroid/game/GameProc.java index 75605bf..94cd34b 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameProc.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameProc.java @@ -1,8 +1,11 @@ package ru.deadsoftware.cavedroid.game; +import com.badlogic.gdx.Gdx; import com.badlogic.gdx.utils.Disposable; import com.badlogic.gdx.utils.Timer; +import ru.deadsoftware.cavedroid.MainConfig; import ru.deadsoftware.cavedroid.game.mobs.MobsController; +import ru.deadsoftware.cavedroid.game.mobs.Player; import ru.deadsoftware.cavedroid.game.world.GameWorldBlocksLogicControllerTask; import ru.deadsoftware.cavedroid.game.world.GameWorldFluidsLogicControllerTask; import ru.deadsoftware.cavedroid.game.world.GameWorldMobDamageControllerTask; @@ -13,7 +16,6 @@ import javax.inject.Inject; public class GameProc implements Disposable { private final GamePhysics mGamePhysics; - private final GameInput mGameInput; private final GameRenderer mGameRenderer; private final MobsController mMobsController; private final GameWorldFluidsLogicControllerTask mGameWorldFluidsLogicControllerTask; @@ -23,8 +25,8 @@ public class GameProc implements Disposable { private final Timer mWorldLogicTimer = new Timer(); @Inject - public GameProc(GamePhysics gamePhysics, - GameInput gameInput, + public GameProc(MainConfig mainConfig, + GamePhysics gamePhysics, GameRenderer gameRenderer, MobsController mobsController, GameWorldFluidsLogicControllerTask gameWorldFluidsLogicControllerTask, @@ -32,14 +34,13 @@ public class GameProc implements Disposable { GameWorldMobDamageControllerTask gameWorldMobDamageControllerTask ) { mGamePhysics = gamePhysics; - mGameInput = gameInput; mGameRenderer = gameRenderer; mMobsController = mobsController; mGameWorldFluidsLogicControllerTask = gameWorldFluidsLogicControllerTask; mGameWorldBlocksLogicControllerTask = gameWorldBlocksLogicControllerTask; mGameWorldMobDamageControllerTask = gameWorldMobDamageControllerTask; - + mobsController.getPlayer().controlMode = mainConfig.isTouch() ? Player.ControlMode.WALK : Player.ControlMode.CURSOR; mWorldLogicTimer.scheduleTask(gameWorldFluidsLogicControllerTask, 0, GameWorldFluidsLogicControllerTask.FLUID_UPDATE_INTERVAL_SEC); @@ -55,10 +56,13 @@ public class GameProc implements Disposable { public void update(float delta) { mGamePhysics.update(delta); - mGameInput.update(); mGameRenderer.render(delta); } + public void show() { + Gdx.input.setInputProcessor(mGameRenderer); + } + @Override public void dispose() { mWorldLogicTimer.stop(); diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java b/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java index c0af140..b54bead 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java @@ -2,12 +2,24 @@ package ru.deadsoftware.cavedroid.game; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.utils.ObjectMap; import ru.deadsoftware.cavedroid.MainConfig; +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler; +import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction; +import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction; +import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey; +import ru.deadsoftware.cavedroid.game.input.handler.mouse.CursorMouseInputHandler; +import ru.deadsoftware.cavedroid.game.input.mapper.KeyboardInputActionMapper; +import ru.deadsoftware.cavedroid.game.input.mapper.MouseInputActionMapper; import ru.deadsoftware.cavedroid.game.mobs.MobsController; import ru.deadsoftware.cavedroid.game.mobs.Player; +import ru.deadsoftware.cavedroid.game.objects.TouchButton; import ru.deadsoftware.cavedroid.game.render.IGameRenderer; +import ru.deadsoftware.cavedroid.misc.Assets; import ru.deadsoftware.cavedroid.misc.Renderer; +import javax.annotation.CheckForNull; import javax.inject.Inject; import java.util.ArrayList; import java.util.Comparator; @@ -17,21 +29,35 @@ import java.util.Set; @GameScope public class GameRenderer extends Renderer { - private final GameInput mGameInput; + private final MainConfig mMainConfig; private final MobsController mMobsController; private final List mRenderers; + private final CursorMouseInputHandler mCursorMouseInputHandler; + private final MouseInputActionMapper mMouseInputActionMapper; + private final KeyboardInputActionMapper mKeyboardInputActionMapper; + private final Set> mMouseInputHandlers; + private final Set> mKeyboardInputHandlers; @Inject GameRenderer(MainConfig mainConfig, - GameInput gameInput, MobsController mobsController, - Set renderers) { + Set renderers, + CursorMouseInputHandler cursorMouseInputHandler, + MouseInputActionMapper mouseInputActionMapper, + KeyboardInputActionMapper keyboardInputActionMapper, + Set> mouseInputHandlers, + Set> keyboardInputHandlers) { super(mainConfig.getWidth(), mainConfig.getHeight()); - mGameInput = gameInput; + mMainConfig = mainConfig; mMobsController = mobsController; mRenderers = new ArrayList<>(renderers); mRenderers.sort(Comparator.comparingInt(IGameRenderer::getRenderLayer)); + mCursorMouseInputHandler = cursorMouseInputHandler; + mMouseInputActionMapper = mouseInputActionMapper; + mKeyboardInputActionMapper = keyboardInputActionMapper; + mMouseInputHandlers = mouseInputHandlers; + mKeyboardInputHandlers = keyboardInputHandlers; Gdx.gl.glClearColor(0f, .6f, .6f, 1f); } @@ -42,11 +68,146 @@ public class GameRenderer extends Renderer { player.getY() + player.getHeight() / 2 - getHeight() / 2); } + private float transformScreenX(int screenX) { + return getWidth() / Gdx.graphics.getWidth() * screenX; + } + + private float transformScreenY(int screenY) { + return getHeight() / Gdx.graphics.getHeight() * screenY; + } + + private void handleMousePosition() { + final Rectangle viewport = getCameraViewport(); + final MouseInputAction action = new MouseInputAction( + Gdx.input.getX() * (viewport.width / Gdx.graphics.getWidth()), + Gdx.input.getY() * (viewport.height / Gdx.graphics.getHeight()), + MouseInputActionKey.None.INSTANCE, + viewport); + + mCursorMouseInputHandler.handle(action); + } + + private boolean handleMouseAction(@CheckForNull MouseInputAction action) { + if (action == null) { + return false; + } + + boolean anyProcessed = false; + + for (IGameInputHandler handler : mMouseInputHandlers) { + final boolean conditions = handler.checkConditions(action); + if (conditions) { + anyProcessed = true; + handler.handle(action); + break; + } +// anyProcessed = anyProcessed || conditions; + } + return anyProcessed; + } + + private boolean onMouseActionEvent(int mouseX, int mouseY, int button, boolean touchUp) { + @CheckForNull MouseInputAction action = mMouseInputActionMapper + .map((float) mouseX, (float) mouseY, getCameraViewport(), button, touchUp); + return handleMouseAction(action); + } + + @Override + public boolean touchUp(int screenX, int screenY, int pointer, int button) { + float touchX = transformScreenX(screenX); + float touchY = transformScreenY(screenY); + + if (mMainConfig.isTouch()) { + @CheckForNull TouchButton touchedKey = getTouchedKey(touchX, touchY); + if (touchedKey != null && touchedKey.isMouse()) { + return onMouseActionEvent(screenX, screenY, touchedKey.getCode(), true); + } else if (touchedKey != null) { + return keyUp(touchedKey.getCode()); + } + } + + return onMouseActionEvent(screenX, screenY, button, true); + } + + @CheckForNull + private TouchButton getTouchedKey(float touchX, float touchY) { + for (ObjectMap.Entry entry : Assets.guiMap) { + TouchButton button = entry.value; + if (button.getRect().contains(touchX, touchY)) { + return button; + } + } + return null; + } + + @Override + public boolean touchDown(int screenX, int screenY, int pointer, int button) { + float touchX = transformScreenX(screenX); + float touchY = transformScreenY(screenY); + + if (mMainConfig.isTouch()) { + @CheckForNull TouchButton touchedKey = getTouchedKey(touchX, touchY); + if (touchedKey != null && touchedKey.isMouse()) { + return onMouseActionEvent(screenX, screenY, touchedKey.getCode(), false); + } else if (touchedKey != null) { + return keyDown(touchedKey.getCode()); + } + } + + return onMouseActionEvent(screenX, screenY, button, false); + } + + @Override + public boolean touchDragged(int screenX, int screenY, int pointer) { + @CheckForNull MouseInputAction action = + mMouseInputActionMapper.mapDragged(screenX, screenY, getCameraViewport()); + return handleMouseAction(action); + } + + @Override + public boolean scrolled(float amountX, float amountY) { + @CheckForNull MouseInputAction action = mMouseInputActionMapper + .mapScrolled(Gdx.input.getX(), Gdx.input.getY(), amountX, amountY, getCameraViewport()); + return handleMouseAction(action); + } + + private boolean handleKeyboardAction(int keycode, boolean isKeyDown) { + @CheckForNull final KeyboardInputAction action = mKeyboardInputActionMapper + .map(keycode, isKeyDown); + + if (action == null) { + return false; + } + + boolean anyProcessed = false; + + for (IGameInputHandler handler : mKeyboardInputHandlers) { + final boolean conditions = handler.checkConditions(action); + if (conditions) { + anyProcessed = true; + handler.handle(action); + break; + } + } + + return anyProcessed; + } + + @Override + public boolean keyDown(int keycode) { + return handleKeyboardAction(keycode, true); + } + + @Override + public boolean keyUp(int keycode) { + return handleKeyboardAction(keycode, false); + } @Override public void render(float delta) { updateCameraPosition(); - mGameInput.moveCursor(this); + handleMousePosition(); +// mGameInput.moveCursor(this); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameScreen.java b/core/src/ru/deadsoftware/cavedroid/game/GameScreen.java index 1d47b90..749d7d4 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameScreen.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameScreen.java @@ -16,8 +16,6 @@ public class GameScreen implements Screen { @CheckForNull private GameProc mGameProc; @CheckForNull - private GameInputProcessor mGameInputProcessor; - @CheckForNull private GameItemsHolder mGameItemsHolder; @Inject @@ -36,11 +34,8 @@ public class GameScreen implements Screen { .mainComponent(mMainConfig.getMainComponent()).build(); mGameProc = gameComponent.getGameProc(); - mGameInputProcessor = gameComponent.getGameInputProcessor(); mGameProc.setPlayerGameMode(gameMode); - - Gdx.input.setInputProcessor(gameComponent.getGameInputProcessor()); } public void loadGame() { @@ -54,9 +49,6 @@ public class GameScreen implements Screen { .mainComponent(mMainConfig.getMainComponent()).build(); mGameProc = gameComponent.getGameProc(); - mGameInputProcessor = gameComponent.getGameInputProcessor(); - - Gdx.input.setInputProcessor(gameComponent.getGameInputProcessor()); } @Override @@ -66,7 +58,8 @@ public class GameScreen implements Screen { @Override public void show() { - Gdx.input.setInputProcessor(mGameInputProcessor); +// Gdx.input.setInputProcessor(mGameInputProcessor); + mGameProc.show(); } @Override diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/IGameInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/IGameInputHandler.kt new file mode 100644 index 0000000..a8eaad1 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/IGameInputHandler.kt @@ -0,0 +1,19 @@ +package ru.deadsoftware.cavedroid.game.input + +import ru.deadsoftware.cavedroid.game.input.action.IGameInputAction + +interface IGameInputHandler { + + /** + * Implementation should check if conditions for handling an input are satisfied + * For example - inventory input handler should return false if inventory is closed + */ + fun checkConditions(action: A): Boolean + + /** + * Handle given input action. + * This will not be called if [checkConditions] returned false + */ + fun handle(action: A) + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/InputUtils.kt b/core/src/ru/deadsoftware/cavedroid/game/input/InputUtils.kt new file mode 100644 index 0000000..425822a --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/InputUtils.kt @@ -0,0 +1,21 @@ +package ru.deadsoftware.cavedroid.game.input + +import com.badlogic.gdx.graphics.g2d.TextureRegion +import com.badlogic.gdx.math.Rectangle +import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction +import ru.deadsoftware.cavedroid.misc.Assets + +fun isInsideHotbar(action: MouseInputAction): Boolean { + val hotbar = requireNotNull(Assets.textureRegions["hotbar"]) + + return action.screenY <= hotbar.regionHeight && + action.screenX >= action.cameraViewport.width / 2 - hotbar.regionWidth / 2 && + action.screenX <= action.cameraViewport.width / 2 + hotbar.regionWidth / 2 +} + +fun isInsideWindow(action: MouseInputAction, windowTexture: TextureRegion): Boolean { + return action.screenY > action.cameraViewport.height / 2 - windowTexture.regionHeight / 2 && + action.screenY < action.cameraViewport.height / 2 + windowTexture.regionHeight / 2 && + action.screenX > action.cameraViewport.width / 2 - windowTexture.regionWidth / 2 && + action.screenX < action.cameraViewport.width / 2 + windowTexture.regionWidth / 2 +} diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/KeyboardInputHandlersModule.kt b/core/src/ru/deadsoftware/cavedroid/game/input/KeyboardInputHandlersModule.kt new file mode 100644 index 0000000..8c5502c --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/KeyboardInputHandlersModule.kt @@ -0,0 +1,111 @@ +package ru.deadsoftware.cavedroid.game.input + +import dagger.Binds +import dagger.Module +import dagger.multibindings.IntoSet +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction +import ru.deadsoftware.cavedroid.game.input.handler.keyboard.* + +@Module +object KeyboardInputHandlersModule { + + @Binds + @IntoSet + @GameScope + fun bindGoLeftKeyboardInputHandler(handler: GoLeftKeyboardInputHandler): IGameInputHandler { + return handler + } + + @Binds + @IntoSet + @GameScope + fun bindGoRightKeyboardInputHandler(handler: GoRightKeyboardInputHandler): IGameInputHandler { + return handler + } + + @Binds + @IntoSet + @GameScope + fun bindJumpKeyboardActionHandler(handler: JumpKeyboardInputHandler): IGameInputHandler { + return handler + } + + @Binds + @IntoSet + @GameScope + fun bindFlyUpKeyboardActionHandler(handler: FlyUpKeyboardInputHandler): IGameInputHandler { + return handler + } + + @Binds + @IntoSet + @GameScope + fun bindTurnOnFlyModeKeyboardActionHandler(handler: TurnOnFlyModeKeyboardInputHandler): IGameInputHandler { + return handler + } + + @Binds + @IntoSet + @GameScope + fun bindFlyDownKeyboardActionHandler(handler: FlyDownKeyboardInputHandler): IGameInputHandler { + return handler + } + + @Binds + @IntoSet + @GameScope + fun bindOpenInventoryKeyboardInputHandler(handler: OpenInventoryKeyboardInputHandler): IGameInputHandler { + return handler + } + + @Binds + @IntoSet + @GameScope + fun bindCloseGameWindowKeyboardInputHandler(handler: CloseGameWindowKeyboardInputHandler): IGameInputHandler { + return handler + } + + @Binds + @IntoSet + @GameScope + fun bindToggleDebugInfoKeyboardInputHandler(handler: ToggleDebugInfoKeyboardInputHandler): IGameInputHandler { + return handler + } + + @Binds + @IntoSet + @GameScope + fun bindToggleMinimapKeyboardInputHandler(handler: ToggleMinimapKeyboardInputHandler): IGameInputHandler { + return handler + } + + @Binds + @IntoSet + @GameScope + fun bindToggleGameModeKeyboardInputHandler(handler: ToggleGameModeKeyboardInputHandler): IGameInputHandler { + return handler + } + + @Binds + @IntoSet + @GameScope + fun bindPauseGameKeyboardInputHandler(handler: PauseGameKeyboardInputHandler): IGameInputHandler { + return handler + } + + @Binds + @IntoSet + @GameScope + fun bindToggleControlsModeKeyboardInputHandler(handler: ToggleControlsModeKeyboardInputHandler): IGameInputHandler { + return handler + } + + @Binds + @IntoSet + @GameScope + fun bindMoveCursorControlsModeKeyboardInputHandler(handler: MoveCursorControlsModeKeyboardInputHandler): IGameInputHandler { + return handler + } + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/MouseInputHandlersModule.kt b/core/src/ru/deadsoftware/cavedroid/game/input/MouseInputHandlersModule.kt new file mode 100644 index 0000000..e17662e --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/MouseInputHandlersModule.kt @@ -0,0 +1,61 @@ +package ru.deadsoftware.cavedroid.game.input + +import dagger.Binds +import dagger.Module +import dagger.multibindings.IntoSet +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction +import ru.deadsoftware.cavedroid.game.input.handler.mouse.* + +@Module +object MouseInputHandlersModule { + + @Binds + @IntoSet + @GameScope + fun bindCursorMouseInputHandler(handler: CursorMouseInputHandler): IGameInputHandler { + return handler + } + + @Binds + @IntoSet + @GameScope + fun bindHoldHotbarMouseInputHandler(handler: HotbarMouseInputHandler): IGameInputHandler { + return handler + } + + @Binds + @IntoSet + @GameScope + fun bindCloseGameWindowMouseActionHandler(handler: CloseGameWindowMouseInputHandler): IGameInputHandler { + return handler + } + + @Binds + @IntoSet + @GameScope + fun bindCreativeInventoryScrollMouseInputHandler(handler: CreativeInventoryScrollMouseInputHandler): IGameInputHandler { + return handler + } + + @Binds + @IntoSet + @GameScope + fun bindSelectCreativeInventoryItemMouseActionHandler(handler: SelectCreativeInventoryItemMouseInputHandler): IGameInputHandler { + return handler + } + + @Binds + @IntoSet + @GameScope + fun bindAttackMouseInputHandler(handler: AttackMouseInputHandler): IGameInputHandler { + return handler + } + + @Binds + @IntoSet + @GameScope + fun bindUseItemMouseInputActionHandler(handler: UseItemMouseInputHandler): IGameInputHandler { + return handler + } +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/action/IGameInputAction.kt b/core/src/ru/deadsoftware/cavedroid/game/input/action/IGameInputAction.kt new file mode 100644 index 0000000..b982a92 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/action/IGameInputAction.kt @@ -0,0 +1,3 @@ +package ru.deadsoftware.cavedroid.game.input.action + +interface IGameInputAction \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/action/KeyboardInputAction.kt b/core/src/ru/deadsoftware/cavedroid/game/input/action/KeyboardInputAction.kt new file mode 100644 index 0000000..416d2e0 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/action/KeyboardInputAction.kt @@ -0,0 +1,8 @@ +package ru.deadsoftware.cavedroid.game.input.action + +import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey + +data class KeyboardInputAction( + val actionKey: KeyboardInputActionKey, + val isKeyDown: Boolean, +) : IGameInputAction \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/action/MouseInputAction.kt b/core/src/ru/deadsoftware/cavedroid/game/input/action/MouseInputAction.kt new file mode 100644 index 0000000..122ffda --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/action/MouseInputAction.kt @@ -0,0 +1,11 @@ +package ru.deadsoftware.cavedroid.game.input.action + +import com.badlogic.gdx.math.Rectangle +import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey + +data class MouseInputAction( + val screenX: Float, + val screenY: Float, + val actionKey: MouseInputActionKey, + val cameraViewport: Rectangle +) : IGameInputAction \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/action/keys/KeyboardInputActionKey.kt b/core/src/ru/deadsoftware/cavedroid/game/input/action/keys/KeyboardInputActionKey.kt new file mode 100644 index 0000000..b3006a6 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/action/keys/KeyboardInputActionKey.kt @@ -0,0 +1,23 @@ +package ru.deadsoftware.cavedroid.game.input.action.keys + +sealed interface KeyboardInputActionKey { + + data object Left : KeyboardInputActionKey + data object Right : KeyboardInputActionKey + data object Down : KeyboardInputActionKey + + data object Jump : KeyboardInputActionKey + + data object Crouch : KeyboardInputActionKey + + data object SwitchControlsMode : KeyboardInputActionKey + + data object OpenInventory : KeyboardInputActionKey + + data object Pause : KeyboardInputActionKey + + data object ShowDebug : KeyboardInputActionKey + data object SpawnPig : KeyboardInputActionKey + data object SwitchGameMode : KeyboardInputActionKey + data object ShowMap : KeyboardInputActionKey +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/action/keys/MouseInputActionKey.kt b/core/src/ru/deadsoftware/cavedroid/game/input/action/keys/MouseInputActionKey.kt new file mode 100644 index 0000000..ce5bdc2 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/action/keys/MouseInputActionKey.kt @@ -0,0 +1,37 @@ +package ru.deadsoftware.cavedroid.game.input.action.keys + +sealed interface MouseInputActionKey { + + val touchUp: Boolean + + data object None : MouseInputActionKey { + override val touchUp: Boolean + get() = throw IllegalAccessException("not applicable for mouse move action") + } + + data object Dragged : MouseInputActionKey { + override val touchUp: Boolean + get() = throw IllegalAccessException("not applicable for mouse dragged action") + } + + data class Left( + override val touchUp: Boolean + ) : MouseInputActionKey + + data class Right( + override val touchUp: Boolean + ) : MouseInputActionKey + + data class Middle( + override val touchUp: Boolean + ) : MouseInputActionKey + + data class Scroll( + val amountX: Float, + val amountY: Float + ) : MouseInputActionKey { + override val touchUp: Boolean + get() = throw IllegalAccessException("not applicable for mouse scroll action") + } + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt new file mode 100644 index 0000000..0111949 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt @@ -0,0 +1,24 @@ +package ru.deadsoftware.cavedroid.game.input.handler.keyboard + +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.GameUiWindow +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey +import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager +import javax.inject.Inject + +@GameScope +class CloseGameWindowKeyboardInputHandler @Inject constructor( + private val gameWindowsManager: GameWindowsManager +) : IGameInputHandler { + + override fun checkConditions(action: KeyboardInputAction): Boolean { + return action.actionKey is KeyboardInputActionKey.OpenInventory && + action.isKeyDown && gameWindowsManager.getCurrentWindow() != GameUiWindow.NONE + } + + override fun handle(action: KeyboardInputAction) { + gameWindowsManager.closeWindow() + } +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/FlyDownKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/FlyDownKeyboardInputHandler.kt new file mode 100644 index 0000000..90347c4 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/FlyDownKeyboardInputHandler.kt @@ -0,0 +1,32 @@ +package ru.deadsoftware.cavedroid.game.input.handler.keyboard + +import ru.deadsoftware.cavedroid.MainConfig +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.mobs.Player +import javax.inject.Inject + +@GameScope +class FlyDownKeyboardInputHandler @Inject constructor( + private val mainConfig: MainConfig, + private val mobsController: MobsController, +) : IGameInputHandler { + + override fun checkConditions(action: KeyboardInputAction): Boolean { + return action.actionKey is KeyboardInputActionKey.Down && + mobsController.player.isFlyMode && + (mobsController.player.controlMode == Player.ControlMode.WALK || !mainConfig.isTouch) + } + + override fun handle(action: KeyboardInputAction) { + if (action.isKeyDown) { + mobsController.player.velocity.y = mobsController.player.speed + } else { + mobsController.player.velocity.y = 0f + } + } + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/FlyUpKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/FlyUpKeyboardInputHandler.kt new file mode 100644 index 0000000..2c6efc9 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/FlyUpKeyboardInputHandler.kt @@ -0,0 +1,32 @@ +package ru.deadsoftware.cavedroid.game.input.handler.keyboard + +import ru.deadsoftware.cavedroid.MainConfig +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.mobs.Player +import javax.inject.Inject + +@GameScope +class FlyUpKeyboardInputHandler @Inject constructor( + private val mainConfig: MainConfig, + private val mobsController: MobsController, +) : IGameInputHandler { + + override fun checkConditions(action: KeyboardInputAction): Boolean { + return action.actionKey is KeyboardInputActionKey.Jump && + mobsController.player.isFlyMode && + (mobsController.player.controlMode == Player.ControlMode.WALK || !mainConfig.isTouch) + } + + override fun handle(action: KeyboardInputAction) { + if (action.isKeyDown) { + mobsController.player.velocity.y = -mobsController.player.speed + } else { + mobsController.player.velocity.y = 0f + } + } + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/GoLeftKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/GoLeftKeyboardInputHandler.kt new file mode 100644 index 0000000..07ddb52 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/GoLeftKeyboardInputHandler.kt @@ -0,0 +1,33 @@ +package ru.deadsoftware.cavedroid.game.input.handler.keyboard + +import ru.deadsoftware.cavedroid.MainConfig +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey +import ru.deadsoftware.cavedroid.game.mobs.Mob +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.mobs.Player +import javax.inject.Inject + +@GameScope +class GoLeftKeyboardInputHandler @Inject constructor( + private val mainConfig: MainConfig, + private val mobsController: MobsController, +) : IGameInputHandler { + + override fun checkConditions(action: KeyboardInputAction): Boolean { + return action.actionKey is KeyboardInputActionKey.Left && + (mobsController.player.controlMode == Player.ControlMode.WALK || !mainConfig.isTouch) && + (mobsController.player.controlMode == Player.ControlMode.WALK || !mainConfig.isTouch) + } + + override fun handle(action: KeyboardInputAction) { + if (action.isKeyDown) { + mobsController.player.velocity.x = -mobsController.player.speed + mobsController.player.setDir(Mob.Direction.LEFT) + } else { + mobsController.player.velocity.x = 0f + } + } +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/GoRightKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/GoRightKeyboardInputHandler.kt new file mode 100644 index 0000000..8f8f038 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/GoRightKeyboardInputHandler.kt @@ -0,0 +1,32 @@ +package ru.deadsoftware.cavedroid.game.input.handler.keyboard + +import ru.deadsoftware.cavedroid.MainConfig +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey +import ru.deadsoftware.cavedroid.game.mobs.Mob +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.mobs.Player +import javax.inject.Inject + +@GameScope +class GoRightKeyboardInputHandler @Inject constructor( + private val mainConfig: MainConfig, + private val mobsController: MobsController +) : IGameInputHandler { + + override fun checkConditions(action: KeyboardInputAction): Boolean { + return action.actionKey is KeyboardInputActionKey.Right && + (mobsController.player.controlMode == Player.ControlMode.WALK || !mainConfig.isTouch) + } + + override fun handle(action: KeyboardInputAction) { + if (action.isKeyDown) { + mobsController.player.velocity.x = mobsController.player.speed + mobsController.player.setDir(Mob.Direction.RIGHT) + } else { + mobsController.player.velocity.x = 0f + } + } +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/JumpKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/JumpKeyboardInputHandler.kt new file mode 100644 index 0000000..1fbc9fb --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/JumpKeyboardInputHandler.kt @@ -0,0 +1,29 @@ +package ru.deadsoftware.cavedroid.game.input.handler.keyboard + +import ru.deadsoftware.cavedroid.MainConfig +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.mobs.Player +import javax.inject.Inject + +@GameScope +class JumpKeyboardInputHandler @Inject constructor( + private val mainConfig: MainConfig, + private val mobsController: MobsController, +) : IGameInputHandler { + + override fun checkConditions(action: KeyboardInputAction): Boolean { + return action.actionKey is KeyboardInputActionKey.Jump && + mobsController.player.canJump() && !mobsController.player.isFlyMode && + action.isKeyDown && + (mobsController.player.controlMode == Player.ControlMode.WALK || !mainConfig.isTouch) + } + + override fun handle(action: KeyboardInputAction) { + mobsController.player.jump() + } + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/MoveCursorControlsModeKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/MoveCursorControlsModeKeyboardInputHandler.kt new file mode 100644 index 0000000..ac82cb8 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/MoveCursorControlsModeKeyboardInputHandler.kt @@ -0,0 +1,62 @@ +package ru.deadsoftware.cavedroid.game.input.handler.keyboard + +import com.badlogic.gdx.math.MathUtils +import ru.deadsoftware.cavedroid.MainConfig +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.mobs.Player +import ru.deadsoftware.cavedroid.game.world.GameWorld +import javax.inject.Inject + +@GameScope +class MoveCursorControlsModeKeyboardInputHandler @Inject constructor( + private val mainConfig: MainConfig, + private val mobsController: MobsController, + private val gameWorld: GameWorld, +) : IGameInputHandler { + + override fun checkConditions(action: KeyboardInputAction): Boolean { + return mainConfig.isTouch && + mobsController.player.controlMode == Player.ControlMode.CURSOR && action.isKeyDown && + (action.actionKey is KeyboardInputActionKey.Left || + action.actionKey is KeyboardInputActionKey.Right || + action.actionKey is KeyboardInputActionKey.Jump || + action.actionKey is KeyboardInputActionKey.Down) + } + + private fun checkCursorBounds() { + val player = mobsController.player + if (player.gameMode == 0) { + val minCursorX = player.mapX - SURVIVAL_CURSOR_RANGE + val maxCursorX = player.mapX + SURVIVAL_CURSOR_RANGE + val minCursorY = player.middleMapY - SURVIVAL_CURSOR_RANGE + val maxCursorY = player.middleMapY + SURVIVAL_CURSOR_RANGE + + player.cursorX = MathUtils.clamp(player.cursorX, minCursorX, maxCursorX) + player.cursorY = MathUtils.clamp(player.cursorY, minCursorY, maxCursorY) + } + + player.cursorY = MathUtils.clamp(player.cursorY, 0, gameWorld.height - 1) + } + + override fun handle(action: KeyboardInputAction) { + val player = mobsController.player + + when (action.actionKey) { + KeyboardInputActionKey.Left -> player.cursorX-- + KeyboardInputActionKey.Right -> player.cursorX++ + KeyboardInputActionKey.Jump -> player.cursorY-- + KeyboardInputActionKey.Down -> player.cursorY++ + else -> return + } + + checkCursorBounds() + } + + companion object { + private const val SURVIVAL_CURSOR_RANGE = 4 + } +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt new file mode 100644 index 0000000..f04c993 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt @@ -0,0 +1,24 @@ +package ru.deadsoftware.cavedroid.game.input.handler.keyboard + +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.GameUiWindow +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey +import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager +import javax.inject.Inject + +@GameScope +class OpenInventoryKeyboardInputHandler @Inject constructor( + private val gameWindowsManager: GameWindowsManager +) : IGameInputHandler { + + override fun checkConditions(action: KeyboardInputAction): Boolean { + return action.actionKey is KeyboardInputActionKey.OpenInventory && + action.isKeyDown && gameWindowsManager.getCurrentWindow() == GameUiWindow.NONE + } + + override fun handle(action: KeyboardInputAction) { + gameWindowsManager.openInventory() + } +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/PauseGameKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/PauseGameKeyboardInputHandler.kt new file mode 100644 index 0000000..60a9edf --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/PauseGameKeyboardInputHandler.kt @@ -0,0 +1,30 @@ +package ru.deadsoftware.cavedroid.game.input.handler.keyboard + +import ru.deadsoftware.cavedroid.MainConfig +import ru.deadsoftware.cavedroid.game.GameSaver +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.objects.DropController +import ru.deadsoftware.cavedroid.game.world.GameWorld +import javax.inject.Inject + +@GameScope +class PauseGameKeyboardInputHandler @Inject constructor( + private val mainConfig: MainConfig, + private val dropController: DropController, + private val mobsController: MobsController, + private val gameWorld: GameWorld, +) : IGameInputHandler { + + override fun checkConditions(action: KeyboardInputAction): Boolean { + return action.actionKey is KeyboardInputActionKey.Pause && action.isKeyDown + } + + override fun handle(action: KeyboardInputAction) { + GameSaver.save(mainConfig, dropController, mobsController, gameWorld) + mainConfig.caveGame.quitGame() + } +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleControlsModeKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleControlsModeKeyboardInputHandler.kt new file mode 100644 index 0000000..3deacbd --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleControlsModeKeyboardInputHandler.kt @@ -0,0 +1,31 @@ +package ru.deadsoftware.cavedroid.game.input.handler.keyboard + +import ru.deadsoftware.cavedroid.MainConfig +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.mobs.Player +import javax.inject.Inject + +@GameScope +class ToggleControlsModeKeyboardInputHandler @Inject constructor( + private val mainConfig: MainConfig, + private val mobsController: MobsController, +) : IGameInputHandler { + + override fun checkConditions(action: KeyboardInputAction): Boolean { + return action.actionKey is KeyboardInputActionKey.SwitchControlsMode && action.isKeyDown + && mainConfig.isTouch + } + + override fun handle(action: KeyboardInputAction) { + if (mobsController.player.controlMode == Player.ControlMode.WALK) { + mobsController.player.controlMode = Player.ControlMode.CURSOR + } else { + mobsController.player.controlMode = Player.ControlMode.WALK + } + } + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleDebugInfoKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleDebugInfoKeyboardInputHandler.kt new file mode 100644 index 0000000..96bc21d --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleDebugInfoKeyboardInputHandler.kt @@ -0,0 +1,22 @@ +package ru.deadsoftware.cavedroid.game.input.handler.keyboard + +import ru.deadsoftware.cavedroid.MainConfig +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey +import javax.inject.Inject + +@GameScope +class ToggleDebugInfoKeyboardInputHandler @Inject constructor( + private val mainConfig: MainConfig +) : IGameInputHandler { + + override fun checkConditions(action: KeyboardInputAction): Boolean { + return action.actionKey is KeyboardInputActionKey.ShowDebug && action.isKeyDown + } + + override fun handle(action: KeyboardInputAction) { + mainConfig.isShowInfo = !mainConfig.isShowInfo + } +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleGameModeKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleGameModeKeyboardInputHandler.kt new file mode 100644 index 0000000..ef4e696 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleGameModeKeyboardInputHandler.kt @@ -0,0 +1,29 @@ +package ru.deadsoftware.cavedroid.game.input.handler.keyboard + +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import javax.inject.Inject + +@GameScope +class ToggleGameModeKeyboardInputHandler @Inject constructor( + private val mobsController: MobsController +) : IGameInputHandler { + + + override fun checkConditions(action: KeyboardInputAction): Boolean { + return action.actionKey is KeyboardInputActionKey.SwitchGameMode && action.isKeyDown + } + + override fun handle(action: KeyboardInputAction) { + if (mobsController.player.gameMode == 1) { + mobsController.player.gameMode = 0 + } else if (mobsController.player.gameMode == 0) { + mobsController.player.gameMode = 1 + } + } + + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleMinimapKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleMinimapKeyboardInputHandler.kt new file mode 100644 index 0000000..d39dfdb --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleMinimapKeyboardInputHandler.kt @@ -0,0 +1,22 @@ +package ru.deadsoftware.cavedroid.game.input.handler.keyboard + +import ru.deadsoftware.cavedroid.MainConfig +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey +import javax.inject.Inject + +@GameScope +class ToggleMinimapKeyboardInputHandler @Inject constructor( + private val mainConfig: MainConfig, +) : IGameInputHandler { + + override fun checkConditions(action: KeyboardInputAction): Boolean { + return action.actionKey is KeyboardInputActionKey.ShowMap && action.isKeyDown + } + + override fun handle(action: KeyboardInputAction) { + mainConfig.isShowMap = !mainConfig.isShowMap + } +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/TurnOnFlyModeKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/TurnOnFlyModeKeyboardInputHandler.kt new file mode 100644 index 0000000..6a73a9b --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/TurnOnFlyModeKeyboardInputHandler.kt @@ -0,0 +1,29 @@ +package ru.deadsoftware.cavedroid.game.input.handler.keyboard + +import ru.deadsoftware.cavedroid.MainConfig +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.mobs.Player +import javax.inject.Inject + +@GameScope +class TurnOnFlyModeKeyboardInputHandler @Inject constructor( + private val mainConfig: MainConfig, + private val mobsController: MobsController, +) : IGameInputHandler { + + override fun checkConditions(action: KeyboardInputAction): Boolean { + return mobsController.player.gameMode == 1 && action.actionKey is KeyboardInputActionKey.Jump && + !mobsController.player.isFlyMode && !mobsController.player.canJump() && action.isKeyDown && + (mobsController.player.controlMode == Player.ControlMode.WALK || !mainConfig.isTouch) + } + + override fun handle(action: KeyboardInputAction) { + mobsController.player.isFlyMode = true + mobsController.player.velocity.y = 0f + } + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/AttackMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/AttackMouseInputHandler.kt new file mode 100644 index 0000000..a0bfa4c --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/AttackMouseInputHandler.kt @@ -0,0 +1,35 @@ +package ru.deadsoftware.cavedroid.game.input.handler.mouse + +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.GameUiWindow +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey +import ru.deadsoftware.cavedroid.game.input.isInsideHotbar +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager +import ru.deadsoftware.cavedroid.game.world.GameWorld +import javax.inject.Inject + +@GameScope +class AttackMouseInputHandler @Inject constructor( + private val mobsController: MobsController, + private val gameWorld: GameWorld, + private val gameWindowsManager: GameWindowsManager +) : IGameInputHandler { + + override fun checkConditions(action: MouseInputAction): Boolean { + return gameWindowsManager.getCurrentWindow() == GameUiWindow.NONE && + !isInsideHotbar(action) && + action.actionKey is MouseInputActionKey.Left + + } + + override fun handle(action: MouseInputAction) { + if (action.actionKey.touchUp) { + mobsController.player.stopHitting() + } else { + mobsController.player.startHitting() + }; + } +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CloseGameWindowMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CloseGameWindowMouseInputHandler.kt new file mode 100644 index 0000000..2929c42 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CloseGameWindowMouseInputHandler.kt @@ -0,0 +1,41 @@ +package ru.deadsoftware.cavedroid.game.input.handler.mouse + +import com.badlogic.gdx.graphics.g2d.TextureRegion +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.GameUiWindow +import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey +import ru.deadsoftware.cavedroid.game.input.isInsideWindow +import ru.deadsoftware.cavedroid.misc.Assets +import javax.inject.Inject + +@GameScope +class CloseGameWindowMouseInputHandler @Inject constructor( + private val gameWindowsManager: GameWindowsManager, +) : IGameInputHandler { + + private val creativeInventoryTexture get() = requireNotNull(Assets.textureRegions["creative"]) + private val survivalInventoryTexture get() = requireNotNull(Assets.textureRegions["survival"]) + + override fun checkConditions(action: MouseInputAction): Boolean { + return gameWindowsManager.getCurrentWindow() != GameUiWindow.NONE && + action.actionKey is MouseInputActionKey.Left && + !action.actionKey.touchUp && + !isInsideWindow(action, getCurrentWindowTexture()) + } + + private fun getCurrentWindowTexture(): TextureRegion { + return when (val window = gameWindowsManager.getCurrentWindow()) { + GameUiWindow.CREATIVE_INVENTORY -> creativeInventoryTexture + GameUiWindow.SURVIVAL_INVENTORY -> survivalInventoryTexture + else -> throw UnsupportedOperationException("Cant close window ${window.name}") + } + } + + override fun handle(action: MouseInputAction) { + gameWindowsManager.closeWindow() + } + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CreativeInventoryScrollMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CreativeInventoryScrollMouseInputHandler.kt new file mode 100644 index 0000000..52e9f62 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CreativeInventoryScrollMouseInputHandler.kt @@ -0,0 +1,86 @@ +package ru.deadsoftware.cavedroid.game.input.handler.mouse + +import com.badlogic.gdx.math.MathUtils +import ru.deadsoftware.cavedroid.game.GameItemsHolder +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.GameUiWindow +import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey +import ru.deadsoftware.cavedroid.game.input.isInsideWindow +import ru.deadsoftware.cavedroid.misc.Assets +import javax.inject.Inject +import kotlin.math.abs + +@GameScope +class CreativeInventoryScrollMouseInputHandler @Inject constructor( + private val gameWindowsManager: GameWindowsManager, + private val gameItemsHolder: GameItemsHolder, +) : IGameInputHandler { + + private val creativeInventoryTexture get() = requireNotNull(Assets.textureRegions["creative"]) + + private var dragStartY = 0f + + override fun checkConditions(action: MouseInputAction): Boolean { + return gameWindowsManager.getCurrentWindow() == GameUiWindow.CREATIVE_INVENTORY && + (gameWindowsManager.isDragging || isInsideWindow(action, creativeInventoryTexture)) && + (checkStartDragConditions(action) || checkEndDragConditions(action) || + checkDragConditions(action) || action.actionKey is MouseInputActionKey.Scroll) + + } + + private fun checkStartDragConditions(action: MouseInputAction): Boolean { + return action.actionKey is MouseInputActionKey.Left && + !action.actionKey.touchUp && !gameWindowsManager.isDragging + } + + private fun checkEndDragConditions(action: MouseInputAction): Boolean { + return action.actionKey is MouseInputActionKey.Left && + action.actionKey.touchUp && gameWindowsManager.isDragging + } + + private fun checkDragConditions(action: MouseInputAction): Boolean { + return action.actionKey is MouseInputActionKey.Dragged && + abs(action.screenY - dragStartY) >= DRAG_SENSITIVITY + } + + private fun clampScrollAmount() { + gameWindowsManager.creativeScrollAmount = + MathUtils.clamp(gameWindowsManager.creativeScrollAmount, 0, gameItemsHolder.getMaxCreativeScrollAmount()) + } + + private fun handleStartOrEndDrag(action: MouseInputAction) { + if (gameWindowsManager.isDragging) { + gameWindowsManager.isDragging = false + } else { + dragStartY = action.screenY + } + } + + private fun handleDrag(action: MouseInputAction) { + gameWindowsManager.isDragging = true + gameWindowsManager.creativeScrollAmount += ((dragStartY - action.screenY) / DRAG_SENSITIVITY).toInt() + clampScrollAmount() + dragStartY = action.screenY + } + + private fun handleScroll(action: MouseInputAction) { + gameWindowsManager.creativeScrollAmount += (action.actionKey as MouseInputActionKey.Scroll).amountY.toInt() + clampScrollAmount() + } + + override fun handle(action: MouseInputAction) { + when (action.actionKey) { + is MouseInputActionKey.Left -> handleStartOrEndDrag(action) + is MouseInputActionKey.Dragged -> handleDrag(action) + is MouseInputActionKey.Scroll -> handleScroll(action) + else -> return + } + } + + companion object { + private const val DRAG_SENSITIVITY = 16f + } +} \ No newline at end of file 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 new file mode 100644 index 0000000..54aacf2 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CursorMouseInputHandler.kt @@ -0,0 +1,120 @@ +package ru.deadsoftware.cavedroid.game.input.handler.mouse + +import com.badlogic.gdx.math.MathUtils +import ru.deadsoftware.cavedroid.MainConfig +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey +import ru.deadsoftware.cavedroid.game.mobs.Mob +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.mobs.Player +import ru.deadsoftware.cavedroid.game.model.block.Block +import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.utils.bl +import ru.deadsoftware.cavedroid.misc.utils.px +import javax.inject.Inject + +@GameScope +class CursorMouseInputHandler @Inject constructor( + private val mainConfig: MainConfig, + private val mobsController: MobsController, + private val gameWorld: GameWorld, +) : IGameInputHandler { + + private val player get() = mobsController.player + + private val Block.isAutoselectable + get() = !isNone() && params.hasCollision + + private fun GameWorld.isCurrentBlockAutoselectable() = + getForeMap(player.cursorX, player.cursorY).isAutoselectable + + private fun checkCursorBounds() { + if (player.gameMode == 0) { + val minCursorX = player.mapX - SURVIVAL_CURSOR_RANGE + val maxCursorX = player.mapX + SURVIVAL_CURSOR_RANGE + val minCursorY = player.middleMapY - SURVIVAL_CURSOR_RANGE + val maxCursorY = player.middleMapY + SURVIVAL_CURSOR_RANGE + + player.cursorX = MathUtils.clamp(player.cursorX, minCursorX, maxCursorX) + player.cursorY = MathUtils.clamp(player.cursorY, minCursorY, maxCursorY) + } + + player.cursorY = MathUtils.clamp(player.cursorY, 0, gameWorld.height - 1) + } + + private fun setPlayerDirectionToCursor() { + if (player.controlMode != Player.ControlMode.CURSOR) { + return + } + + if (player.cursorX.px + 8 < player.x + player.width / 2) { + player.setDir(Mob.Direction.LEFT) + } else { + player.setDir(Mob.Direction.RIGHT) + } + } + + private fun handleWalkTouch() { + player.cursorX = player.mapX + player.direction.basis + player.cursorY = player.upperMapY + + for (i in 1..2) { + if (gameWorld.isCurrentBlockAutoselectable()) { + break + } + player.cursorY++ + } + + if (!gameWorld.isCurrentBlockAutoselectable()) { + player.cursorX -= player.direction.basis + } + } + + private fun getPlayerHeadRotation(mouseWorldX: Float, mouseWorldY: Float): Float { + val h = mouseWorldX - player.x + val v = mouseWorldY - player.y + + return MathUtils.atan(v / h) * MathUtils.radDeg + } + + private fun handleMouse(action: MouseInputAction) { + val worldX = action.screenX + action.cameraViewport.x + val worldY = action.screenY + action.cameraViewport.y + + // when worldX < 0, need to subtract 1 to avoid negative zero +// val fixCycledWorld = if (worldX < 0) 1 else 0 + + player.cursorX = worldX.bl - 0 + player.cursorY = worldY.bl + + player.headRotation = getPlayerHeadRotation(worldX, worldY) + } + + override fun checkConditions(action: MouseInputAction): Boolean { + return action.actionKey is MouseInputActionKey.None + } + + override fun handle(action: MouseInputAction) { + val pastCursorX = player.cursorX + val pastCursorY = player.cursorY + + when { + player.controlMode == Player.ControlMode.WALK && mainConfig.isTouch -> handleWalkTouch() + !mainConfig.isTouch -> handleMouse(action) + } + + checkCursorBounds() + setPlayerDirectionToCursor() + + if (player.cursorX != pastCursorX || player.cursorY != pastCursorY) { + player.blockDamage = 0f + } + } + + companion object { + private const val SURVIVAL_CURSOR_RANGE = 4 + } + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt new file mode 100644 index 0000000..3c2a163 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt @@ -0,0 +1,95 @@ +package ru.deadsoftware.cavedroid.game.input.handler.mouse + +import com.badlogic.gdx.utils.Timer +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.GameUiWindow +import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey +import ru.deadsoftware.cavedroid.game.input.isInsideHotbar +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.misc.Assets +import javax.inject.Inject + +@GameScope +class HotbarMouseInputHandler @Inject constructor( + private val gameWindowsManager: GameWindowsManager, + private val mobsController: MobsController, +) : IGameInputHandler { + + private val hotbarTexture get() = requireNotNull(Assets.textureRegions["hotbar"]) + + private var buttonHoldTask: Timer.Task? = null + + override fun checkConditions(action: MouseInputAction): Boolean { + return buttonHoldTask?.isScheduled == true || + (action.actionKey is MouseInputActionKey.Left && isInsideHotbar(action) || action.actionKey is MouseInputActionKey.Scroll) && + gameWindowsManager.getCurrentWindow() == GameUiWindow.NONE + } + + private fun cancelHold() { + buttonHoldTask?.cancel() + buttonHoldTask = null + } + + private fun handleHold() { + buttonHoldTask = null + gameWindowsManager.openInventory() + } + + private fun handleDown(action: MouseInputAction) { + buttonHoldTask = object : Timer.Task() { + override fun run() { + handleHold() + } + } + + Timer.schedule(buttonHoldTask, TOUCH_HOLD_TIME_SEC) + } + + private fun handleUp(action: MouseInputAction) { + mobsController.player.slot = + ((action.screenX - + (action.cameraViewport.width / 2 - hotbarTexture.regionWidth / 2)) + / HOTBAR_CELL_WIDTH).toInt() + } + + private fun handleScroll(action: MouseInputAction) { + if (action.actionKey !is MouseInputActionKey.Scroll) { + return + } + mobsController.player.slot += action.actionKey.amountY.toInt() + if (mobsController.player.slot < 0) { + mobsController.player.slot = HOTBAR_ITEMS - 1 + } else if (mobsController.player.slot >= HOTBAR_ITEMS){ + mobsController.player.slot = 0 + } + } + + override fun handle(action: MouseInputAction) { + if (buttonHoldTask != null && buttonHoldTask?.isScheduled == true) { + cancelHold() + } + + if (action.actionKey !is MouseInputActionKey.Left) { + if (action.actionKey is MouseInputActionKey.Scroll) { + handleScroll(action) + } + return + } + + if (action.actionKey.touchUp) { + handleUp(action) + } else { + handleDown(action) + } + } + + companion object { + private const val TOUCH_HOLD_TIME_SEC = 0.5f + private const val HOTBAR_CELL_WIDTH = 20 + private const val HOTBAR_ITEMS = 9 + } + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCreativeInventoryItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCreativeInventoryItemMouseInputHandler.kt new file mode 100644 index 0000000..5e64027 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCreativeInventoryItemMouseInputHandler.kt @@ -0,0 +1,60 @@ +package ru.deadsoftware.cavedroid.game.input.handler.mouse + +import ru.deadsoftware.cavedroid.game.GameItemsHolder +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.GameUiWindow +import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey +import ru.deadsoftware.cavedroid.game.input.isInsideWindow +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.windows.GameWindowsConfigs +import ru.deadsoftware.cavedroid.misc.Assets +import javax.inject.Inject + +@GameScope +class SelectCreativeInventoryItemMouseInputHandler @Inject constructor( + private val gameItemsHolder: GameItemsHolder, + private val gameWindowsManager: GameWindowsManager, + private val mobsController: MobsController, +) : IGameInputHandler { + + private val creativeInventoryTexture get() = requireNotNull(Assets.textureRegions["creative"]) + + override fun checkConditions(action: MouseInputAction): Boolean { + return gameWindowsManager.getCurrentWindow() == GameUiWindow.CREATIVE_INVENTORY && + !gameWindowsManager.isDragging && + action.actionKey is MouseInputActionKey.Left && + action.actionKey.touchUp && isInsideWindow(action, creativeInventoryTexture) + } + + override fun handle(action: MouseInputAction) { + val creativeTexture = creativeInventoryTexture + val xOnGrid = (action.screenX - (action.cameraViewport.width / 2 - creativeTexture.regionWidth / 2 + + GameWindowsConfigs.Creative.itemsGridMarginLeft)) / + GameWindowsConfigs.Creative.itemsGridColWidth + val yOnGrid = (action.screenY - (action.cameraViewport.height / 2 - creativeTexture.regionHeight / 2 + + GameWindowsConfigs.Creative.itemsGridMarginTop)) / + GameWindowsConfigs.Creative.itemsGridRowHeight + + if (xOnGrid < 0 || xOnGrid >= GameWindowsConfigs.Creative.itemsInRow || + yOnGrid < 0 || yOnGrid >= GameWindowsConfigs.Creative.itemsInCol) { + return + } + + val itemIndex = (gameWindowsManager.creativeScrollAmount * GameWindowsConfigs.Creative.itemsInRow + + (xOnGrid.toInt() + yOnGrid.toInt() * GameWindowsConfigs.Creative.itemsInRow)) + + mobsController.player.inventory.copyInto( + destination = mobsController.player.inventory, + destinationOffset = 1, + startIndex = 0, + endIndex = mobsController.player.inventory.size - 2 + ) + + val item = gameItemsHolder.getItemFromCreativeInventory(itemIndex) + mobsController.player.inventory[0] = item.toInventoryItem(amount = item.params.maxStack) + } + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/UseItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/UseItemMouseInputHandler.kt new file mode 100644 index 0000000..e2d3f1d --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/UseItemMouseInputHandler.kt @@ -0,0 +1,109 @@ +package ru.deadsoftware.cavedroid.game.input.handler.mouse + +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.utils.Timer +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.GameUiWindow +import ru.deadsoftware.cavedroid.game.actions.placeToBackgroundAction +import ru.deadsoftware.cavedroid.game.actions.placeToForegroundAction +import ru.deadsoftware.cavedroid.game.actions.placeblock.IPlaceBlockAction +import ru.deadsoftware.cavedroid.game.actions.useitem.IUseItemAction +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey +import ru.deadsoftware.cavedroid.game.input.isInsideHotbar +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.model.item.Item +import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager +import javax.inject.Inject + +@GameScope +class UseItemMouseInputHandler @Inject constructor( + private val mobsController: MobsController, + private val useItemActionMap: Map, + private val placeBlockActionMap: Map, + private val gameWindowsManager: GameWindowsManager, +) : IGameInputHandler { + + private var buttonHoldTask: Timer.Task? = null + + override fun checkConditions(action: MouseInputAction): Boolean { + return buttonHoldTask?.isScheduled == true || + !isInsideHotbar(action) && + gameWindowsManager.getCurrentWindow() == GameUiWindow.NONE && + action.actionKey is MouseInputActionKey.Right + } + + private fun cancelHold() { + buttonHoldTask?.cancel() + buttonHoldTask = null + } + + private fun handleHold(action: MouseInputAction) { + cancelHold() + + val player = mobsController.player + val item = player.currentItem.item + player.startHitting(false) + player.stopHitting() + + if (item is Item.Placeable) { + placeBlockActionMap.placeToBackgroundAction( + item = player.currentItem.item as Item.Placeable, + x = player.cursorX, + y = player.cursorY + ) + } + } + + private fun handleDown(action: MouseInputAction) { + cancelHold() + buttonHoldTask = object : Timer.Task() { + override fun run() { + handleHold(action) + } + + } + Timer.schedule(buttonHoldTask, TOUCH_HOLD_TIME_SEC) + } + + private fun handleUp(action: MouseInputAction) { + val player = mobsController.player + val item = player.currentItem.item + cancelHold() + + player.startHitting(false) + player.stopHitting() + + if (item is Item.Placeable) { + placeBlockActionMap.placeToForegroundAction( + item = item, + x = player.cursorX, + y = player.cursorY + ) + } else if (item is Item.Usable) { + useItemActionMap[item.useActionKey]?.perform(item, player.cursorX, player.cursorY) + ?: Gdx.app.error(TAG, "use item action ${item.useActionKey} not found"); + } + } + + override fun handle(action: MouseInputAction) { + if (action.actionKey !is MouseInputActionKey.Right) { + if (buttonHoldTask?.isScheduled == true) { + cancelHold() + } + return + } + + if (action.actionKey.touchUp && buttonHoldTask?.isScheduled == true) { + handleUp(action) + } else if (!action.actionKey.touchUp) { + handleDown(action) + } + } + + companion object { + private const val TAG = "UseItemMouseInputActionHandler" + private const val TOUCH_HOLD_TIME_SEC = 0.5f + } +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/mapper/KeyboardInputActionMapper.kt b/core/src/ru/deadsoftware/cavedroid/game/input/mapper/KeyboardInputActionMapper.kt new file mode 100644 index 0000000..fefd4ad --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/mapper/KeyboardInputActionMapper.kt @@ -0,0 +1,34 @@ +package ru.deadsoftware.cavedroid.game.input.mapper + +import com.badlogic.gdx.Input +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey +import javax.inject.Inject + +@GameScope +class KeyboardInputActionMapper @Inject constructor() { + + fun map(key: Int, isKeyDown: Boolean): KeyboardInputAction? { + val actionKey = when (key) { + Input.Keys.A, Input.Keys.LEFT -> KeyboardInputActionKey.Left + Input.Keys.D, Input.Keys.RIGHT -> KeyboardInputActionKey.Right + Input.Keys.W, Input.Keys.SPACE -> KeyboardInputActionKey.Jump + Input.Keys.S -> KeyboardInputActionKey.Down + + Input.Keys.E -> KeyboardInputActionKey.OpenInventory + Input.Keys.ALT_LEFT -> KeyboardInputActionKey.SwitchControlsMode + + Input.Keys.ESCAPE, Input.Keys.BACK -> KeyboardInputActionKey.Pause + + Input.Keys.F1 -> KeyboardInputActionKey.ShowDebug + Input.Keys.GRAVE -> KeyboardInputActionKey.SwitchGameMode + Input.Keys.M -> KeyboardInputActionKey.ShowMap + + else -> null + } + + return actionKey?.let { KeyboardInputAction(it, isKeyDown) } + } + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/mapper/MouseInputActionMapper.kt b/core/src/ru/deadsoftware/cavedroid/game/input/mapper/MouseInputActionMapper.kt new file mode 100644 index 0000000..666154e --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/mapper/MouseInputActionMapper.kt @@ -0,0 +1,79 @@ +package ru.deadsoftware.cavedroid.game.input.mapper + +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.Input +import com.badlogic.gdx.math.Rectangle +import ru.deadsoftware.cavedroid.MainConfig +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey +import javax.inject.Inject + +@GameScope +class MouseInputActionMapper @Inject constructor( + val mainConfig: MainConfig, +) { + + fun map( + mouseX: Float, + mouseY: Float, + cameraViewport: Rectangle, + button: Int, + touchUp: Boolean + ): MouseInputAction? { + val actionKey = mapActionKey(button, touchUp) ?: return null + + return MouseInputAction( + screenX = getScreenX(mouseX), + screenY = getScreenY(mouseY), + actionKey = actionKey, + cameraViewport = cameraViewport, + ) + } + + fun mapDragged( + mouseX: Float, + mouseY: Float, + cameraViewport: Rectangle, + ): MouseInputAction { + return MouseInputAction( + screenX = getScreenX(mouseX), + screenY = getScreenY(mouseY), + actionKey = MouseInputActionKey.Dragged, + cameraViewport = cameraViewport, + ) + } + + fun mapScrolled( + mouseX: Float, + mouseY: Float, + amountX: Float, + amountY: Float, + cameraViewport: Rectangle, + ): MouseInputAction { + return MouseInputAction( + screenX = getScreenX(mouseX), + screenY = getScreenY(mouseY), + actionKey = MouseInputActionKey.Scroll(amountX, amountY), + cameraViewport = cameraViewport, + ) + } + + private fun mapActionKey(button: Int, touchUp: Boolean): MouseInputActionKey? { + return when (button) { + Input.Buttons.LEFT -> MouseInputActionKey.Left(touchUp) + Input.Buttons.RIGHT -> MouseInputActionKey.Right(touchUp) + Input.Buttons.MIDDLE -> MouseInputActionKey.Middle(touchUp) + else -> null + } + } + + private fun getScreenX(mouseX: Float): Float { + return mouseX * (mainConfig.width / Gdx.graphics.width) + } + + private fun getScreenY(mouseY: Float): Float { + return mouseY * (mainConfig.height / Gdx.graphics.height) + } + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/mobs/Player.java b/core/src/ru/deadsoftware/cavedroid/game/mobs/Player.java index a93141a..83f3257 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/mobs/Player.java +++ b/core/src/ru/deadsoftware/cavedroid/game/mobs/Player.java @@ -22,7 +22,7 @@ public class Player extends Mob { private static final float JUMP_VELOCITY = -133.332f; private static final int MAX_HEALTH = 20; - private boolean hitting = false; + private boolean hitting = false, hittingWithDamage = false; private float hitAnim = 0f; private float hitAnimDelta = ANIMATION_SPEED; @@ -36,6 +36,13 @@ public class Player extends Mob { public int cursorX = 0; public int cursorY = 0; + public ControlMode controlMode = ControlMode.WALK; + + public enum ControlMode { + WALK, + CURSOR + } + public Player(GameItemsHolder gameItemsHolder) { super(0, 0, 4, 30, randomDir(), Type.MOB, MAX_HEALTH); inventory = new InventoryItem[36]; @@ -134,9 +141,41 @@ public class Player extends Mob { mVelocity.y = JUMP_VELOCITY; } + private void hitBlock(GameWorld gameWorld, GameItemsHolder gameItemsHolder) { + if (!hitting || !hittingWithDamage) { + return; + } + + final Block foregroundBlock = gameWorld.getForeMap(cursorX, cursorY); + final Block backgroundBlock = gameWorld.getBackMap(cursorX, cursorY); + + if ((!foregroundBlock.isNone() && foregroundBlock.getParams().getHitPoints() >= 0) || + (foregroundBlock.isNone() && !backgroundBlock.isNone() && backgroundBlock.getParams().getHitPoints() >= 0)) { + if (gameMode == 0) { + if (!foregroundBlock.isNone() && blockDamage >= foregroundBlock.getParams().getHitPoints()) { + gameWorld.destroyForeMap(cursorX, cursorY); + blockDamage = 0; + } else if (!backgroundBlock.isNone() && blockDamage >= backgroundBlock.getParams().getHitPoints()) { + gameWorld.destroyBackMap(cursorX, cursorY); + blockDamage = 0; + } + } else { + if (!foregroundBlock.isNone()) { + gameWorld.placeToForeground(cursorX, cursorY, gameItemsHolder.getFallbackBlock()); + } else if (!backgroundBlock.isNone()) { + gameWorld.placeToBackground(cursorX, cursorY, gameItemsHolder.getFallbackBlock()); + } + stopHitting(); + } + } else { + stopHitting(); + } + } + @Override public void ai(GameWorld gameWorld, GameItemsHolder gameItemsHolder, float delta) { updateAnimation(delta); + hitBlock(gameWorld, gameItemsHolder); if (gameMode == 1) { return; @@ -166,7 +205,7 @@ public class Player extends Mob { multiplier *= ((Item.Tool)currentItem).getBlockDamageMultiplier(); } - if (hitting && canHitBlock) { + if (hitting && hittingWithDamage && canHitBlock) { blockDamage += 60f * delta * multiplier; } else { blockDamage = 0f; @@ -247,16 +286,21 @@ public class Player extends Mob { } } - public void startHitting() { + public void startHitting(boolean withDamage) { if (hitting) { return; } hitting = true; + hittingWithDamage = withDamage; hitAnim = 90f; hitAnimDelta = ANIMATION_SPEED; } + public void startHitting() { + startHitting(true); + } + public void stopHitting() { blockDamage = 0f; hitting = false; diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/HudRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/HudRenderer.kt index b631902..b3f8990 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/HudRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/HudRenderer.kt @@ -3,19 +3,16 @@ package ru.deadsoftware.cavedroid.game.render import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.glutils.ShapeRenderer import com.badlogic.gdx.math.Rectangle -import ru.deadsoftware.cavedroid.game.GameInput import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.mobs.MobsController -import ru.deadsoftware.cavedroid.game.model.item.InventoryItem +import ru.deadsoftware.cavedroid.game.mobs.Player.ControlMode import ru.deadsoftware.cavedroid.game.world.GameWorld import ru.deadsoftware.cavedroid.misc.Assets -import ru.deadsoftware.cavedroid.misc.ControlMode import ru.deadsoftware.cavedroid.misc.utils.px import javax.inject.Inject @GameScope class HudRenderer @Inject constructor( - private val gameInput: GameInput, private val gameWorld: GameWorld, private val mobsController: MobsController, ) : IGameRenderer { @@ -34,7 +31,7 @@ class HudRenderer @Inject constructor( if (gameWorld.hasForeAt(cursorX, cursorY) || gameWorld.hasBackAt(cursorX, cursorY) || - gameInput.controlMode == ControlMode.CURSOR + mobsController.player.controlMode == ControlMode.CURSOR ) { spriteBatch.draw(cursorTexture, cursorX.px - viewport.x, cursorY.px - viewport.y) } diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/TouchControlsRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/TouchControlsRenderer.kt index c9f2bcc..d9dc5c4 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/TouchControlsRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/TouchControlsRenderer.kt @@ -4,10 +4,10 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.glutils.ShapeRenderer import com.badlogic.gdx.math.Rectangle import ru.deadsoftware.cavedroid.MainConfig -import ru.deadsoftware.cavedroid.game.GameInput import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.mobs.Player.ControlMode import ru.deadsoftware.cavedroid.misc.Assets -import ru.deadsoftware.cavedroid.misc.ControlMode import ru.deadsoftware.cavedroid.misc.utils.ArrayMapExtensions.component1 import ru.deadsoftware.cavedroid.misc.utils.ArrayMapExtensions.component2 import javax.inject.Inject @@ -15,7 +15,7 @@ import javax.inject.Inject @GameScope class TouchControlsRenderer @Inject constructor( private val mainConfig: MainConfig, - private val gameInput: GameInput + private val mobsController: MobsController, ) : IGameRenderer { override val renderLayer get() = RENDER_LAYER @@ -41,7 +41,7 @@ class TouchControlsRenderer @Inject constructor( } // FIXME: Add pressed state for buttons - if (gameInput.controlMode == ControlMode.CURSOR) { + if (mobsController.player.controlMode == ControlMode.CURSOR) { val altKeyRect = touchControlsMap.get("alt").rect spriteBatch.draw(shadeTexture, altKeyRect.x, altKeyRect.y, altKeyRect.width, altKeyRect.height) } diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/windows/CreativeWindowRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/windows/CreativeWindowRenderer.kt index ef62996..4c43600 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/windows/CreativeWindowRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/windows/CreativeWindowRenderer.kt @@ -4,13 +4,13 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.glutils.ShapeRenderer import com.badlogic.gdx.math.Rectangle import ru.deadsoftware.cavedroid.MainConfig -import ru.deadsoftware.cavedroid.game.GameInput import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager import ru.deadsoftware.cavedroid.game.mobs.MobsController -import ru.deadsoftware.cavedroid.game.model.item.InventoryItem import ru.deadsoftware.cavedroid.game.render.IGameRenderer import ru.deadsoftware.cavedroid.game.render.WindowsRenderer +import ru.deadsoftware.cavedroid.game.windows.GameWindowsConfigs import ru.deadsoftware.cavedroid.misc.Assets import javax.inject.Inject import kotlin.math.min @@ -18,7 +18,7 @@ import kotlin.math.min @GameScope class CreativeWindowRenderer @Inject constructor( private val mainConfig: MainConfig, - private val gameInput: GameInput, + private val gameWindowsManager: GameWindowsManager, private val gameItemsHolder: GameItemsHolder, private val mobsController: MobsController, ) : AbstractWindowRenderer(), IGameRenderer { @@ -34,19 +34,19 @@ class CreativeWindowRenderer @Inject constructor( val windowX = viewport.width / 2 - creativeWindow.regionWidth / 2 val windowY = viewport.height / 2 - creativeWindow.regionHeight / 2 - val oneScrollAmount = CreativeWindowConfig.scrollIndicatorFullHeight / gameItemsHolder.getCreativeScrollAmount() + val oneScrollAmount = GameWindowsConfigs.Creative.scrollIndicatorFullHeight / gameItemsHolder.getMaxCreativeScrollAmount() spriteBatch.draw(creativeWindow, windowX, windowY) spriteBatch.draw( /* region = */ scrollIndicatorTexture, - /* x = */ windowX + CreativeWindowConfig.scrollIndicatorMarginLeft, - /* y = */ windowY + CreativeWindowConfig.scrollIndicatorMarginTop - + (gameInput.creativeScroll * oneScrollAmount) + /* x = */ windowX + GameWindowsConfigs.Creative.scrollIndicatorMarginLeft, + /* y = */ windowY + GameWindowsConfigs.Creative.scrollIndicatorMarginTop + + (gameWindowsManager.creativeScrollAmount * oneScrollAmount) ) val allItems = gameItemsHolder.getAllItems() - val startIndex = gameInput.creativeScroll * CreativeWindowConfig.itemsInRow - val endIndex = min(startIndex + CreativeWindowConfig.itemsOnPage, allItems.size) + val startIndex = gameWindowsManager.creativeScrollAmount * GameWindowsConfigs.Creative.itemsInRow + val endIndex = min(startIndex + GameWindowsConfigs.Creative.itemsOnPage, allItems.size) val items = sequence { for (i in startIndex.. cache) { if (cache.containsKey(textureName)) { return cache.get(textureName); @@ -155,6 +195,7 @@ public class Assets { loadJSON(assetLoader); loadBlocks(assetLoader); loadItems(assetLoader); + loadTouchButtonsFromJSON(assetLoader); setPlayerHeadOrigin(); minecraftFont = new BitmapFont(assetLoader.getAssetHandle("font.fnt"), true); minecraftFont.getData().setScale(.375f); diff --git a/core/src/ru/deadsoftware/cavedroid/misc/ControlMode.java b/core/src/ru/deadsoftware/cavedroid/misc/ControlMode.java deleted file mode 100644 index dab3ac3..0000000 --- a/core/src/ru/deadsoftware/cavedroid/misc/ControlMode.java +++ /dev/null @@ -1,6 +0,0 @@ -package ru.deadsoftware.cavedroid.misc; - -public enum ControlMode { - WALK, - CURSOR -} diff --git a/core/src/ru/deadsoftware/cavedroid/misc/utils/AssetLoader.kt b/core/src/ru/deadsoftware/cavedroid/misc/utils/AssetLoader.kt index 7fb5df1..dff4d90 100644 --- a/core/src/ru/deadsoftware/cavedroid/misc/utils/AssetLoader.kt +++ b/core/src/ru/deadsoftware/cavedroid/misc/utils/AssetLoader.kt @@ -24,4 +24,12 @@ class AssetLoader @Inject constructor( } } + fun getGameRendererWidth(): Float { + return mainConfig.width + } + + fun getGameRendererHeight(): Float { + return mainConfig.height + } + }