From 0ae1a6f6bc2f57daf00224dd4799f87ad5087283 Mon Sep 17 00:00:00 2001 From: Compl Yue Date: Sun, 28 Apr 2024 00:09:33 +0800 Subject: [PATCH] unified digital steering --- .../gameinput/DigitalSteering.java | 65 +++++++++++++++++++ .../gameinput/InputMapperInputHandler.java | 15 ++--- .../gameinput/PieTouchInputHandler.java | 4 +- .../gameinput/SidesTouchInputHandler.java | 7 +- .../gameinput/TouchInputUtils.java | 36 ---------- 5 files changed, 74 insertions(+), 53 deletions(-) create mode 100644 core/src/com/agateau/pixelwheels/gameinput/DigitalSteering.java delete mode 100644 core/src/com/agateau/pixelwheels/gameinput/TouchInputUtils.java diff --git a/core/src/com/agateau/pixelwheels/gameinput/DigitalSteering.java b/core/src/com/agateau/pixelwheels/gameinput/DigitalSteering.java new file mode 100644 index 000000000..f44e2802e --- /dev/null +++ b/core/src/com/agateau/pixelwheels/gameinput/DigitalSteering.java @@ -0,0 +1,65 @@ +/* + * Copyright 2024 Compl Yue + * + * This file is part of Pixel Wheels. + * + * Pixel Wheels is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ +package com.agateau.pixelwheels.gameinput; + +import com.agateau.pixelwheels.GamePlay; +import com.badlogic.gdx.math.MathUtils; + +public class DigitalSteering { + + private float mRawDirection = 0; + + public float direction() { + // use parabolic curve to smooth the ctrl + return mRawDirection * mRawDirection * Math.signum(mRawDirection); + } + + public float steer(boolean left, boolean right) { + if (left && right) { + // both left and right, full steer in original direction. + // currently there are 2 folds to do it this way: + // + // * with two-sides button control, I seldom purposfully do a + // straight braking/slow-down, almost always meant to reverse at + // a direction, then I always press the other button too quickly + // after pressed the 1st button, making it reverse almost + // straightly, the treatment here meant to make that op easy. + // also there are times I'd mean slow-down & turn-hard, this case + // works pretty well like a trick - just release the other button + // after the speed is sufficiently slowed down, and keep holding + // the 1st button to keep hard turning toward the original direction + // using full steering during the whole course. + // + // * for kbd control (maybe also pie-touch), this happens to enable + // a hard-turning trick - the player first press the button for the + // target direction, immediately followed by a press on the other + // button, it'll skip the gradually increasing steering output, and + // do an instant, full steering. + mRawDirection = Math.signum(mRawDirection); + } else if (left) { + mRawDirection += GamePlay.instance.steeringStep; + } else if (right) { + mRawDirection -= GamePlay.instance.steeringStep; + } else { + mRawDirection *= 0.4; + } + mRawDirection = MathUtils.clamp(mRawDirection, -1, 1); + return this.direction(); + } +} diff --git a/core/src/com/agateau/pixelwheels/gameinput/InputMapperInputHandler.java b/core/src/com/agateau/pixelwheels/gameinput/InputMapperInputHandler.java index 9d848095a..8febd45d7 100644 --- a/core/src/com/agateau/pixelwheels/gameinput/InputMapperInputHandler.java +++ b/core/src/com/agateau/pixelwheels/gameinput/InputMapperInputHandler.java @@ -19,18 +19,17 @@ package com.agateau.pixelwheels.gameinput; import com.agateau.pixelwheels.Assets; -import com.agateau.pixelwheels.GamePlay; import com.agateau.pixelwheels.bonus.Bonus; import com.agateau.pixelwheels.racescreen.Hud; import com.agateau.ui.InputMapper; import com.agateau.ui.VirtualKey; import com.badlogic.gdx.Preferences; -import com.badlogic.gdx.math.MathUtils; /** Base class for InputMapper-based GameInputHandlers */ public abstract class InputMapperInputHandler implements GameInputHandler { private final InputMapper mInputMapper; private final GameInput mInput = new GameInput(); + private final DigitalSteering mSteer = new DigitalSteering(); InputMapperInputHandler(InputMapper inputMapper) { mInputMapper = inputMapper; @@ -42,14 +41,10 @@ public GameInput getGameInput() { mInputMapper.isKeyPressed(VirtualKey.DOWN) || mInputMapper.isKeyPressed(VirtualKey.BACK); mInput.accelerating = !mInput.braking; - if (mInputMapper.isKeyPressed(VirtualKey.LEFT)) { - mInput.direction += GamePlay.instance.steeringStep; - } else if (mInputMapper.isKeyPressed(VirtualKey.RIGHT)) { - mInput.direction -= GamePlay.instance.steeringStep; - } else { - mInput.direction *= 0.4; - } - mInput.direction = MathUtils.clamp(mInput.direction, -1, 1); + mInput.direction = + mSteer.steer( + mInputMapper.isKeyPressed(VirtualKey.LEFT), + mInputMapper.isKeyPressed(VirtualKey.RIGHT)); mInput.triggeringBonus = mInputMapper.isKeyPressed(VirtualKey.TRIGGER); return mInput; diff --git a/core/src/com/agateau/pixelwheels/gameinput/PieTouchInputHandler.java b/core/src/com/agateau/pixelwheels/gameinput/PieTouchInputHandler.java index 6392ad796..fd7917ae7 100644 --- a/core/src/com/agateau/pixelwheels/gameinput/PieTouchInputHandler.java +++ b/core/src/com/agateau/pixelwheels/gameinput/PieTouchInputHandler.java @@ -32,6 +32,7 @@ /** Handle input using pie buttons in the bottom left and right corners */ public class PieTouchInputHandler implements GameInputHandler { private final GameInput mInput = new GameInput(); + private final DigitalSteering mSteer = new DigitalSteering(); private PieButton mLeftButton, mRightButton, mBrakeButton, mBonusButton; public static class Factory implements GameInputHandlerFactory { @@ -61,8 +62,7 @@ public Array getAllHandlers() { public GameInput getGameInput() { mInput.braking = mBrakeButton.isPressed(); mInput.accelerating = !mInput.braking; - mInput.direction = - TouchInputUtils.applyDirectionInput(mLeftButton, mRightButton, mInput.direction); + mInput.direction = mSteer.steer(mLeftButton.isPressed(), mRightButton.isPressed()); mInput.triggeringBonus = mBonusButton.isPressed(); return mInput; } diff --git a/core/src/com/agateau/pixelwheels/gameinput/SidesTouchInputHandler.java b/core/src/com/agateau/pixelwheels/gameinput/SidesTouchInputHandler.java index 8c0ddc4ff..c89ed0393 100644 --- a/core/src/com/agateau/pixelwheels/gameinput/SidesTouchInputHandler.java +++ b/core/src/com/agateau/pixelwheels/gameinput/SidesTouchInputHandler.java @@ -32,6 +32,7 @@ /** Handle input using buttons on the sides */ public class SidesTouchInputHandler implements GameInputHandler { private final GameInput mInput = new GameInput(); + private final DigitalSteering mSteer = new DigitalSteering(); private HudButton mLeftButton, mRightButton, mBonusButton; public static class Factory implements GameInputHandlerFactory { @@ -61,11 +62,7 @@ public Array getAllHandlers() { public GameInput getGameInput() { mInput.braking = isBraking(); mInput.accelerating = !mInput.braking; - if (!mInput.braking) { - mInput.direction = - TouchInputUtils.applyDirectionInput( - mLeftButton, mRightButton, mInput.direction); - } + mInput.direction = mSteer.steer(mLeftButton.isPressed(), mRightButton.isPressed()); mInput.triggeringBonus = mBonusButton.isPressed(); return mInput; } diff --git a/core/src/com/agateau/pixelwheels/gameinput/TouchInputUtils.java b/core/src/com/agateau/pixelwheels/gameinput/TouchInputUtils.java deleted file mode 100644 index 0342ec769..000000000 --- a/core/src/com/agateau/pixelwheels/gameinput/TouchInputUtils.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2019 Aurélien Gâteau - * - * This file is part of Pixel Wheels. - * - * Pixel Wheels is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ -package com.agateau.pixelwheels.gameinput; - -import com.agateau.pixelwheels.GamePlay; -import com.agateau.pixelwheels.racescreen.HudButton; -import com.badlogic.gdx.math.MathUtils; - -class TouchInputUtils { - static float applyDirectionInput(HudButton leftButton, HudButton rightButton, float direction) { - if (leftButton.isPressed()) { - direction += GamePlay.instance.steeringStep; - } else if (rightButton.isPressed()) { - direction -= GamePlay.instance.steeringStep; - } else { - direction = 0; - } - return MathUtils.clamp(direction, -1, 1); - } -}