From 51bc7ada3000b957efb9cfa0f601182c02ec80a4 Mon Sep 17 00:00:00 2001 From: Miloslav Ciz Date: Wed, 16 Apr 2025 22:31:56 +0200 Subject: [PATCH] Rework drifting --- TODO.txt | 19 +++++++++++-------- game.h | 2 +- racing.h | 53 +++++++++++++++++++++++++++++------------------------ 3 files changed, 41 insertions(+), 33 deletions(-) diff --git a/TODO.txt b/TODO.txt index 9e105e2..b95f88d 100644 --- a/TODO.txt +++ b/TODO.txt @@ -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 diff --git a/game.h b/game.h index 27f0162..e91cdea 100644 --- a/game.h +++ b/game.h @@ -1562,7 +1562,7 @@ uint8_t LCR_gameStep(uint32_t time) for (int i = 0; i < LCR_KEYS_TOTAL; ++i) LCR_game.keyStates[i] = LCR_keyPressed(i) ? (LCR_game.keyStates[i] < 255 ? LCR_game.keyStates[i] + 1 : 255) : 0; - + if (LCR_game.state == LCR_GAME_STATE_LOADING) { LCR_rendererLoadMap(); diff --git a/racing.h b/racing.h index 058ea1a..bf0580a 100644 --- a/racing.h +++ b/racing.h @@ -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];