1
1
Fork 0
Browse Source

Applying forces is more solid, so gravity works now, and motors respect max-velocity, and there is support for variable motor output functions. However calculating the velocity of an object does not respect direction, so forces cannot be applied if the object is moving too fast either towards or away.

thread-physics
user 5 years ago
parent
commit
392ad5c018
  1. 7
      .gitignore
  2. 9
      Makefile
  3. 27
      draw.c
  4. 3
      draw.h
  5. 405
      game.c
  6. 43
      game.h
  7. 2
      logger.c
  8. 2
      main.c
  9. 1
      physics.c
  10. 0
      physics.h
  11. 41
      vect.c
  12. 30
      vect.h

7
.gitignore vendored

@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
not.md
sillystrings.c
sillystrings.h
debug.log
*.o
vgcore*

9
Makefile

@ -3,11 +3,10 @@ SDL_INCLUDE = -lSDL2 -lm -lSDL2_image @@ -3,11 +3,10 @@ SDL_INCLUDE = -lSDL2 -lm -lSDL2_image
CXXFLAGS = -Wall $(SDL_INCLUDE)
EXE = main
all: $(EXE)
$(EXE): main.o logger.o game.o garbo.o draw.o
$(CXX) $(CXXFLAGS) -o $(EXE) main.o game.o logger.o draw.o garbo.o
$(EXE): main.o vect.o logger.o game.o garbo.o draw.o
$(CXX) $(CXXFLAGS) -o $(EXE) main.o vect.o game.o logger.o draw.o garbo.o
main.o: main.c logger.h game.h garbo.h draw.h
$(CXX) $(CXXFLAGS) -c main.c
@ -24,8 +23,10 @@ garbo.o: garbo.c garbo.h @@ -24,8 +23,10 @@ garbo.o: garbo.c garbo.h
draw.o: draw.c draw.h
$(CXX) $(CXXFLAGS) -c draw.c
clean:
vect.o: vect.c vect.h
$(CXX) $(CXXFLAGS) -c vect.c
clean:
rm *.o && rm $(EXE)

27
draw.c

@ -55,11 +55,11 @@ void draw_player(SDL_Renderer * ren, int x, int y) { @@ -55,11 +55,11 @@ void draw_player(SDL_Renderer * ren, int x, int y) {
void draw_wall(SDL_Renderer *ren, Wall *wall) {
float x_st, x_en, y_st, y_en;
x_st = wall->nodes[0].physics.x_pos;
y_st = wall->nodes[0].physics.y_pos;
x_st = wall->nodes[0].x;
y_st = wall->nodes[0].y;
for (int i = 1; i < wall->numNodes; i++) {
x_en = wall->nodes[i].physics.x_pos;
y_en = wall->nodes[i].physics.y_pos;
x_en = wall->nodes[i].x;
y_en = wall->nodes[i].y;
printf("wall: %f %f %f %f\n", x_st, y_st, x_en, y_en);
SDL_SetRenderDrawColor(ren, 120, 85, 188, 255);
SDL_RenderDrawLine(ren, x_st, y_st, x_en, y_en);
@ -94,8 +94,6 @@ int distance_colour(int x, int y, int x2, int y2, int blackpoint) { @@ -94,8 +94,6 @@ int distance_colour(int x, int y, int x2, int y2, int blackpoint) {
void redraw_buffer(SDL_Renderer * ren) {
static int width = 0;
static int height = 0;
static int mousex = 0;
static int mousey = 0;
static int newmousex = 0;
@ -103,14 +101,13 @@ void redraw_buffer(SDL_Renderer * ren) { @@ -103,14 +101,13 @@ void redraw_buffer(SDL_Renderer * ren) {
static SDL_Point *bgPixels[256];
static int numpixels[256];
if (!width && !height) {
SDL_GetRendererOutputSize(ren, &width, &height);
for (int i = 0; i < 256; i++) {
bgPixels[i] = malloc(sizeof(SDL_Point) * width * height);
memset(bgPixels[i], 0, sizeof(SDL_Point) * width * height);
memset(numpixels, 0, (sizeof(int) * 256));
}
}
/*if (!width && !height) {*/
/*for (int i = 0; i < 256; i++) {*/
/*bgPixels[i] = malloc(sizeof(SDL_Point) * width * height);*/
/*memset(bgPixels[i], 0, sizeof(SDL_Point) * width * height);*/
/*memset(numpixels, 0, (sizeof(int) * 256));*/
/*}*/
/*}*/
int col = 0;
@ -123,6 +120,8 @@ void redraw_buffer(SDL_Renderer * ren) { @@ -123,6 +120,8 @@ void redraw_buffer(SDL_Renderer * ren) {
switch (thing.kind) {
case PLAYER:
newmousex = (*thing.player).physics->x_pos;
newmousey = (*thing.player).physics->y_pos;
draw_player(ren, (*thing.player).physics->x_pos, (*thing.player).physics->y_pos);
break;
case STATIC_WALL_W:

3
draw.h

@ -26,4 +26,7 @@ void add_to_view(draw_type kind, void * object); @@ -26,4 +26,7 @@ void add_to_view(draw_type kind, void * object);
void redraw_buffer(SDL_Renderer * ren);
int width, height;
#endif

405
game.c

@ -1,16 +1,34 @@ @@ -1,16 +1,34 @@
#include "game.h"
#include "vect.h"
#define GRAVITY_ACCEL 2
player_st *glob_player;
// @param uninitialised physics_thing pointer
void set_motor_newtons(Body *thing, int motorID, double x, double y);
void set_motor_max_velocity(Body *thing, int motorID, double max);
void default_update_collision_poly(Body *body) {
return;
}
// would probably be useful xd
enum collision_definition_type {
CIRCLE,
LINE,
CONVEX_POLY
};
void default_motor_curve(Motor *motor) {
// constant
return;
}
// @param uninitialised Body pointer
// @result: malloc and configure a physics thing pointer
void get_new_physics(physics_thing **phys) {
void get_new_physics(Body **phys) {
/* physics */
physics_thing * physics = malloc(sizeof(physics_thing));
memset(physics, 0, sizeof(physics_thing));
Body * physics = malloc(sizeof(Body));
memset(physics, 0, sizeof(Body));
physics->glob_gravity = false;
physics->glob_friction = 0.0000;
@ -24,7 +42,14 @@ void get_new_physics(physics_thing **phys) { @@ -24,7 +42,14 @@ void get_new_physics(physics_thing **phys) {
physics->num_motors = 0;
add_motor(physics, 0.0, 0.0);
*phys = physics;
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;
}
player_st get_player(int x, int y) {
@ -38,28 +63,28 @@ player_st get_player(int x, int y) { @@ -38,28 +63,28 @@ player_st get_player(int x, int y) {
player.physics->x_pos = x;
player.physics->y_pos = y;
player.physics->glob_friction = 40; // drag coef * area
player.physics->updateCollisionPoly = updatePlayerCollision;
add_motor(player.physics, 0.0, 0.0);
player.physics->collision_poly = calloc(1, sizeof(SDL_Point));
set_motor_newtons(player.physics, M_GRAVITY, 0.0, player.physics->obj_mass * 7);
// 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_GRAVITY, 5);
return (player);
}
wall_node get_wall_node(int x, int y) {
wall_node wn;
memset(&wn, 0, sizeof(wn));
wn.physics.x_pos = x;
wn.physics.y_pos = y;
wn.physics.x_acc = 0;
wn.physics.y_acc = 0;
wn.physics.obj_mass = 10;
wn.physics.glob_gravity = false;
wn.physics.glob_friction = 0.00000000;
wn.physics.x_vel = 0;
wn.physics.y_vel = 0;
wn.x = x;
wn.y = y;
return wn;
}
@ -78,62 +103,96 @@ Wall *get_stat_wall(int st_x, int st_y, int en_x, int en_y) { @@ -78,62 +103,96 @@ Wall *get_stat_wall(int st_x, int st_y, int en_x, int en_y) {
return wallwall;
}
void collision(int numNodes1, physics_thing *nodes1,
int numNodes2, physics_thing *nodes2) {
int x_1, y_1, x_2, y_2, xa_1, ya_1, xa_2, ya_2;
for (int i = 0; i < numNodes1; i++) {
x_1 = nodes1[2*i].x_pos;
y_1 = nodes1[2*i].y_pos;
x_2 = nodes1[2*i+1].x_pos;
y_2 = nodes1[2*i+1].y_pos;
for (int j = 0; j < numNodes2; j++) {
xa_1 = nodes2[2*j].x_pos;
ya_1 = nodes2[2*j].y_pos;
xa_2 = nodes2[2*j+1].x_pos;
ya_2 = nodes2[2*j+1].y_pos;
}
bool point_point_colcheck(SDL_Point one, SDL_Point two) {
if (one.x == two.x && one.y == two.y) {
return true;
}
return false;
}
physics_thing *get_player_collision_test(physics_thing *player) {
physics_thing up, right;
physics_thing *nodes = malloc(sizeof(physics_thing) * 2);
typedef struct {
Vect one;
Vect two;
} Collision;
up = *player;
right = *player;
bool point_line_colcheck(SDL_Point line[2], SDL_Point point) {
up.y_pos += 1;
right.x_pos += 1;
// 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)
|| (point.y > line[0].y && point.y > line[0].y)
|| (point.y < line[0].y && point.y < line[0].y)
){
return false;
}
nodes[0] = up;
nodes[1] = right;
double m = (double)(line[1].y - line[0].y) / (double)(line[1].x - line[0].x);
double c = (double)(line[0].y - (m * line[0].x));
double y = point.x * m + c;
// point is in the line +- 1
if ((int)y == point.y || ((int)y < point.y && (int)y + 1 > point.y)) {
return true;
}
return nodes;
return false;
}
void check_collision(int numNodes, physics_thing *things) {
for (int i = 0; i < things_in_world; i++) {
world_thing worldThing = world[i];
Wall *wall;
physics_thing *nodes;
if (worldThing.collisions) {
switch (worldThing.kind) {
case PLAYER_W:
collision(2, get_player_collision_test(things), 1, worldThing.player->physics);
break;
case STATIC_WALL_W:
wall = worldThing.wall;
nodes = malloc(sizeof(physics_thing) * wall->numNodes);
for (int i = 0; i < wall->numNodes; i++) {
nodes[i] = wall->nodes[i].physics;
}
collision(numNodes, things, wall->numNodes, nodes);
free(nodes);
break;
}
bool route_collision(Body *one, Body *two) {
int onesize = one->collison_poly_size;
int twosize = two->collison_poly_size;
// point-point
if (one->collison_poly_size == 1 && two->collison_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];
SDL_Point point;
if (onesize > twosize) {
line[0] = one->collision_poly[0];
line[1] = one->collision_poly[1];
point = two->collision_poly[0];
} else {
line[0] = two->collision_poly[0];
line[1] = two->collision_poly[1];
point = one->collision_poly[0];
}
return point_line_colcheck(line, point);
}
// line-line
if ((onesize == 2 && twosize == 2)) {
return false;
}
// point-poly
if ((onesize == 1 || twosize == 1) && (onesize > 2 || twosize > 2)) {
return false;
}
// line-poly
if ((onesize == 2 || twosize == 2) && (onesize > 2 || twosize > 2)) {
return false;
}
// poly-poly
if ((onesize > 2 && twosize > 2)) {
return false;
}
}
bool check_collision(Body *one, Body *two) {
return route_collision(one, two);
}
Wall *get_long_wall(int numNodes, int *nodes) {
@ -142,10 +201,15 @@ Wall *get_long_wall(int numNodes, int *nodes) { @@ -142,10 +201,15 @@ Wall *get_long_wall(int numNodes, int *nodes) {
wall.numNodes = numNodes;
wall.nodes = malloc(sizeof(wall_node) * numNodes);
wall.physics = calloc(1, sizeof(Body));
wall.physics->collision_poly = calloc(numNodes, sizeof(SDL_Point));
// 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]);
//set_motor_ms(&(wall.nodes[i].physics), 2.0 , 1.0);
wall.physics->collision_poly[i].x = nodes[2*i];
wall.physics->collision_poly[i].y = nodes[2*i+1];
}
Wall *wallwall = malloc(sizeof(wall));
@ -153,7 +217,7 @@ Wall *get_long_wall(int numNodes, int *nodes) { @@ -153,7 +217,7 @@ Wall *get_long_wall(int numNodes, int *nodes) {
return wallwall;
}
void accel_thing(physics_thing * thing, float x, float y) {
void accel_thing(Body * thing, float x, float y) {
/* takes acceleration in m/s2 and converts to m/ms adding
* it to physics_thing
*/
@ -169,24 +233,37 @@ void accel_thing(physics_thing * thing, float x, float y) { @@ -169,24 +233,37 @@ void accel_thing(physics_thing * thing, float x, float y) {
}
void set_motor_newtons(physics_thing *thing, int motorID, double x, double y) {
void set_motor_max_velocity(Body *thing, int motorID, double max) {
thing->motors[motorID].max_velocity = max;
}
void set_motor_ttl(Body *thing, int motorID, double ttl) {
thing->motors[motorID].TTL = ttl;
}
void set_motor_newtons(Body *thing, int motorID, double x, double y) {
thing->motors[motorID].x =x;
thing->motors[motorID].y =y;
}
void add_motor_newtons(physics_thing *thing, int motorID, double x, double y) {
void add_motor_newtons(Body *thing, int motorID, double x, double y) {
thing->motors[motorID].x +=x;
thing->motors[motorID].y +=y;
}
void add_motor(physics_thing *thing, double x, double y) {
// @param thing: the body to apply the motor to
// @param x, y: The initial motor force vector.
void add_motor(Body *thing, double x, double y) {
Motor motor;
memset(&motor, 0, sizeof(Motor));
motor.x = x;
motor.y = y;
motor.TTL = INFINITY;
motor.max_velocity = 999899;
motor.update_motor = default_motor_curve;
if (thing->num_motors == thing->max_motors) {
thing->motors = realloc(thing->motors, sizeof(Motor) * (thing->max_motors *=2));
}
@ -195,100 +272,112 @@ void add_motor(physics_thing *thing, double x, double y) { @@ -195,100 +272,112 @@ void add_motor(physics_thing *thing, double x, double y) {
thing->num_motors += 1;
}
/* Basic physics works by adding up the acceleratino caused by all the forces on
* the object, converting it to velocity, then doing collision detection and
* applying various reactive forces (friction etc) and finally adjusting the
* object's position.
*/
void advance_thing(Body * thing) {
thing->x_acc = 0;
thing->y_acc = 0;
int advance_glob(physics_thing * thing) {
logwrite(DEBUG, "Global physics\n");
// gravity
if ((*thing).glob_gravity == true) {
accel_thing(thing, 0, GRAVITY_ACCEL);
}
thing->updateCollisionPoly(thing);
// friction
uint32_t time_delta = SDL_GetTicks() - thing->last_advance_time ;
thing->last_advance_time = SDL_GetTicks(); // in milliseconds
time_delta = 17;
if ((*thing).glob_friction != 0.0) {
logwrite(DEBUG, "Friction\n");
float normal = (*thing).obj_mass * 9.81;
float F_force = normal * (*thing).glob_friction;
float dir = atan2((*thing).y_vel, (*thing).x_vel);
dir += M_PI;
// motors
for (int i = 0; i < thing->num_motors; i++) {
float f_x = (float)(cos((double)dir)) * F_force;
float f_y = (float)(sin((double)dir)) * F_force;
Vect F;
Vect V;
F.x = thing->motors[i].x;
F.y = thing->motors[i].y;
V.x = thing->x_vel;
V.y = thing->y_vel;
printf("Friction %f, %f", f_x, f_y);
Vect vel_in_dir = project_vect(V, F);
if (fabs((*thing).x_vel) > 0.0000001) {
(*thing).x_acc += f_x;
if (thing->motors[i].TTL <= 0) {
continue;
}
if (fabs((*thing).y_vel) > 0.0000001) {
(*thing).y_acc += f_y;
if (thing->motors[i].TTL != INFINITY) {
thing->motors[i].TTL--;
}
/*if (fabs((*thing).x_acc ) < fabs(f_x)) {*/
/*(*thing).x_acc = 0;*/
/*}*/
/*else {*/
/*(*thing).x_acc += f_x;*/
/*}*/
/*if (fabs((*thing).y_acc) < fabs(f_y)) {*/
/*(*thing).y_acc = 0;*/
/*}*/
/*else {*/
/*(*thing).y_acc += f_y;*/
/*}*/
if (thing->motors[i].max_velocity > vect_mag(vel_in_dir)) {
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);
}
}
}
void advance_thing(physics_thing * thing) {
thing->x_acc = 0;
thing->y_acc = 0;
uint32_t time_delta = SDL_GetTicks() - thing->last_advance_time ;
thing->last_advance_time = SDL_GetTicks(); // in milliseconds
// accelerate based on accel
printf("time: %f", (float)time_delta);
thing->x_vel += thing->x_acc * (float)time_delta;
thing->y_vel += thing->y_acc * (float)time_delta;
double velocity = sqrt((double)(thing->x_vel * thing->x_vel + thing->y_vel * thing->y_vel));
printf("\nvels %e %e\n\n", thing->x_vel, thing->y_vel);
for (int i = 0; i < thing->num_motors; i++) {
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);
}
// simple air drag
// motor
//float motor_x = (float)(*thing).motor_x / (float)(*thing).obj_mass ;
//float motor_y = (float)(*thing).motor_y / (float)(*thing).obj_mass ;
//printf("MOTOR: %f, %f\n", motor_x, motor_y);
//accel_thing(thing, motor_x, motor_y);
/*if (velocity > 0.000000000000000) {*/
/*double dir = atan2((double)thing->y_vel, (double)thing->x_vel) + M_PI;*/
advance_glob(thing);
/*double absolute_force = 5 * thing->obj_mass * (velocity / time_delta); // 2 * 0.1231 * 5;*/
/*printf("dir %e %e\n\n", dir, dir - M_PI);*/
/*printf("force %e\n\n", absolute_force);*/
// accelerate based on accel
/*double f_x = (cos(dir)) * absolute_force;*/
/*double f_y = (sin(dir)) * absolute_force;*/
printf("time: %f", (float)time_delta);
(*thing).x_vel = (*thing).x_acc * (float)time_delta;
(*thing).y_vel = (*thing).y_acc * (float)time_delta;
/*accel_thing(thing, (float)f_x, (float)f_y);*/
/*}*/
if (fabs((*thing).x_vel) < 0.00001) {
(*thing).x_vel = 0;
}
if (fabs((*thing).y_vel) < 0.00001) {
(*thing).y_vel = 0;
}
(*thing).x_pos += (int)((*thing).x_vel * 1/2 * (float)time_delta);
(*thing).y_pos += (int)((*thing).y_vel * 1/2 * (float)time_delta);
printf("player position: %d, %d ", (*thing).x_pos, (*thing).y_pos );
printf(" player acc: %f, %f \n", (*thing).x_acc, (*thing).y_acc);
// wrap screen
if (thing->x_pos > width) {
thing->x_pos = 0;
}
if (thing->y_pos > height) {
thing->y_pos = 0;
}
if (thing->y_pos < 0) {
thing->y_pos = height;
}
if (fabs((*thing).x_vel) < 0.00001) {
(*thing).x_vel = 0;
if (thing->x_pos < 0) {
thing->x_pos = width;
}
if (fabs((*thing).y_vel) < 0.00001) {
(*thing).y_vel = 0;
}
// basic collision handler
void handle_collisions(void) {
for (int k = 0; k < things_in_world; k++) {
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;
}
}
}
}
void advance_things(void) {
@ -296,20 +385,20 @@ void advance_things(void) { @@ -296,20 +385,20 @@ void advance_things(void) {
switch (world[i].kind) {
case PLAYER_W :
logwrite(INFO, "ADVANCE PLAYER\n");
handle_collisions();
advance_thing((world[i].player->physics));
break;
case STATIC_WALL_W:
logwrite(INFO, "ADVANCE WALL\n");
for (int j = 0; j < world[i].wall->numNodes; j++) {
advance_thing(&(world[i].wall->nodes[j].physics));
}
// advance_thing(world[i].wall->physics);
break;
}
}
}
// grow array of world things if needed
void add_to_world(world_thing thing) {
if (things_in_world == world_size) {
logwrite(INFO, "Increased world size.");
world = realloc(world, sizeof(world_thing) * (world_size*=2));
@ -330,6 +419,7 @@ void startgame(SDL_Renderer * ren) { @@ -330,6 +419,7 @@ void startgame(SDL_Renderer * ren) {
world_size = 100;
world = malloc(sizeof(world_thing) * 100);
memset(world, 0, sizeof(world_thing) * 100);
SDL_GetRendererOutputSize(ren, &width, &height);
player = get_player(100,400);
@ -346,11 +436,6 @@ void startgame(SDL_Renderer * ren) { @@ -346,11 +436,6 @@ void startgame(SDL_Renderer * ren) {
int wall_nodes[] = {500, 100, 200, 100, 100, 200, 900, 200};
wall_world.wall = get_long_wall(4, wall_nodes);
wall_world.kind = STATIC_WALL_W;
printf("WALLNODES");
for (int i = 0; i < 4; i++) {
printf(": %d", wall_world.wall->nodes[i].physics.x_pos);
}
printf("\n\n\n\n");
add_to_world(wall_world);
}
@ -359,36 +444,38 @@ float get_abs(float x,float y) { @@ -359,36 +444,38 @@ float get_abs(float x,float y) {
}
void walk_player(int x, int y) {
if (y == -1) {
add_motor_newtons(glob_player->physics, M_PLAYER_WALK, 0, 100 * 10 * y);
return;
}
add_motor_newtons(glob_player->physics, M_PLAYER_WALK, 100 * x , 100 * y);
}
void process_keydown(SDL_Keysym key) {
}
void process_keyup(SDL_Keysym key) {
}
void step(int interval) {
const uint8_t * keyboard;
printf("THINGS IN WORLD: %d\n", things_in_world);
keyboard = SDL_GetKeyboardState(NULL);
//set_motor_ms(&player.physics, 0 ,0);
//
set_motor_newtons(player.physics, M_PLAYER_WALK, 0, 0);
if (keyboard[SDL_SCANCODE_W]) {
walk_player(0, -1);
} if (keyboard[SDL_SCANCODE_SPACE]) {
walk_player(0, -1);
} if (keyboard[SDL_SCANCODE_A]) {
walk_player(-1, 0);
} if (keyboard[SDL_SCANCODE_S]) {
walk_player(0, 1);
} if (keyboard[SDL_SCANCODE_D]) {
walk_player(1, 0);
} if (!keyboard[SDL_SCANCODE_W]
&& !keyboard[SDL_SCANCODE_A]
&& !keyboard[SDL_SCANCODE_S]
&& !keyboard[SDL_SCANCODE_D]) {
set_motor_ttl(player.physics, M_PLAYER_WALK, 90);
}
advance_things();
logwrite(DEBUG, "Update Physics \n");
}

43
game.h

@ -12,30 +12,33 @@ @@ -12,30 +12,33 @@
#include "garbo.h"
#include "draw.h"
typedef union {
struct {
float x;
float y;
float z;
};
float vect[3];
} vector;
enum motors {
M_GRAVITY = 0,
M_PLAYER_WALK = 1
};
// Exert a force on an object
typedef struct {
// used to exert a force on an object
typedef struct motorstruct {
double x; // positive is right
double y; // positive is down
double torque; // positive is anticlockwise
double max_velocity; // max motor output velocity
// does not apply force if the velocity in the
// direction of the motor vector is greater than
// max_velocity
int TTL; // motor dies after this expires.
// units are simulation tick
void (*update_motor)(struct motorstruct *motor); // function pointer for generating
// the motor's output curve
} Motor;
typedef struct {
double x;
double y;
} Point;
typedef struct BodyStruct{
int x_pos;
int y_pos;
@ -45,12 +48,15 @@ typedef struct { @@ -45,12 +48,15 @@ typedef struct {
float x_acc;
float y_acc;
// properties
// collisions
SDL_Point *collision_poly;
int collison_poly_size;
void (*updateCollisionPoly)(struct BodyStruct *);
// properties
float obj_mass; // kgs
// fields
float glob_friction;
bool glob_gravity; // t/f
@ -59,23 +65,24 @@ typedef struct { @@ -59,23 +65,24 @@ typedef struct {
int num_motors;
int max_motors;
Motor *motors;
} physics_thing;
} Body;
typedef struct {
bool has_physics;
physics_thing *physics;
Body *physics;
int max_walking_speed;
} player_st;
typedef struct {
bool has_physics;
physics_thing physics;
int x;
int y;
//void setup(struct stat_wall_st *self);
} wall_node;
typedef struct {
int numNodes;
wall_node *nodes;
Body *physics;
} Wall;
enum world_thing_kind {
@ -111,5 +118,5 @@ void step(int interval); @@ -111,5 +118,5 @@ void step(int interval);
player_st player;
void add_motor(physics_thing *thing, double x, double y);
void add_motor(Body *thing, double x, double y);
#endif

2
logger.c

@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
// Defaults
loggerlevel LOGLEVEL = WARN;
loggerlevel LOGLEVEL = SILENT;
loggerlevel STDOUTLEVEL = WARN;
void set_loglevel(loggerlevel echo, loggerlevel write) {

2
main.c

@ -76,7 +76,7 @@ int main () { @@ -76,7 +76,7 @@ int main () {
int close = 0;
draw_pictures(ren);
//draw_pictures(ren);
bool once = true;
startgame(ren);

1
physics.c

@ -0,0 +1 @@ @@ -0,0 +1 @@
#include "physics.h"

41
vect.c

@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
#include "vect.h"
double vect_dot(Vect V, Vect B) {
return V.x * B.x + V.y * B.y;
}
double vect_mag(Vect v) {
double mag = sqrt((v.x * v.x) + (v.y * v.y));
return mag;
}
Vect vect_scalar(Vect V, double s) {
Vect ret;
ret.x = V.x * s;
ret.y = V.y * s;
return ret;
}
Vect vect_add(Vect v1, Vect v2) {
Vect res;
res.x = v1.x + v2.x;
res.y = v1.y + v2.y;
return res;
}
Vect project_vect(Vect one, Vect two) {
// $$ a \cdot \frac {|b|} {b} $$
Vect unittwo;
unittwo.x = two.x / vect_mag(two);
unittwo.y = two.y / vect_mag(two);
Vect proj;
proj.x = unittwo.x * one.x;
proj.y = unittwo.y * one.y;
return proj;
}
double vect_dir(Vect V) {
return atan2(V.y, V.x);
}

30
vect.h

@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
#include <math.h>
#ifndef VECT_H
#define VECT_H
// origin-centred vector
typedef struct {
double x;
double y;
} Vect;
/* Return the magnitude of two vectors */
double vect_mag(Vect v);
/* Return the angle of a vector in radians (using atan2) */
double vect_dir(Vect V);
/* Return the dot product of two vectors */
double vect_dot(Vect V, Vect B);
/* return a vector multiplied by a scalar */
Vect vect_scalar(Vect V, double s);
/* Return the sum of two vectors */
Vect vect_add(Vect v1, Vect v2);
/* Return the projection of vector one onto vector two */
Vect project_vect(Vect one, Vect two);
#endif
Loading…
Cancel
Save