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);
- }
-}