@ -1,8 +1,10 @@
@@ -1,8 +1,10 @@
# include "game.h"
player_st * glob_player ;
void set_motor_newtons ( Body * thing , int motorID , double x , double y ) ;
void set_motor_max_velocity ( Body * thing , int motorID , double max ) ;
void get_new_physics ( Body * * phys ) ;
// move the collision poly to the position of the player
void default_update_collision_poly ( Body * body ) {
@ -17,18 +19,53 @@ void default_update_collision_poly(Body *body) {
@@ -17,18 +19,53 @@ void default_update_collision_poly(Body *body) {
fflush ( stdout ) ;
}
// would probably be useful xd
enum collision_definition_type {
CIRCLE ,
LINE ,
CONVEX_POLY
} ;
void default_motor_curve ( Motor * motor ) {
// constant
return ;
}
FloorPoly * generate_floor_simple ( int num_polys ) {
FloorPoly * floor = calloc ( num_polys , sizeof ( FloorPoly ) ) ;
Vect last , next ;
last . x = 10 ;
last . y = 900 ;
for ( int i = 0 ; i < num_polys ; i + + ) {
double run = ( rand ( ) % 900 ) ;
double rise = ( rand ( ) % 100 ) - ( rand ( ) % 100 ) ;
next . x = last . x + run ;
next . y = last . y + rise ;
FloorPoly poly ;
poly . left = last ;
poly . right = next ;
get_new_physics ( & poly . physics ) ;
poly . physics - > position = last ;
poly . physics - > collision_poly_size = 4 ;
poly . physics - > collision_poly = calloc ( 4 , sizeof ( Vect ) ) ;
poly . physics - > collision_shape = calloc ( 4 , sizeof ( Vect ) ) ;
poly . physics - > collision_shape [ 0 ] . x = 0 ;
poly . physics - > collision_shape [ 0 ] . y = 0 ;
poly . physics - > collision_shape [ 1 ] . x = run ;
poly . physics - > collision_shape [ 1 ] . y = rise ;
poly . physics - > collision_shape [ 2 ] . x = run ;
poly . physics - > collision_shape [ 2 ] . y = rise + 200 ;
poly . physics - > collision_shape [ 3 ] . x = 0 ;
poly . physics - > collision_shape [ 3 ] . y = rise + 200 ;
last = next ;
floor [ i ] = poly ;
}
return floor ;
}
// @param uninitialised Body pointer
// @result: malloc and configure a physics thing pointer
void get_new_physics ( Body * * phys ) {
@ -55,7 +92,8 @@ void get_new_physics(Body **phys) {
@@ -55,7 +92,8 @@ void get_new_physics(Body **phys) {
add_motor ( physics , 0.0 , 0.0 ) ;
physics - > updateCollisionPoly = default_update_collision_poly ;
* phys = physics ; return ;
* phys = physics ;
return ;
}
/*void updatePlayerCollision(Body *physics) {*/
@ -82,18 +120,19 @@ player_st get_player(int x, int y) {
@@ -82,18 +120,19 @@ player_st get_player(int x, int y) {
player . physics - > glob_friction = 40 ; // drag coef * area
// collisions
player . physics - > collision_poly = calloc ( 4 , sizeof ( SDL_Point ) ) ;
player . physics - > collision_shape = calloc ( 4 , sizeof ( SDL_Point ) ) ;
player . physics - > obj_elasticity = 0.7 ;
player . physics - > collision_poly = calloc ( 4 , sizeof ( Vect ) ) ;
player . physics - > collision_shape = calloc ( 4 , sizeof ( Vect ) ) ;
player . physics - > collision_poly_size = 4 ;
SDL_Poin t * rect = player . physics - > collision_shape ;
rect [ 0 ] . x = - 5 ; rect [ 0 ] . y = - 2 0;
rect [ 1 ] . x = 5 ; rect [ 1 ] . y = - 2 0;
rect [ 2 ] . x = 5 ; rect [ 2 ] . y = 2 0;
rect [ 3 ] . x = - 5 ; rect [ 3 ] . y = 2 0;
Vec t * rect = player . physics - > collision_shape ;
rect [ 0 ] . x = - 10 ; rect [ 0 ] . y = - 1 0;
rect [ 1 ] . x = 10 ; rect [ 1 ] . y = - 1 0;
rect [ 2 ] . x = 10 ; rect [ 2 ] . y = 1 0;
rect [ 3 ] . x = - 10 ; rect [ 3 ] . y = 1 0;
// gravity
//set_motor_newtons(player.physics, M_GRAVITY, 0.0, player.physics->obj_mass * 5);
set_motor_newtons ( player . physics , M_GRAVITY , 0.0 , player . physics - > obj_mass * 4 ) ;
// walking motor
add_motor ( player . physics , 0.0 , player . physics - > obj_mass * 9.81 ) ;
@ -103,7 +142,7 @@ player_st get_player(int x, int y) {
@@ -103,7 +142,7 @@ player_st get_player(int x, int y) {
return ( player ) ;
}
bool point_point_colcheck ( SDL_Point one , SDL_Poin t two ) {
bool point_point_colcheck ( Vect one , Vec t two ) {
if ( one . x = = two . x & & one . y = = two . y ) {
return true ;
}
@ -115,8 +154,7 @@ typedef struct {
@@ -115,8 +154,7 @@ typedef struct {
Vect two ;
} Collision ;
bool point_line_colcheck ( SDL_Point line [ 2 ] , SDL_Point point ) {
bool point_line_colcheck ( Vect line [ 2 ] , Vect point ) {
// point is outside the rectangle made by the line
if ( ( point . x > line [ 0 ] . x & & point . x > line [ 1 ] . x )
| | ( point . x < line [ 0 ] . x & & point . x < line [ 0 ] . x )
@ -170,7 +208,7 @@ double *project_col_poly(Body *shape, Vect V) {
@@ -170,7 +208,7 @@ double *project_col_poly(Body *shape, Vect V) {
return res ;
}
Vect get_normal ( SDL_Point start , SDL_Poin t end ) {
Vect get_normal ( Vect start , Vec t end ) {
Vect norm ;
double x = ( end . x - start . x ) ;
double y = ( end . y - start . y ) ;
@ -187,8 +225,8 @@ bool sat_collision_check(Body *one, Body *two, Vect *translation) {
@@ -187,8 +225,8 @@ bool sat_collision_check(Body *one, Body *two, Vect *translation) {
int num_axes = one - > collision_poly_size + two - > collision_poly_size ;
Vect * axes = calloc ( num_axes , sizeof ( Vect ) ) ;
SDL_Poin t end ;
SDL_Poin t start = one - > collision_poly [ 0 ] ;
Vec t end ;
Vec t start = one - > collision_poly [ 0 ] ;
for ( int i = 1 ; i < one - > collision_poly_size ; i + + ) {
end = one - > collision_poly [ i ] ;
axes [ i - 1 ] = get_normal ( start , end ) ;
@ -264,6 +302,8 @@ bool sat_collision_check(Body *one, Body *two, Vect *translation) {
@@ -264,6 +302,8 @@ bool sat_collision_check(Body *one, Body *two, Vect *translation) {
trans . y = min_overlap * min_axis . y ;
* translation = trans ;
printf ( " Trans Vect: %e, %e \n " , trans . x , trans . y ) ;
free ( axes ) ;
free ( proj_one ) ;
free ( proj_two ) ;
@ -282,8 +322,8 @@ bool check_collision(Body *one, Body *two, Vect *translation) {
@@ -282,8 +322,8 @@ bool check_collision(Body *one, Body *two, Vect *translation) {
}
// point-line
if ( ( onesize = = 1 | | twosize = = 1 ) & & ( onesize = = 2 | | twosize = = 2 ) ) {
SDL_Poin t line [ 2 ] ;
SDL_Poin t point ;
Vec t line [ 2 ] ;
Vec t point ;
if ( onesize > twosize ) {
line [ 0 ] = one - > collision_poly [ 0 ] ;
line [ 1 ] = one - > collision_poly [ 1 ] ;
@ -324,11 +364,11 @@ Wall *get_long_wall(int numNodes, int *nodes) {
@@ -324,11 +364,11 @@ Wall *get_long_wall(int numNodes, int *nodes) {
memset ( & wall , 0 , sizeof ( wall ) ) ;
wall . numNodes = numNodes ;
wall . nodes = malloc ( sizeof ( SDL_Point ) * numNodes ) ;
wall . nodes = calloc ( numNodes , sizeof ( SDL_Point ) ) ;
get_new_physics ( & wall . physics ) ;
wall . physics - > collision_poly = calloc ( numNodes , sizeof ( SDL_Poin t) ) ;
wall . physics - > collision_shape = calloc ( numNodes , sizeof ( SDL_Poin t) ) ;
wall . physics - > collision_poly = calloc ( numNodes , sizeof ( Vec t) ) ;
wall . physics - > collision_shape = calloc ( numNodes , sizeof ( Vec t) ) ;
wall . physics - > collision_poly_size = numNodes ;
// collisions
@ -400,18 +440,32 @@ void add_motor(Body *thing, double x, double y) {
@@ -400,18 +440,32 @@ void add_motor(Body *thing, double x, double y) {
}
// basic collision handler for testing
bool process_collisions ( Body * thing , Vect * trans ) {
int process_collisions ( Body * thing , Vect * * trans ) {
* trans = calloc ( 10 , sizeof ( Vect ) ) ;
int num_cols = 0 ;
for ( int k = 0 ; k < things_in_world ; k + + ) {
if ( world [ k ] . kind = = STATIC_WALL_W
if ( world [ k ] . kind = = STATIC_WALL_W
& & world [ k ] . wall - > physics - > uid ! = thing - > uid ) {
if ( check_collision ( world [ k ] . wall - > physics , thing , trans ) ) {
if ( check_collision ( world [ k ] . wall - > physics , thing , * trans + num_cols ) ) {
num_cols + + ;
thing - > colliding = true ;
return true ;
}
} else if ( world [ k ] . kind = = FLOOR ) {
for ( int i = 0 ; i < world [ k ] . floor - > numPolys ; i + + ) {
if ( check_collision ( world [ k ] . floor - > polys [ i ] . physics , thing , * trans + num_cols ) ) {
num_cols + + ;
thing - > colliding = true ;
}
}
}
}
thing - > colliding = false ;
return false ;
if ( ! num_cols ) {
thing - > colliding = false ;
free ( * trans ) ;
return false ;
} else {
return num_cols ;
}
}
/* Basic physics works by adding up the acceleratino caused by all the forces on
@ -423,36 +477,61 @@ void advance_thing(Body * thing) {
@@ -423,36 +477,61 @@ void advance_thing(Body * thing) {
thing - > acc . x = 0 ;
thing - > acc . y = 0 ;
printf ( " Position: %f %f \n " , thing - > position . x , thing - > position . y ) ;
thing - > updateCollisionPoly ( thing ) ;
Vect translation ;
if ( process_collisions ( thing , & translation ) ) {
thing - > position . x + = translation . x ;
thing - > position . y + = translation . y ;
double mag = vect_mag ( translation ) ;
translation . x = translation . x / mag ;
translation . y = translation . y / mag ;
if ( ! thing - > dynamics ) {
return ;
}
mag = vect_scalar_projection ( thing - > vel , translation ) ;
Vect * translations ;
int numcols = 0 ;
if ( ( numcols = process_collisions ( thing , & translations ) ) ) {
for ( int i = 0 ; i < numcols ; i + + ) {
Vect translation = translations [ i ] ;
double mag = vect_mag ( translation ) ;
double check = vect_scalar_projection ( translation , thing - > vel ) ;
if ( check > = 0 ) {
translation . x * = - 1 ;
translation . y * = - 1 ;
}
Vect revert_vel ;
thing - > position . x + = translation . x ;
thing - > position . y + = translation . y ;
translation . x = translation . x / mag ;
translation . y = translation . y / mag ;
revert_vel . x = cos ( vect_dir ( translation ) ) * mag ;
revert_vel . y = sin ( vect_dir ( translation ) ) * mag ;
mag = vect_scalar_projection ( thing - > vel , translation ) ;
thing - > vel . x - = revert_vel . x ;
thing - > vel . y - = revert_vel . y ;
}
Vect revert_vel ;
if ( ! thing - > dynamics ) {
return ;
revert_vel . x = cos ( vect_dir ( translation ) ) * mag ;
revert_vel . y = sin ( vect_dir ( translation ) ) * mag ;
thing - > vel . x - = revert_vel . x ;
thing - > vel . y - = revert_vel . y ;
// restitution force
Vect rest ;
/*rest.x = 0;*/
/*rest.y = 0;*/
/*double impulse = thing->obj_mass * vect_mag(thing->vel) * thing->obj_elasticity;*/
/*rest.x = cos(vect_dir(translation)) * impulse;*/
/*rest.y = sin(vect_dir(translation)) * impulse;*/
/*accel_thing(thing, rest.x, rest.y);*/
}
free ( translations ) ;
}
uint32_t now = SDL_GetTicks ( ) ;
uint32_t time_delta = now - thing - > last_advance_time ;
thing - > last_advance_time = SDL_GetTicks ( ) ; // in milliseconds
//time_delta = 17;
time_delta = 15 ;
// motors
for ( int i = 0 ; i < thing - > num_motors ; i + + ) {
@ -558,6 +637,10 @@ void advance_things(void) {
@@ -558,6 +637,10 @@ void advance_things(void) {
logwrite ( INFO , " ADVANCE WALL \n " ) ;
advance_thing ( world [ i ] . wall - > physics ) ;
break ;
case FLOOR :
for ( int k = 0 ; k < world [ i ] . floor - > numPolys ; k + + ) {
advance_thing ( world [ i ] . floor - > polys [ k ] . physics ) ;
}
}
}
}
@ -578,6 +661,22 @@ void add_to_world(world_thing thing) {
@@ -578,6 +661,22 @@ void add_to_world(world_thing thing) {
}
void get_floor ( void ) {
int floorsize = 100 ;
FloorPoly * polys = generate_floor_simple ( floorsize ) ;
Floor * floor = calloc ( 1 , sizeof ( Floor ) ) ;
floor - > polys = polys ;
floor - > numPolys = floorsize ;
world_thing thing ;
thing . kind = FLOOR ;
thing . floor = floor ;
add_to_world ( thing ) ;
}
void startgame ( SDL_Renderer * ren ) {
logwrite ( INFO , " STARTGAME " ) ;
things_in_world = 0 ;
@ -586,7 +685,7 @@ void startgame(SDL_Renderer * ren) {
@@ -586,7 +685,7 @@ void startgame(SDL_Renderer * ren) {
memset ( world , 0 , sizeof ( world_thing ) * 100 ) ;
SDL_GetRendererOutputSize ( ren , & width , & height ) ;
player = get_player ( 100 , 4 00) ;
player = get_player ( 700 , 6 00) ;
world_thing player_world ;
@ -603,8 +702,10 @@ void startgame(SDL_Renderer * ren) {
@@ -603,8 +702,10 @@ void startgame(SDL_Renderer * ren) {
wall_world . kind = STATIC_WALL_W ;
add_to_world ( wall_world ) ;
viewport_pos . x = 0 ;
viewport_pos . x = 70 0;
viewport_pos . y = 0 ;
get_floor ( ) ;
}
float get_abs ( float x , float y ) {