@ -1,14 +1,24 @@
@@ -1,14 +1,24 @@
# include "game.h"
# include "vect.h"
# define GRAVITY_ACCEL 2
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 ) ;
// move the collision poly to the position of the player
void default_update_collision_poly ( Body * body ) {
return ;
printf ( " Collision polygon: " ) ;
for ( int i = 0 ; i < body - > collision_poly_size ; i + + ) {
int x = body - > collision_shape [ i ] . x + body - > x_pos ;
int y = body - > collision_shape [ i ] . y + body - > y_pos ;
printf ( " %d %d, " , x , y ) ;
body - > collision_poly [ i ] . x = x ;
body - > collision_poly [ i ] . y = y ;
}
printf ( " \n " ) ;
fflush ( stdout ) ;
}
// would probably be useful xd
@ -43,14 +53,13 @@ void get_new_physics(Body **phys) {
@@ -43,14 +53,13 @@ void get_new_physics(Body **phys) {
add_motor ( physics , 0.0 , 0.0 ) ;
physics - > updateCollisionPoly = default_update_collision_poly ;
* phys = physics ; return ;
}
void updatePlayerCollision ( Body * physics ) {
physics - > collision_poly [ 0 ] . x = physics - > x_pos ;
physics - > collision_poly [ 0 ] . y = physics - > y_pos ;
}
/*void updatePlayerCollision(Body *physics) {*/
/*physics->collision_poly[0].x = physics->x_pos;*/
/*physics->collision_poly[0].y = physics->y_pos;*/
/*}*/
player_st get_player ( int x , int y ) {
/* creates player at given postion and zeroes physics */
@ -65,44 +74,28 @@ player_st get_player(int x, int y) {
@@ -65,44 +74,28 @@ player_st get_player(int x, int y) {
player . physics - > y_pos = y ;
player . physics - > glob_friction = 40 ; // drag coef * area
player . physics - > updateCollisionPoly = updatePlayerCollision ;
player . physics - > updateCollisionPoly = default_update_collision_poly ;
player . physics - > collision_poly = calloc ( 1 , sizeof ( SDL_Point ) ) ;
player . physics - > collision_poly = calloc ( 4 , sizeof ( SDL_Point ) ) ;
player . physics - > collision_shape = calloc ( 4 , sizeof ( SDL_Point ) ) ;
set_motor_newtons ( player . physics , M_GRAVITY , 0.0 , player . physics - > obj_mass * 7 ) ;
player . physics - > collision_poly_size = 4 ;
SDL_Point * rect = player . physics - > collision_shape ;
rect [ 0 ] . x = - 5 ; rect [ 0 ] . y = - 5 ;
rect [ 1 ] . x = 5 ; rect [ 1 ] . y = - 5 ;
rect [ 2 ] . x = 5 ; rect [ 2 ] . y = 5 ;
rect [ 3 ] . x = - 5 ; rect [ 3 ] . y = 5 ;
set_motor_newtons ( player . physics , M_GRAVITY , 0.0 , player . physics - > obj_mass * 5 ) ;
// walking motor
add_motor ( player . physics , 0.0 , player . physics - > obj_mass * 9.81 ) ;
set_motor_max_velocity ( player . physics , M_PLAYER_WALK , 6 ) ; // has to be > grav
set_motor_max_velocity ( player . physics , M_PLAYER_WALK , 5 ) ; // has to be > grav
set_motor_max_velocity ( player . physics , M_GRAVITY , 5 ) ;
return ( player ) ;
}
wall_node get_wall_node ( int x , int y ) {
wall_node wn ;
memset ( & wn , 0 , sizeof ( wn ) ) ;
wn . x = x ;
wn . y = y ;
return wn ;
}
Wall * get_stat_wall ( int st_x , int st_y , int en_x , int en_y ) {
Wall wall ;
memset ( & wall , 0 , sizeof ( wall ) ) ;
wall . numNodes = 2 ;
wall . nodes = malloc ( sizeof ( wall_node ) * wall . numNodes ) ;
wall . nodes [ 0 ] = get_wall_node ( st_x , st_y ) ;
wall . nodes [ 1 ] = get_wall_node ( en_x , en_y ) ;
Wall * wallwall = malloc ( sizeof ( wall ) ) ;
* wallwall = wall ;
return wallwall ;
}
bool point_point_colcheck ( SDL_Point one , SDL_Point two ) {
if ( one . x = = two . x & & one . y = = two . y ) {
return true ;
@ -115,6 +108,7 @@ typedef struct {
@@ -115,6 +108,7 @@ typedef struct {
Vect two ;
} Collision ;
bool point_line_colcheck ( SDL_Point line [ 2 ] , SDL_Point point ) {
// point is outside the rectangle made by the line
@ -139,18 +133,125 @@ bool point_line_colcheck(SDL_Point line[2], SDL_Point point) {
@@ -139,18 +133,125 @@ bool point_line_colcheck(SDL_Point line[2], SDL_Point point) {
return false ;
}
double * project_col_poly ( Body * shape , Vect V ) {
printf ( " PROJECTION : \n " ) ;
double * proj = calloc ( shape - > collision_poly_size , sizeof ( double ) ) ;
for ( int i = 0 ; i < shape - > collision_poly_size ; i + + ) {
Vect point ;
point . x = shape - > collision_poly [ i ] . x ;
point . y = shape - > collision_poly [ i ] . y ;
printf ( " point: %f %f mag: %f \n " , point . x , point . y , vect_mag ( point ) ) ;
printf ( " Vectp: %f %f mag: %f \n " , V . x , V . y , vect_mag ( V ) ) ;
proj [ i ] = vect_scalar_projection ( point , V ) ;
}
double min , max ;
max = - 99999999 ;
min = 99999999 ;
for ( int i = 0 ; i < shape - > collision_poly_size ; i + + ) {
if ( proj [ i ] > max ) {
max = proj [ i ] ;
}
if ( proj [ i ] < min ) {
min = proj [ i ] ;
}
}
double * res = calloc ( 2 , sizeof ( double ) ) ;
res [ 0 ] = min ;
res [ 1 ] = max ;
return res ;
}
Vect get_normal ( SDL_Point start , SDL_Point end ) {
Vect norm ;
double x = ( end . x - start . x ) ;
double y = ( end . y - start . y ) ;
norm . x = - y ;
norm . y = x ;
return norm ;
}
bool sat_collision_check ( Body * one , Body * two ) {
int num_axes = one - > collision_poly_size + two - > collision_poly_size ;
Vect * axes = calloc ( num_axes , sizeof ( Vect ) ) ;
SDL_Point end ;
SDL_Point 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 ) ;
printf ( " .%d \n " , i - 1 ) ;
start = end ;
}
end = one - > collision_poly [ 0 ] ;
axes [ one - > collision_poly_size - 1 ] = get_normal ( start , end ) ;
printf ( " .%d \n " , one - > collision_poly_size - 1 ) ;
start = two - > collision_poly [ 0 ] ;
for ( int i = 1 ; i < two - > collision_poly_size ; i + + ) {
end = two - > collision_poly [ i ] ;
axes [ i - 1 + one - > collision_poly_size ] = get_normal ( start , end ) ;
printf ( " .%d \n " , i - 1 + one - > collision_poly_size ) ;
start = end ;
}
end = two - > collision_poly [ 0 ] ;
axes [ two - > collision_poly_size + one - > collision_poly_size - 1 ] = get_normal ( start , end ) ;
printf ( " .%d \n " , two - > collision_poly_size + one - > collision_poly_size - 1 ) ;
// normalise
for ( int i = 0 ; i < num_axes ; i + + ) {
printf ( " AXIS TO CHECK :(num %d) %f %f \n " , i , axes [ i ] . x , axes [ i ] . y ) ;
double len = vect_mag ( axes [ i ] ) ;
axes [ i ] . x = axes [ i ] . x / len ;
axes [ i ] . y = axes [ i ] . y / len ;
printf ( " AXIS TO CHECK normed: %f %f \n " , axes [ i ] . x , axes [ i ] . y ) ;
}
double * proj_one , * proj_two ;
proj_one = proj_two = 0 ;
for ( int i = 0 ; i < num_axes ; i + + ) {
// project
if ( proj_one ) {
free ( proj_one ) ;
}
if ( proj_two ) {
free ( proj_two ) ;
}
proj_one = project_col_poly ( one , axes [ i ] ) ;
proj_two = project_col_poly ( two , axes [ i ] ) ;
printf ( " Testing on : %f %f \n " , axes [ i ] . x , axes [ i ] . y ) ;
if ( ! ( proj_one [ 1 ] > proj_two [ 1 ] & & proj_one [ 0 ] < proj_two [ 0 ] )
& & ! ( proj_one [ 1 ] < proj_two [ 1 ] & & proj_one [ 0 ] > proj_two [ 0 ] ) ) {
printf ( " not overlapping \n " ) ;
free ( axes ) ;
return false ;
} else {
printf ( " overlapping \n " ) ;
}
}
free ( axes ) ;
free ( proj_one ) ;
free ( proj_two ) ;
return true ;
}
bool route_collision ( Body * one , Body * two ) {
int onesize = one - > collison_poly_size ;
int twosize = two - > collison_poly_size ;
int onesize = one - > collisi on_poly_size ;
int twosize = two - > collisi on_poly_size ;
// point-point
if ( one - > collison_poly_size = = 1 & & two - > collison_poly_size = = 1 ) {
if ( one - > collisi on_poly_size = = 1 & & two - > collisi on_poly_size = = 1 ) {
if ( point_point_colcheck ( one - > collision_poly [ 0 ] , two - > collision_poly [ 0 ] ) ) {
return true ;
}
}
// point-line
if ( ( onesize = = 1 | | twosize = = 1 ) & & ( onesize = = 2 | | twosize = = 2 ) ) {
SDL_Point line [ 2 ] ;
@ -166,7 +267,6 @@ bool route_collision(Body *one, Body *two) {
@@ -166,7 +267,6 @@ bool route_collision(Body *one, Body *two) {
}
return point_line_colcheck ( line , point ) ;
}
// line-line
@ -186,7 +286,8 @@ bool route_collision(Body *one, Body *two) {
@@ -186,7 +286,8 @@ bool route_collision(Body *one, Body *two) {
// poly-poly
if ( ( onesize > 2 & & twosize > 2 ) ) {
return false ;
return sat_collision_check ( one , two ) ;
}
}
@ -200,16 +301,21 @@ Wall *get_long_wall(int numNodes, int *nodes) {
@@ -200,16 +301,21 @@ Wall *get_long_wall(int numNodes, int *nodes) {
memset ( & wall , 0 , sizeof ( wall ) ) ;
wall . numNodes = numNodes ;
wall . nodes = malloc ( sizeof ( wall_node ) * numNodes ) ;
wall . physics = calloc ( 1 , sizeof ( Body ) ) ;
wall . nodes = malloc ( sizeof ( SDL_Point ) * numNodes ) ;
get_new_physics ( & wall . physics ) ;
wall . physics - > collision_poly = calloc ( numNodes , sizeof ( SDL_Point ) ) ;
wall . physics - > collision_shape = calloc ( numNodes , sizeof ( SDL_Point ) ) ;
wall . physics - > collision_poly_size = numNodes ;
// collisions
//SDL_Point *collision_poly;
for ( int i = 0 ; i < numNodes ; i + + ) {
wall . nodes [ i ] = get_wall_node ( nodes [ 2 * i ] , nodes [ 2 * i + 1 ] ) ;
wall . nodes [ i ] . x = nodes [ 2 * i ] ;
wall . nodes [ i ] . y = nodes [ 2 * i + 1 ] ;
wall . physics - > collision_poly [ i ] . x = nodes [ 2 * i ] ;
wall . physics - > collision_poly [ i ] . y = nodes [ 2 * i + 1 ] ;
wall . physics - > collision_shape [ i ] . x = nodes [ 2 * i ] ;
wall . physics - > collision_shape [ i ] . y = nodes [ 2 * i + 1 ] ;
}
Wall * wallwall = malloc ( sizeof ( wall ) ) ;
@ -289,6 +395,9 @@ void advance_thing(Body * thing) {
@@ -289,6 +395,9 @@ void advance_thing(Body * thing) {
// motors
for ( int i = 0 ; i < thing - > num_motors ; i + + ) {
if ( thing - > motors [ i ] . TTL < = 0 ) {
continue ;
}
Vect F ;
Vect V ;
@ -298,20 +407,23 @@ void advance_thing(Body * thing) {
@@ -298,20 +407,23 @@ void advance_thing(Body * thing) {
V . y = thing - > y_vel ;
Vect vel_in_dir = project_vect ( V , F ) ;
if ( thing - > motors [ i ] . TTL < = 0 ) {
continue ;
}
double dirF = atan2 ( F . y , F . x ) ;
double dirV = atan2 ( V . y , V . x ) ;
if ( thing - > motors [ i ] . TTL ! = INFINITY ) {
thing - > motors [ i ] . TTL - - ;
}
if ( thing - > motors [ i ] . max_velocity > vect_mag ( vel_in_dir ) ) {
double diff = dirV > dirF ? dirV - dirF : dirF - dirV ;
if ( thing - > motors [ i ] . max_velocity > vect_mag ( vel_in_dir )
| | diff > = M_PI ) {
double acc_x = thing - > motors [ i ] . x / thing - > obj_mass ;
double acc_y = thing - > motors [ i ] . y / thing - > obj_mass ;
accel_thing ( thing , acc_x , acc_y ) ;
}
// printf("\n diff angle: %f pi: %f \n", dirV - dirF, M_PI);
// printf("Vel: %f, Force: %f\n\n", dirV, dirF);
}
// accelerate based on accel
@ -364,6 +476,8 @@ void advance_thing(Body * thing) {
@@ -364,6 +476,8 @@ void advance_thing(Body * thing) {
if ( thing - > x_pos < 0 ) {
thing - > x_pos = width ;
}
thing - > updateCollisionPoly ( thing ) ;
}
// basic collision handler
@ -372,7 +486,6 @@ void handle_collisions(void) {
@@ -372,7 +486,6 @@ void handle_collisions(void) {
if ( world [ k ] . kind = = STATIC_WALL_W ) {
if ( check_collision ( world [ k ] . wall - > physics ,
player . physics ) ) {
player . physics - > x_vel = 0 ;
player . physics - > y_vel = 0 ;
}
@ -391,7 +504,7 @@ void advance_things(void) {
@@ -391,7 +504,7 @@ void advance_things(void) {
break ;
case STATIC_WALL_W :
logwrite ( INFO , " ADVANCE WALL \n " ) ;
// advance_thing(world[i].wall->physics);
advance_thing ( world [ i ] . wall - > physics ) ;
break ;
}
}