Rework drifting

This commit is contained in:
Miloslav Ciz 2025-04-16 22:31:56 +02:00
parent 74bd36c893
commit 51bc7ada30
3 changed files with 41 additions and 33 deletions

View file

@ -1,7 +1,8 @@
=========== GENERAL ==============
- Create a physics test map.
- Unstuck idea: make the body non-rotating for a while?
- keyboard ghosting is an issue, particularly when initiating drift with brake
(arrow keys must be used with S for braking for left drift to work) -- think
about what to do about this? or leave as is?
- Map4: fix top bottom corner, making the curve is too hard -- either add ramps
on wall or shift the down ramp further.
- Try doing the bouncy car body? Just keep a point and its velocity, change
@ -18,13 +19,10 @@
data file, try to somehow hack around it (maybe just convert it to an array in
the end?) Maybe this: make a standalone C file with the string in it that
when compiled and run outputs the array.
- car deglitch idea: deglitch only if the middle joint collided this frame?
- some kinda easteregg in menu or smt
- culling is very slow now, it showed that distance bailout can accelerate it
a lot, try to make a more accurate bailaout and see if it's faster (watch
out for bugs due to false positives)
- improve the car unstucking? maybe we can just keep the position of the car
and ONE wheel (other joint positions can be computed)
- maps to make:
- there should be these maps:
- compiled in:
@ -36,7 +34,7 @@
- map types:
- purely falling map DONE
- traveling salesman kind of maze, with fans n shit KINDA DONE
- city map?
- city map? DONE
- some kinda buggy bumpy downhill DONE
- map where car starts upside down DONE
- dirt map DONE
@ -47,8 +45,8 @@
- falling tube map? DONE
- grass hills as decoration? DONE
- something with multiple roads DONE
- RPG kinda map? could be in bonus maps
- some speed map (mostly flat to prevent high speed bugs)
- RPG kinda map? could be in bonus maps KINDA DONE
- some speed map (mostly flat to prevent high speed bugs) DONE
- some (at least partially) interior map KINDA DONE
- something with multiple finishes DONE
- U-ramp to build speed and jump up to catch a CP (done) DONE
@ -84,9 +82,12 @@
=========== HANDLED ==============
- MAP4: one triangle in top section is missing!
- Unstuck idea: make the body non-rotating for a while?
- Create a physics test map.
- Antibug: maybe always simulate the step with non-rotating body AND normal one
as well -- if the car ends up bugged, use the non-rotating result?
- Fix weird reversing.
- car deglitch idea: deglitch only if the middle joint collided this frame?
- CP gets often missed, would be cool to increase its radius, but also hard.
We would have to be checking 8 cells instead of one, but even then issues
would appear with multiple CPs next to each other (returned CP_TAKEN event).
@ -111,6 +112,8 @@
to be drawn? could optimize rendering and map loading a lot <-- PROLLY NOT
- on 1st map the camera is obscured by the wall at the start, fix it somehow
(not the best first impression) <-- shifted start pos.
- improve the car unstucking? maybe we can just keep the position of the car
and ONE wheel (other joint positions can be computed)
- replay format should probably record game version
- also there should probably be some version system that says version of
physics vs version of everything else; replay could only record physics

View file

@ -36,7 +36,7 @@
physics version.
*/
typedef int32_t LCR_GameUnit; ///< abstract game unit
typedef int32_t LCR_GameUnit; ///< abstract game unit
#define LCR_RACING_VERSION1 '0' ///< first part of physics eng. version
#define LCR_RACING_VERSION2 '0' ///< second part of physics eng. version
@ -84,9 +84,6 @@ typedef int32_t LCR_GameUnit; ///< abstract game unit
#define LCR_CAR_WHEEL_AIR_ROTATION_SPEED (LCR_GAME_UNIT / 32)
#define LCR_CAR_WHEEL_GROUND_SPEED_DIV 8
#define LCR_CAR_DRIFT_THRESHOLD_1 (LCR_GAME_UNIT / 4)
#define LCR_CAR_DRIFT_THRESHOLD_0 (LCR_GAME_UNIT / 200)
#define LCR_CAR_CRASH_SPEED_SMALL 400
#define LCR_CAR_CRASH_SPEED_BIG 800
@ -94,8 +91,13 @@ typedef int32_t LCR_GameUnit; ///< abstract game unit
#define LCR_CAR_GRASS_FACTOR 5
#define LCR_CAR_DIRT_FACTOR 3
#define LCR_CAR_ICE_FACTOR 1
//#define LCR_CAR_DRIFT_FACTOR 2 ///< only affects steering friction
#define LCR_CAR_DRIFT_FACTOR 2 ///< only affects steering friction
#define LCR_CAR_DRIFT_THRESHOLD_1 (LCR_GAME_UNIT / 10)
#define LCR_CAR_DRIFT_THRESHOLD_0 (LCR_GAME_UNIT / 227)
#define LCR_CAR_JOINTS 5
#define LCR_CAR_CONNECTIONS 10
@ -1122,7 +1124,7 @@ int _LCR_racingCarShapeOK(void)
LCR_racing.carBody.connections[i].joint1].position,
LCR_racing.carBody.joints[
LCR_racing.carBody.connections[i].joint2].position),
LCR_racing.carBody.connections[i].length) < TPE_F / 16; // TODO: const
LCR_racing.carBody.connections[i].length) < TPE_F / 16; // 16: magic con.
return r;
}
@ -1140,6 +1142,7 @@ uint32_t LCR_racingStep(unsigned int input)
uint8_t groundMat = LCR_BLOCK_MATERIAL_CONCRETE; // material under wheels
uint8_t onAccel = 0; // standing on accelerator?
int groundBlockIndex = -1;
TPE_Unit driftFriction = 0; // average wheel friction (absolute value)
if (LCR_racing.playingReplay)
{
@ -1182,7 +1185,7 @@ uint32_t LCR_racingStep(unsigned int input)
LCR_racing.carBody.joints[4].velocity[2]);
/* Apply gravity like this: if all wheels are on ground, we don't apply
gravity to roof. This helps prevent sliding. */
gravity to roof. This helps prevent sliding when standing still. */
for (int i = 0; i < 5; ++i)
if (i < 4 || (((LCR_racing.wheelCollisions |
@ -1247,8 +1250,8 @@ uint32_t LCR_racingStep(unsigned int input)
if(!(input & (LCR_RACING_INPUT_FORW | LCR_RACING_INPUT_BACK)))
LCR_racing.carBody.friction *= LCR_CAR_STAND_FRICTION_MULTIPLIER;
else if (
((input & LCR_RACING_INPUT_FORW) && (LCR_racing.carSpeeds[0] < 0)) ||
((input & LCR_RACING_INPUT_BACK) && (LCR_racing.carSpeeds[0] > 0)))
((input & LCR_RACING_INPUT_FORW) && (LCR_racing.carSpeeds[0] < 0)) ||
((input & LCR_RACING_INPUT_BACK) && (LCR_racing.carSpeeds[0] > 0)))
LCR_racing.carBody.friction *= 2 * LCR_CAR_STAND_FRICTION_MULTIPLIER;
if (input)
@ -1316,8 +1319,6 @@ uint32_t LCR_racingStep(unsigned int input)
}
}
TPE_Unit driftFriction = 0; // average wheel friction (absolute value)
for (int i = 0; i < 4; ++i)
if (LCR_racing.wheelCollisions & (0x11 << i)) // wheel on ground?
{
@ -1359,19 +1360,6 @@ uint32_t LCR_racingStep(unsigned int input)
driftFriction /= 4; // divide by 4 wheels
if ((!LCR_racing.carDrifting) &&
driftFriction > LCR_CAR_DRIFT_THRESHOLD_1)
{
LCR_LOG2("drift start");
LCR_racing.carDrifting = 1;
}
else if (LCR_racing.carDrifting &&
driftFriction < LCR_CAR_DRIFT_THRESHOLD_0)
{
LCR_LOG2("drift end");
LCR_racing.carDrifting = 0;
}
if (steering &&
(input & (LCR_RACING_INPUT_FORW | LCR_RACING_INPUT_BACK)) &&
(LCR_racing.wheelCollisions & 0x33))
@ -1386,6 +1374,23 @@ uint32_t LCR_racingStep(unsigned int input)
}
}
if ((!LCR_racing.carDrifting) &&
driftFriction >
(LCR_CAR_DRIFT_THRESHOLD_1 >> (( // back key initiates drift easily
((input & (LCR_RACING_INPUT_FORW | LCR_RACING_INPUT_BACK))
== (LCR_RACING_INPUT_FORW | LCR_RACING_INPUT_BACK))) << 2)))
{
LCR_LOG1("drift start");
LCR_racing.carDrifting = 1;
}
else if (LCR_racing.carDrifting &&
(driftFriction < LCR_CAR_DRIFT_THRESHOLD_0 ||
LCR_racingGetCarSpeedUnsigned() < 5))
{
LCR_LOG1("drift end");
LCR_racing.carDrifting = 0;
}
if ((!(input & LCR_RACING_INPUT_LEFT)) &&
(!(input & LCR_RACING_INPUT_RIGHT)))
LCR_racing.wheelSteer /= 2;
@ -1437,7 +1442,7 @@ uint32_t LCR_racingStep(unsigned int input)
if ((LCR_racing.carBody.flags & TPE_BODY_FLAG_UNRESOLVED) ||
!_LCR_racingCarShapeOK()) // bad?
{
LCR_LOG1("car bad, simplifying physics");
LCR_LOG2("using simplified physics");
for (int i = 0; i < LCR_CAR_JOINTS; ++i) // use the first step positions
LCR_racing.carBody.joints[i] = joints[i];