From e09bed1bc3d325ef3de15405bbf8c1ff97da0331 Mon Sep 17 00:00:00 2001 From: bl0ckeduser Date: Wed, 30 May 2012 14:33:48 -0400 Subject: [PATCH] Simpler, less buggy edge-evasion system --- clown3d-DS.nds | Bin 288320 -> 286784 bytes collisions.c | 57 ++++++++++++++++++------------------------------- edge-evasion.c | 18 ++++++++++++++++ headers.h | 11 +++++----- main.c | 3 +++ oop.c | 13 +++++++++++ player.c | 20 ++++++++++++----- 7 files changed, 76 insertions(+), 46 deletions(-) create mode 100644 edge-evasion.c diff --git a/clown3d-DS.nds b/clown3d-DS.nds index 8aa7f227b4ed038fd99bf680c7ae92af84aecc40..baf45468a46cbb3b501e2e9307d35fd30e1a2ddb 100644 GIT binary patch delta 25707 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

2P2z>B&3&mP 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 diff --git a/collisions.c b/collisions.c index 6c28b14..bd1ea35 100644 --- a/collisions.c +++ b/collisions.c @@ -19,7 +19,6 @@ #include "headers.h" int which; -static int cf = 0; /* Compares using absolute values, equivalent to measuring the magnitude of a 1-dimensional @@ -116,7 +115,7 @@ float smallestOfThree(float a, float b, float c) \ /* in the case of a corner, wall-direction is ambiguous and must be \ inferred from player direction */ \ - if(which && !cc) \ + if(which) \ if(fabs(x_offs / node->box.move.x - z_offs / node->box.move.z) < 2.0) {\ if(fabs(move.x) > fabs(move.z)) { \ ratio = x_offs / node->box.move.x; which = 1; \ @@ -138,10 +137,6 @@ float smallestOfThree(float a, float b, float c) react.y = node->box.move.y * ratio; \ react.z = node->box.move.z * ratio; \ \ - if(node->type == PLAYER && \ - ratio == 0.0 && node->box.move.y == 0.0){ \ - glitch = 1; goto foundglitch; } \ - \ goto jump; \ } \ @@ -170,9 +165,7 @@ void resolveCollisions(game_obj* objs, void (*handler)(void*, void*)) vector move, react; float x_offs, y_offs, z_offs; float ratio; - int cc; - int glitch = 0; - int n; + int ee; /* * Objects marked as "stairs" have normal @@ -194,8 +187,8 @@ void resolveCollisions(game_obj* objs, void (*handler)(void*, void*)) for(node = objs; node != NULL; node = node->next) { if(node->type == SOLID) continue; /* heuristic: SOLIDs don't move ! */ - cc = 0; - glitch = 0; + + ee = 0; for(node2 = objs; node2 != NULL; node2 = node2->next) { if(node != node2 && node->type != NONE && node2->type != NONE) { @@ -292,16 +285,20 @@ void resolveCollisions(game_obj* objs, void (*handler)(void*, void*)) collision_found2: /* Simple edge-evasion, based on PypeBros' suggestion. - When a collision occurs,the projection of the player's - move vector on the "wall direction" (obtained here from - earlier collision calculations) is added for edge evasion. */ - if(node->type == PLAYER && which == 3 && !glitch && !cc) { - node->box.min.x += move.x * 0.4; - node->box.max.x += move.x * 0.4; + When a collision occurs, a request is made to add the + the projection of the player's move vector on the "wall direction" + (obtained here from earlier collision calculations). The + edge-evasion module will cancel all edge-evasion if a conflict + (edge-evasion in both wall-directions requested) is detected. + */ + + if(which == 3) { + edge_evade(node, node2, 0); + ee = 1; } - if(node->type == PLAYER && which == 1 && !glitch && !cc) { - node->box.min.z += move.z * 0.4; - node->box.max.z += move.z * 0.4; + if(which == 1) { + edge_evade(node, node2, 1); + ee = 1; } node->box.min.x += react.x; @@ -320,12 +317,10 @@ void resolveCollisions(game_obj* objs, void (*handler)(void*, void*)) } if(react.x || react.y || react.z) { - ++cc; (*handler)(node, node2); (*handler)(node2, node); } - foundglitch: /* * Restore the move vector as * it was prior to the Y axis / X, Z axes @@ -337,20 +332,10 @@ void resolveCollisions(game_obj* objs, void (*handler)(void*, void*)) } } - /* last resort for player collisions too complex for engine */ - if(node->type == PLAYER) { - player->data[PLAYER_GLITCHED] = 0; - if(glitch) { - player->data[PLAYER_GLITCHED] = 1; - player->data[PLAYER_X] -= player->data[PLAYER_GMX]; - player->data[PLAYER_Z] -= player->data[PLAYER_GMZ]; - cf = 0; - } else if(++cf >= 5 && (move.x || move.z)){ - player->data[PLAYER_GMX] = move.x; - player->data[PLAYER_GMZ] = move.z; - cf = 0; - } - } + /* If no edge-evasion requests occured in this collision + code frame, clear the edge-evasion data. (The edge-evasion + module is a state machine) */ + if(!ee) edge_evade(node, NULL, 0); } } diff --git a/edge-evasion.c b/edge-evasion.c new file mode 100644 index 0000000..cd7a23e --- /dev/null +++ b/edge-evasion.c @@ -0,0 +1,18 @@ + +#include "headers.h" + +void edge_evade(game_obj* who, game_obj* what, int dir) +{ + if(what) + who->ee_bits |= (2 << dir); + + if(!who->ee_targ) { + who->ee_targ = what; + who->ee_dir = dir; + } + + if(!what) { + who->ee_targ = NULL; + who->ee_bits = 0; + } +} diff --git a/headers.h b/headers.h index 2eb578d..86cf832 100644 --- a/headers.h +++ b/headers.h @@ -74,7 +74,9 @@ typedef struct game_obj vector coords; float rot; collisionBox box; - collisionBox last_good; + void* ee_targ; + int ee_dir; + int ee_bits; float* data; void* prev; void* next; @@ -99,10 +101,7 @@ enum PLAYER_MOVEY, PLAYER_MOVEZ, PLAYER_KEYS, - PLAYER_BULLET_TIMER, - PLAYER_GMX, - PLAYER_GMZ, - PLAYER_GLITCHED + PLAYER_BULLET_TIMER }; /* KEY */ @@ -263,6 +262,8 @@ extern void gc_push(game_obj* ptr); extern void gc_collect(void); extern void gc_stop(void); +extern void edge_evade(game_obj* who, game_obj* what, int dir); + #endif diff --git a/main.c b/main.c index acfcad4..198fc2b 100644 --- a/main.c +++ b/main.c @@ -266,6 +266,9 @@ void runGameFrame(void) resolveCollisions(objs, collisionFunction); + /* Edge-evasion */ + for(node = objs; node; node = node->next) + eeFunction(node); /* * Drawing code follows diff --git a/oop.c b/oop.c index a7c312d..6b012c4 100644 --- a/oop.c +++ b/oop.c @@ -95,3 +95,16 @@ void collisionFunction(void* va, void* vb) } } +void eeFunction(void* va) +{ + game_obj* a = va; + + if(a == NULL) return; + + switch(a->type){ + case PLAYER: + playerEdgeEvade(a); + break; + } +} + diff --git a/player.c b/player.c index 5de6636..0b45a9e 100644 --- a/player.c +++ b/player.c @@ -28,6 +28,8 @@ void playerInit(game_obj* a) a->data[PLAYER_DIRZ] = 0.0; a->data[PLAYER_KEYS] = 0; a->data[PLAYER_BULLET_TIMER] = 0.0f; + a->ee_targ = NULL; + a->ee_bits = 0; } void playerTick(game_obj* player) @@ -147,11 +149,9 @@ void playerTick(game_obj* player) player->data[PLAYER_ON_PLATFORM] = 0.0; - if(!player->data[PLAYER_GLITCHED]) { - player->data[PLAYER_X] += player->data[PLAYER_MOVEX]; - player->data[PLAYER_Y] += player->data[PLAYER_MOVEY]; - player->data[PLAYER_Z] += player->data[PLAYER_MOVEZ]; - } + player->data[PLAYER_X] += player->data[PLAYER_MOVEX]; + player->data[PLAYER_Y] += player->data[PLAYER_MOVEY]; + player->data[PLAYER_Z] += player->data[PLAYER_MOVEZ]; /* Player collision box and movement vector */ player->box.min.x = (float)(player->data[PLAYER_X] - 10); @@ -222,3 +222,13 @@ void playerDraw(game_obj* player) drawModelWithGL(turtleModel); } } + +void playerEdgeEvade(game_obj* player) +{ + if(player->ee_targ && player->ee_bits != 6) { + switch(player->ee_dir) { + case 0: player->data[PLAYER_X] += player->data[PLAYER_MOVEX]; break; + case 1: player->data[PLAYER_Z] += player->data[PLAYER_MOVEZ]; break; + } + } +}