1
1
Fork 0
Browse Source

Add ceiling

thread-physics
= 4 years ago
parent
commit
ae436a96df
  1. 30
      draw.c
  2. 117
      game.c
  3. 5
      game.h
  4. 2
      logger.c

30
draw.c

@ -67,7 +67,7 @@ void draw_player(SDL_Renderer * ren, int x, int y, bool red) { @@ -67,7 +67,7 @@ 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) {
void draw_floor(SDL_Renderer *ren, FloorPoly *poly, bool down) {
SDL_Point left;
SDL_Point right;
left.x = poly->left.x - viewport_pos.x;
@ -84,15 +84,27 @@ void draw_floor(SDL_Renderer *ren, FloorPoly *poly) { @@ -84,15 +84,27 @@ void draw_floor(SDL_Renderer *ren, FloorPoly *poly) {
left.y = poly->left.y - viewport_pos.y;
right.y = poly->right.y - viewport_pos.y;
if (left.y <= 0 && right.y <= 0) {
return;
}
if (left.y >= height && right.y >= height) {
return;
}
SDL_SetRenderDrawColor(ren, 100,100,100, 255);
int end = down ? height : 0;
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);
if (y > 0) {
SDL_RenderDrawLine(ren, i, y, i, end);
}
}
SDL_SetRenderDrawColor(ren, 0,0,0, 255);
SDL_SetRenderDrawColor(ren, 0,0,0, 255);
}
// draw collision poly
@ -270,10 +282,18 @@ void redraw_buffer(SDL_Renderer * ren) { @@ -270,10 +282,18 @@ void redraw_buffer(SDL_Renderer * ren) {
break;
case FLOOR:
for (int i = 0; i < thing.floor->numPolys; i++) {
draw_floor(ren, &thing.floor->polys[i]);
draw_floor(ren, &thing.floor->polys[i], true);
draw_collision_poly(ren, thing.floor->polys[i].physics);
}
break;
case CEILING:
for (int i = 0; i < thing.floor->numPolys; i++) {
// draw_floor(ren, &thing.floor->polys[i], true);
draw_floor(ren, &thing.floor->polys[i], false);
draw_collision_poly(ren, thing.floor->polys[i].physics);
}
break;
}
}

117
game.c

@ -16,7 +16,42 @@ void default_update_collision_poly(Body *body) { @@ -16,7 +16,42 @@ void default_update_collision_poly(Body *body) {
body->collision_poly[i].x = x;
body->collision_poly[i].y = y;
}
fflush(stdout);
}
// collision poly size must be 2x shape_size + 1
void cast_update_collision_poly(Body *body) {
for (int i=0; i < body->collision_shape_size; i++) {
double x = body->collision_shape[i].x + body->position.x;
double y = body->collision_shape[i].y + body->position.y;
body->collision_poly[i].x = x;
body->collision_poly[i].y = y;
printf("xxx %d\n", i);
}
for (int i=body->collision_shape_size - 1; i >= 0; i--) {
double x = body->collision_shape[i].x + body->next_position.x;
double y = body->collision_shape[i].y + body->next_position.y;
int k = body->collision_shape_size + i;
body->collision_poly[k].x = x;
body->collision_poly[k].y = y;
printf("xxx %d\n", k);
}
for (int i = 0; i < body->collision_poly_size; i++) {
printf("colpoly: %f %f\n", body->collision_poly[i].x, body->collision_poly[i].y);
}
/*int i=body->collision_shape_size - 1;*/
/*double x = body->collision_shape[i].x + body->next_position.x;*/
/*double y = body->collision_shape[i].y + body->next_position.y;*/
/*body->collision_poly[body->collision_shape_size - 1 + i].x = x; */
/*body->collision_poly[body->collision_shape_size - 1 + i].y = y; */
/*body->collision_poly[(body->collision_poly_size - 1) * 2 + 1] = body->collision_poly[(body->collision_poly_size - 1) * 2 + 1];*/
/*body->collision_poly[(body->collision_poly_size - 1) * 2 + 2] = body->collision_poly[(body->collision_poly_size - 1)];*/
}
void default_motor_curve(Motor *motor) {
@ -24,11 +59,13 @@ void default_motor_curve(Motor *motor) { @@ -24,11 +59,13 @@ void default_motor_curve(Motor *motor) {
return;
}
FloorPoly* generate_floor_simple(int num_polys) {
#define FLOOR_THICKNESS 200
FloorPoly* generate_floor_simple(int num_polys, bool extend_down, int st_height) {
FloorPoly *floor = calloc(num_polys, sizeof(FloorPoly));
Vect last, next;
last.x = 10;
last.y = 900;
last.y = st_height;
for (int i = 0; i < num_polys; i++) {
double run = (rand() % 900);
@ -43,6 +80,8 @@ FloorPoly* generate_floor_simple(int num_polys) { @@ -43,6 +80,8 @@ FloorPoly* generate_floor_simple(int num_polys) {
poly.physics->position = last;
int offset = extend_down ? FLOOR_THICKNESS : -FLOOR_THICKNESS;
poly.physics->collision_poly_size = 4;
poly.physics->collision_poly = calloc(4, sizeof(Vect));
poly.physics->collision_shape = calloc(4, sizeof(Vect));
@ -54,10 +93,12 @@ FloorPoly* generate_floor_simple(int num_polys) { @@ -54,10 +93,12 @@ FloorPoly* generate_floor_simple(int num_polys) {
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[2].y = rise+offset;
poly.physics->collision_shape[3].x = 0;
poly.physics->collision_shape[3].y = rise+200;
poly.physics->collision_shape[3].y = rise+offset;
default_update_collision_poly(poly.physics);
last = next;
floor[i] = poly;
@ -89,6 +130,7 @@ void get_new_physics(Body **phys) { @@ -89,6 +130,7 @@ void get_new_physics(Body **phys) {
memset(physics->motors, 0, sizeof(Motor) * 100);
physics->max_motors = 100;
physics->num_motors = 0;
// gravity
add_motor(physics, 0.0, 0.0);
// friction
@ -118,16 +160,22 @@ player_st get_player(int x, int y) { @@ -118,16 +160,22 @@ player_st get_player(int x, int y) {
player.physics->position.x = x;
player.physics->position.y = y;
player.physics->next_position = player.physics->position;
// friction (not in use)
player.physics->glob_friction = 40; // drag coef * area
// collisions
player.physics->obj_elasticity = 0.7;
player.physics->collision_poly = calloc(4, sizeof(Vect));
player.physics->collision_poly_size = 4 + 4;
player.physics->collision_poly = calloc(player.physics->collision_poly_size, sizeof(Vect));
player.physics->collision_shape_size = 4;
player.physics->collision_shape = calloc(4, sizeof(Vect));
player.physics->collision_poly_size = 4;
player.physics->updateCollisionPoly = cast_update_collision_poly;
Vect *rect = player.physics->collision_shape;
rect[0].x = -10; rect[0].y = -10;
rect[1].x = 10; rect[1].y = -10;
@ -504,7 +552,7 @@ int process_collisions(Body *thing, Vect *trans) { @@ -504,7 +552,7 @@ int process_collisions(Body *thing, Vect *trans) {
thing->colliding = true;
translation = vect_add(translation, temptrans);
}
} else if (world[k].kind == FLOOR) {
} else if (world[k].kind == FLOOR || world[k].kind == CEILING) {
for (int i = 0; i < world[k].floor->numPolys; i++) {
if ((world[k].floor->polys[i].physics->position.x - viewport_pos.x) > (2 *width)
|| (world[k].floor->polys[i].physics->position.x - viewport_pos.x) < -width) {
@ -546,13 +594,14 @@ void advance_thing(Body * thing) { @@ -546,13 +594,14 @@ void advance_thing(Body * thing) {
set_motor_newtons(thing, M_FRICTION, 0,0);
set_motor_max_velocity(thing, M_FRICTION, 0);
if (!thing->dynamics) {
return;
}
if (!thing->collision_poly[0].y) {
thing->updateCollisionPoly(thing);
}
if (!thing->dynamics) {
return;
}
thing->updateCollisionPoly(thing);
Vect translation;
@ -568,8 +617,8 @@ void advance_thing(Body * thing) { @@ -568,8 +617,8 @@ void advance_thing(Body * thing) {
/*translation.y *= -1;*/
/*}*/
thing->position.x += translation.x;
thing->position.y += translation.y;
thing->next_position.x += translation.x;
thing->next_position.y += translation.y;
translation.x = translation.x / mag;
translation.y = translation.y / mag;
@ -599,8 +648,8 @@ void advance_thing(Body * thing) { @@ -599,8 +648,8 @@ void advance_thing(Body * thing) {
// force
friction.x = friction.x * norm * fric_const;
friction.y = friction.y * norm * fric_const;
printf("friction accel: %e %e\n", friction.x, friction.y);
printf("velocity: %e %e\n", thing->vel.x, thing->vel.y);
// printf("friction accel: %e %e\n", friction.x, friction.y);
// printf("velocity: %e %e\n", thing->vel.x, thing->vel.y);
set_motor_newtons(thing, M_FRICTION, friction.x, friction.y);
set_motor_max_velocity(thing, M_FRICTION, vect_mag(project_vect(thing->vel, friction)));
@ -612,7 +661,6 @@ void advance_thing(Body * thing) { @@ -612,7 +661,6 @@ void advance_thing(Body * thing) {
/*rest.x = cos(vect_dir(translation)) * impulse;*/
/*rest.y = sin(vect_dir(translation)) * impulse;*/
/*accel_thing(thing, rest.x, rest.y);*/
}
uint32_t now = SDL_GetTicks();
@ -620,6 +668,7 @@ void advance_thing(Body * thing) { @@ -620,6 +668,7 @@ void advance_thing(Body * thing) {
uint32_t time_delta = now - thing->last_advance_time ;
thing->last_advance_time = SDL_GetTicks(); // in milliseconds
if (time_delta > 18) {
return;
logwrite(ERROR, "Simulation too slow\n");
}
@ -685,8 +734,9 @@ void advance_thing(Body * thing) { @@ -685,8 +734,9 @@ void advance_thing(Body * thing) {
double oldx = thing->position.x;
double oldy = thing->position.y;
thing->position.x += (thing->vel.x * 1/2 * (double)time_delta);
thing->position.y += (thing->vel.y * 1/2 * (double)time_delta);
thing->position = thing->next_position;
thing->next_position.x += (thing->vel.x * 1/2 * (double)time_delta);
thing->next_position.y += (thing->vel.y * 1/2 * (double)time_delta);
// revert if this caused collision
/*if (process_collisions(thing)) {*/
@ -730,6 +780,10 @@ void advance_things(void) { @@ -730,6 +780,10 @@ void advance_things(void) {
for (int k = 0; k < world[i].floor->numPolys; k++) {
advance_thing(world[i].floor->polys[k].physics);
}
case CEILING:
for (int k = 0; k < world[i].floor->numPolys; k++) {
advance_thing(world[i].floor->polys[k].physics);
}
}
}
}
@ -750,20 +804,27 @@ void add_to_world(world_thing thing) { @@ -750,20 +804,27 @@ void add_to_world(world_thing thing) {
}
void get_floor(void) {
int floorsize = 1000;
FloorPoly *polys = generate_floor_simple(floorsize);
void get_room(void) {
int floorsize = 100;
FloorPoly *polys = generate_floor_simple(floorsize, true, 1300);
Floor *floor = calloc(1, sizeof(Floor));
floor->polys = polys;
floor->numPolys = floorsize;
world_thing thing;
FloorPoly *ceil = generate_floor_simple(floorsize, false, 1000);
Floor* ceiling = calloc(1, sizeof(Floor));
ceiling->polys = ceil;
ceiling->numPolys = floorsize;
thing.kind = FLOOR;
thing.floor = floor;
world_thing ceilingthing;
ceilingthing.kind = CEILING;
ceilingthing.floor = ceiling;
add_to_world(ceilingthing);
add_to_world(thing);
world_thing floorthing;
floorthing.kind = FLOOR;
floorthing.floor = floor;
add_to_world(floorthing);
}
void startgame(SDL_Renderer * ren) {
@ -774,7 +835,7 @@ void startgame(SDL_Renderer * ren) { @@ -774,7 +835,7 @@ void startgame(SDL_Renderer * ren) {
memset(world, 0, sizeof(world_thing) * 100);
SDL_GetRendererOutputSize(ren, &width, &height);
player = get_player(20 * width,600);
player = get_player(500,500);
world_thing player_world;
@ -794,7 +855,7 @@ void startgame(SDL_Renderer * ren) { @@ -794,7 +855,7 @@ void startgame(SDL_Renderer * ren) {
viewport_pos.x = 700;
viewport_pos.y = 0;
get_floor();
get_room();
}
float get_abs(float x,float y) {

5
game.h

@ -20,7 +20,8 @@ enum motors { @@ -20,7 +20,8 @@ enum motors {
enum world_thing_kind {
PLAYER_W,
STATIC_WALL_W,
FLOOR
FLOOR,
CEILING
};
// used to exert a force on an object
@ -62,6 +63,7 @@ typedef struct BodyStruct{ @@ -62,6 +63,7 @@ typedef struct BodyStruct{
// SI Unit kinematics
/*------------------*/
Vect position;
Vect next_position; // used for casting collision
Vect vel;
Vect acc;
@ -84,6 +86,7 @@ typedef struct BodyStruct{ @@ -84,6 +86,7 @@ typedef struct BodyStruct{
Vect *collision_poly;
Vect *collision_shape;
int collision_poly_size;
int collision_shape_size;
void (*updateCollisionPoly)(struct BodyStruct *);

2
logger.c

@ -49,6 +49,8 @@ void logwrite(loggerlevel level, char message[]) { @@ -49,6 +49,8 @@ void logwrite(loggerlevel level, char message[]) {
case ERROR:
strcat(prepend, "ERROR");
break;
case SILENT:
return;
}
strcat(prepend, ": ");

Loading…
Cancel
Save