1
1
Fork 0
Browse Source

sorta working collisions idk they broke

thread-physics
user 5 years ago
parent
commit
90e8da7a40
  1. 47
      draw.c
  2. 3
      draw.h
  3. 205
      game.c
  4. 45
      game.h

47
draw.c

@ -67,6 +67,25 @@ void draw_player(SDL_Renderer * ren, int x, int y, bool red) { @@ -67,6 +67,25 @@ void draw_player(SDL_Renderer * ren, int x, int y, bool red) {
SDL_SetRenderDrawColor(ren, 0,0,0, 255);
}
void draw_floor(SDL_Renderer *ren, FloorPoly *poly) {
SDL_Point left;
SDL_Point right;
left.x = poly->left.x - viewport_pos.x;
left.y = poly->left.y - viewport_pos.y;
right.x = poly->right.x - viewport_pos.x;
right.y = poly->right.y - viewport_pos.y;
SDL_SetRenderDrawColor(ren, 100,100,100, 255);
double m = (double)(right.y - left.y) / (double)(right.x - left.x);
double c = (double)left.y - ((double)left.x * m);
for (int i = left.x; i <= right.x; i++) {
int y = (int)(m * i + c);
SDL_RenderDrawLine(ren, i, y, i, height);
}
SDL_SetRenderDrawColor(ren, 0,0,0, 255);
}
// draw collision poly
void draw_collision_poly(SDL_Renderer* ren, Body *body) {
if (!SHOWCOLLISION) {
@ -182,10 +201,25 @@ int distance_colour(int x, int y, int x2, int y2, int blackpoint) { @@ -182,10 +201,25 @@ int distance_colour(int x, int y, int x2, int y2, int blackpoint) {
return frac;
}
void update_viewport(double x, double y) {
viewport_pos.x = x - 300;
viewport_pos.y = y - 300;
float xmargin = 0.26;
float ymargin = 0.2;
if (player.physics->position.x - viewport_pos.x > (1-xmargin) * width) {
viewport_pos.x = - ((1-xmargin) * width - player.physics->position.x);
}
if (player.physics->position.x - viewport_pos.x < xmargin * width) {
viewport_pos.x = -(xmargin * width - player.physics->position.x);
}
if (player.physics->position.y - viewport_pos.y > (1-ymargin) * height) {
viewport_pos.y = -((1-ymargin) * height - player.physics->position.y);
}
if (player.physics->position.y - viewport_pos.y < ymargin * height) {
viewport_pos.y = -(ymargin * height - player.physics->position.y);
}
}
@ -217,7 +251,6 @@ void redraw_buffer(SDL_Renderer * ren) { @@ -217,7 +251,6 @@ void redraw_buffer(SDL_Renderer * ren) {
switch (thing.kind) {
case PLAYER:
draw_player(ren, (*thing.player).physics->position.x, (*thing.player).physics->position.y, thing.player->colliding);
draw_collision_poly(ren, thing.player->physics);
draw_forces(ren, thing.player->physics);
@ -226,6 +259,12 @@ void redraw_buffer(SDL_Renderer * ren) { @@ -226,6 +259,12 @@ void redraw_buffer(SDL_Renderer * ren) {
draw_wall(ren, thing.wall);
draw_collision_poly(ren, thing.wall->physics);
break;
case FLOOR:
for (int i = 0; i < thing.floor->numPolys; i++) {
draw_floor(ren, &thing.floor->polys[i]);
draw_collision_poly(ren, thing.floor->polys[i].physics);
}
}
}

3
draw.h

@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
#define _DEFDRAW
#define SHOWCOLLISION 1
#define SHOWFORCES 1
#define SHOWFORCES 0
#include "garbo.h"
#include "game.h"
@ -31,7 +31,6 @@ void redraw_buffer(SDL_Renderer * ren); @@ -31,7 +31,6 @@ void redraw_buffer(SDL_Renderer * ren);
Vect viewport_pos;
int width, height;
#endif

205
game.c

@ -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_Point *rect = player.physics->collision_shape;
rect[0].x = -5; rect[0].y = -20;
rect[1].x = 5; rect[1].y = -20;
rect[2].x = 5; rect[2].y = 20;
rect[3].x = -5; rect[3].y = 20;
Vect *rect = player.physics->collision_shape;
rect[0].x = -10; rect[0].y = -10;
rect[1].x = 10; rect[1].y = -10;
rect[2].x = 10; rect[2].y = 10;
rect[3].x = -10; rect[3].y = 10;
// 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_Point two) {
bool point_point_colcheck(Vect one, Vect 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_Point end) {
Vect get_normal(Vect start, Vect 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_Point end;
SDL_Point start = one->collision_poly[0];
Vect end;
Vect 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_Point line[2];
SDL_Point point;
Vect line[2];
Vect 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_Point));
wall.physics->collision_shape = calloc(numNodes, sizeof(SDL_Point));
wall.physics->collision_poly = calloc(numNodes, sizeof(Vect));
wall.physics->collision_shape = calloc(numNodes, sizeof(Vect));
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,400);
player = get_player(700,600);
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 = 700;
viewport_pos.y = 0;
get_floor();
}
float get_abs(float x,float y) {

45
game.h

@ -19,6 +19,12 @@ enum motors { @@ -19,6 +19,12 @@ enum motors {
M_PLAYER_WALK = 1
};
enum world_thing_kind {
PLAYER_W,
STATIC_WALL_W,
FLOOR
};
// used to exert a force on an object
typedef struct motorstruct {
double x; // positive is right
@ -36,8 +42,8 @@ typedef struct motorstruct { @@ -36,8 +42,8 @@ typedef struct motorstruct {
} Motor;
typedef struct {
double x;
double y;
int x;
int y;
} Point;
typedef struct BodyStruct{
@ -58,11 +64,13 @@ typedef struct BodyStruct{ @@ -58,11 +64,13 @@ typedef struct BodyStruct{
// SI Unit kinematics
/*------------------*/
Vect position;
Vect vel;
Vect acc;
// properties
double obj_mass; // kgs
double obj_elasticity; // rho
//float x_vel;
//float y_vel;
@ -70,21 +78,24 @@ typedef struct BodyStruct{ @@ -70,21 +78,24 @@ typedef struct BodyStruct{
//float y_acc;
/*------------------*/
// constants
double elasticity;
// collisions
SDL_Point *collision_poly;
SDL_Point *collision_shape;
Vect *collision_poly;
Vect *collision_shape;
int collision_poly_size;
void (*updateCollisionPoly)(struct BodyStruct *);
// properties
float obj_mass; // kgs
// fields
float glob_friction;
double glob_friction;
bool glob_gravity; // t/f
uint32_t last_advance_time;
// applying forces
int num_motors;
int max_motors;
Motor *motors;
@ -103,10 +114,16 @@ typedef struct { @@ -103,10 +114,16 @@ typedef struct {
Body *physics;
} Wall;
enum world_thing_kind {
PLAYER_W = 0,
STATIC_WALL_W = 1
};
typedef struct {
Vect left;
Vect right;
Body *physics;
} FloorPoly;
typedef struct {
FloorPoly *polys;
int numPolys;
} Floor;
typedef struct {
enum world_thing_kind kind;
@ -116,8 +133,8 @@ typedef struct { @@ -116,8 +133,8 @@ typedef struct {
union {
player_st *player;
Wall *wall;
Floor *floor;
};
} world_thing;

Loading…
Cancel
Save