Skip to content

Commit

Permalink
Simpler, less buggy edge-evasion system
Browse files Browse the repository at this point in the history
  • Loading branch information
bl0ckeduser committed May 30, 2012
1 parent b091657 commit e09bed1
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 46 deletions.
Binary file modified clown3d-DS.nds
Binary file not shown.
57 changes: 21 additions & 36 deletions collisions.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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; \
Expand All @@ -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; \
} \

Expand Down Expand Up @@ -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
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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);
}
}

Expand Down
18 changes: 18 additions & 0 deletions edge-evasion.c
Original file line number Diff line number Diff line change
@@ -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;
}
}
11 changes: 6 additions & 5 deletions headers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -99,10 +101,7 @@ enum
PLAYER_MOVEY,
PLAYER_MOVEZ,
PLAYER_KEYS,
PLAYER_BULLET_TIMER,
PLAYER_GMX,
PLAYER_GMZ,
PLAYER_GLITCHED
PLAYER_BULLET_TIMER
};

/* KEY */
Expand Down Expand Up @@ -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

Expand Down
3 changes: 3 additions & 0 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,9 @@ void runGameFrame(void)

resolveCollisions(objs, collisionFunction);

/* Edge-evasion */
for(node = objs; node; node = node->next)
eeFunction(node);

/*
* Drawing code follows
Expand Down
13 changes: 13 additions & 0 deletions oop.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

20 changes: 15 additions & 5 deletions player.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
}
}

0 comments on commit e09bed1

Please sign in to comment.