feat: add mini-turbo boost mechanic to drifting
- Track drift charge duration while sliding and payout a speed boost when the drift is released cleanly (not stalled or reversed) - Boost strength scales with drift duration, capped at maximum charge - Added configurable mini-turbo parameters (min/max ms, boost ms, boost multiplier range) to superkart-rules.json - Increase drift visual rotation angle from 6° to 14° for more pronounced drift feedback - Reset charge on respawn, spin, and new drift start
This commit is contained in:
parent
29d18c9c5f
commit
a0316bf467
|
|
@ -25,6 +25,11 @@
|
|||
"driftTurnMult": 1.6,
|
||||
"driftSlipRate": 240,
|
||||
"driftGripSpread": 170,
|
||||
"miniTurboMinMs": 500,
|
||||
"miniTurboMaxMs": 1800,
|
||||
"miniTurboBoostMs": 650,
|
||||
"miniTurboBoostMultMin": 1.1,
|
||||
"miniTurboBoostMultMax": 1.4,
|
||||
"slipDecay": 3.2,
|
||||
"hopMs": 260,
|
||||
"hopCooldownMs": 160,
|
||||
|
|
|
|||
|
|
@ -713,8 +713,7 @@ export default class SuperKartGame extends Phaser.Scene {
|
|||
if (kart.spinMs > 0) {
|
||||
frame = Math.floor((this.raceState.timeMs / 60)) % KART_ROT_FRAMES;
|
||||
} else if (kart.drifting) {
|
||||
frame = kart.driftDir > 0 ? 1 : KART_ROT_FRAMES - 1;
|
||||
angle = kart.driftDir * 6;
|
||||
angle = kart.driftDir * 14;
|
||||
} else if (inputs.steer !== 0 && hasLean) {
|
||||
frame = inputs.steer < 0 ? KART_ROT_FRAMES : KART_ROT_FRAMES + 1;
|
||||
} else if (inputs.steer !== 0) {
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ function makeKart(index, racer, isPlayer, slot, physics) {
|
|||
airborne: false,
|
||||
drifting: false,
|
||||
driftDir: 0,
|
||||
driftChargeMs: 0, // mini-turbo charge accrued while committed to the slide
|
||||
prevHop: false,
|
||||
prevItem: false,
|
||||
surface: SURFACE.ROAD,
|
||||
|
|
@ -201,6 +202,7 @@ function respawnAtCheckpoint(state, kart) {
|
|||
kart.velAngle = kart.heading;
|
||||
kart.speed = 0;
|
||||
kart.drifting = false;
|
||||
kart.driftChargeMs = 0;
|
||||
kart.airborne = false;
|
||||
kart.hopMs = 0;
|
||||
kart.offroadMs = 0;
|
||||
|
|
@ -214,6 +216,7 @@ function startSpin(state, kart, cause) {
|
|||
kart.spinMs = state.physics.spinMs;
|
||||
kart.spinSpin = 0;
|
||||
kart.drifting = false;
|
||||
kart.driftChargeMs = 0;
|
||||
const dropped = Math.min(kart.coins, state.physics.coinsLostOnHit);
|
||||
kart.coins -= dropped;
|
||||
emit(state, 'spin', { kart: kart.index, cause });
|
||||
|
|
@ -359,14 +362,30 @@ function stepKart(state, kart, inputs, dt) {
|
|||
if (inputs.hop && steer !== 0 && kart.speed > effTopSpeed(state, kart) * 0.3) {
|
||||
kart.drifting = true;
|
||||
kart.driftDir = Math.sign(steer);
|
||||
kart.driftChargeMs = 0;
|
||||
emit(state, 'drift-start', { kart: kart.index });
|
||||
}
|
||||
}
|
||||
}
|
||||
if (kart.drifting) {
|
||||
kart.driftChargeMs += STEP_MS;
|
||||
const top = effTopSpeed(state, kart);
|
||||
if (!inputs.hop || kart.speed < top * 0.25 || (steer !== 0 && Math.sign(steer) !== kart.driftDir)) {
|
||||
const speedDropped = kart.speed < top * 0.25;
|
||||
const steerReversed = steer !== 0 && Math.sign(steer) !== kart.driftDir;
|
||||
if (!inputs.hop || speedDropped || steerReversed) {
|
||||
kart.drifting = false;
|
||||
// Mini-turbo: only a clean release (hop let go, not a stall/reversal
|
||||
// cutting the slide short) with enough committed charge pays out —
|
||||
// stronger the longer the slide, capped at miniTurboMaxMs.
|
||||
if (!speedDropped && !steerReversed && kart.driftChargeMs >= physics.miniTurboMinMs) {
|
||||
const span = Math.max(1, physics.miniTurboMaxMs - physics.miniTurboMinMs);
|
||||
const t = Math.min(1, (kart.driftChargeMs - physics.miniTurboMinMs) / span);
|
||||
kart.boostMs = physics.miniTurboBoostMs;
|
||||
kart.boostMult = physics.miniTurboBoostMultMin
|
||||
+ (physics.miniTurboBoostMultMax - physics.miniTurboBoostMultMin) * t;
|
||||
emit(state, 'boost', { kart: kart.index, pad: false });
|
||||
}
|
||||
kart.driftChargeMs = 0;
|
||||
emit(state, 'drift-end', { kart: kart.index });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue