From 41e55aecc807b9d2a9073c4a9ecc1ddbf5569266 Mon Sep 17 00:00:00 2001 From: Compl Yue Date: Tue, 30 Apr 2024 05:32:23 +0800 Subject: [PATCH] catchup by maxspeed --- .../src/com/agateau/pixelwheels/GamePlay.java | 4 ++- .../agateau/pixelwheels/racer/Vehicle.java | 11 ++++++- .../com/agateau/pixelwheels/racer/Wheel.java | 5 ++-- .../pixelwheels/racescreen/GameWorldImpl.java | 30 ++++++++++++++++++- 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/core/src/com/agateau/pixelwheels/GamePlay.java b/core/src/com/agateau/pixelwheels/GamePlay.java index 025ac60a8..375e0c597 100644 --- a/core/src/com/agateau/pixelwheels/GamePlay.java +++ b/core/src/com/agateau/pixelwheels/GamePlay.java @@ -45,13 +45,15 @@ public class GamePlay { public int viewportWidth = 60; - public int turboStrength = 200; + public int turboStrength = 70; public float turboDuration = 0.5f; // When an AI is better ranked than a player, set its max speed to this percent of the best max // speed public float aiSpeedLimiter = 0.8f; + public float catchupFactor = 20; + public boolean oneLapOnly = false; public boolean freeCamera = false; diff --git a/core/src/com/agateau/pixelwheels/racer/Vehicle.java b/core/src/com/agateau/pixelwheels/racer/Vehicle.java index eb0fe2425..c2bfb0975 100644 --- a/core/src/com/agateau/pixelwheels/racer/Vehicle.java +++ b/core/src/com/agateau/pixelwheels/racer/Vehicle.java @@ -79,6 +79,7 @@ public static class WheelInfo { private boolean mStopped = false; private Material mMaterial = Material.ROAD; private float mSpeedLimiter = 1f; + private float mMaxSpeed = GamePlay.instance.maxSpeed; private boolean mFlying = false; private Probe mProbe = null; @@ -255,6 +256,14 @@ public void setSpeedLimiter(float speedLimiter) { mSpeedLimiter = speedLimiter; } + public float getMaxSpeed() { + return mMaxSpeed; + } + + public void setMaxSpeed(float maxSpeed) { + mMaxSpeed = maxSpeed; + } + /** Returns the angle the car is facing */ public float getAngle() { return AgcMathUtils.normalizeAngle(mBody.getAngle() * MathUtils.radiansToDegrees); @@ -381,7 +390,7 @@ private void applyPilotCommands() { float steerAngle = computeSteerAngle() * MathUtils.degRad; for (WheelInfo info : mWheels) { float angle = info.steeringFactor * steerAngle; - info.wheel.adjustSpeed(speedDelta); + info.wheel.adjustSpeed(speedDelta, mMaxSpeed); info.joint.setLimits(angle, angle); } } diff --git a/core/src/com/agateau/pixelwheels/racer/Wheel.java b/core/src/com/agateau/pixelwheels/racer/Wheel.java index f2eccca3f..4dc5274e2 100644 --- a/core/src/com/agateau/pixelwheels/racer/Wheel.java +++ b/core/src/com/agateau/pixelwheels/racer/Wheel.java @@ -183,14 +183,13 @@ public float getGroundSpeed() { return mMaterial.getSpeed(); } - public void adjustSpeed(float amount) { + public void adjustSpeed(float amount, float maxSpeed) { if (amount == 0) { return; } final float currentSpeed = mBody.getLinearVelocity().len() * Box2DUtils.MS_TO_KMH; - final float limit = - 1 - 0.2f * Interpolation.sineOut.apply(currentSpeed / GamePlay.instance.maxSpeed); + final float limit = 1 - 0.2f * Interpolation.sineOut.apply(currentSpeed / maxSpeed); amount *= limit; float force = mMaxDrivingForce * amount; diff --git a/core/src/com/agateau/pixelwheels/racescreen/GameWorldImpl.java b/core/src/com/agateau/pixelwheels/racescreen/GameWorldImpl.java index b4fdec76a..7bd28e8b8 100644 --- a/core/src/com/agateau/pixelwheels/racescreen/GameWorldImpl.java +++ b/core/src/com/agateau/pixelwheels/racescreen/GameWorldImpl.java @@ -20,6 +20,7 @@ import com.agateau.pixelwheels.Assets; import com.agateau.pixelwheels.Constants; +import com.agateau.pixelwheels.GamePlay; import com.agateau.pixelwheels.GameWorld; import com.agateau.pixelwheels.PwGame; import com.agateau.pixelwheels.bonus.Bonus; @@ -183,6 +184,34 @@ public GameStats getGameStats() { @Override public void act(float delta) { + // lower maxSpeed of racers ahead of another, propotional to the distance between them + final int distancePerLap = mTrack.getLapPositionTable().getSectionCount(); + final float catchupRatio = GamePlay.instance.catchupFactor / distancePerLap; + mRacers.sort(sRacerComparator); + Racer racerBehind = null; + for (int i = mRacers.size - 1; i >= 0; i--) { + final Racer racer = mRacers.get(i); + if (racer.getLapPositionComponent().hasFinishedRace()) { + break; + } + if (racerBehind == null) { + racer.getVehicle().setMaxSpeed(GamePlay.instance.maxSpeed); + } else { + final LapPositionComponent p1 = racer.getLapPositionComponent(); + final LapPositionComponent p2 = racerBehind.getLapPositionComponent(); + final float ddiff = + (p1.getLapCount() - p2.getLapCount()) * distancePerLap + + p1.getLapDistance() + - p2.getLapDistance(); + assert ddiff >= 0; + racer.getVehicle() + .setMaxSpeed( + racerBehind.getVehicle().getMaxSpeed() + / (1 + ddiff * catchupRatio)); + } + racerBehind = racer; + } + // fixed time step // max frame time to avoid spiral of death (on slow devices) float frameTime = Math.min(delta, 0.25f); @@ -214,7 +243,6 @@ public void act(float delta) { } if (haveAllRacersFinished()) { - mRacers.sort(sRacerComparator); setState(GameWorld.State.FINISHED); } }