1
1
Fork 0
Browse Source

Add string winch

thread-physics
alistair 4 years ago
parent
commit
c062f3d501
  1. 1
      controlscheme.c
  2. 1
      controlscheme.h
  3. 145
      game.c
  4. 9
      game.h
  5. 2
      main.c
  6. 18
      vect.c
  7. 10
      vect.h

1
controlscheme.c

@ -9,5 +9,6 @@ void get_input_map(void) { @@ -9,5 +9,6 @@ void get_input_map(void) {
input_map.player_right = SDL_SCANCODE_D;
input_map.player_left = SDL_SCANCODE_A;
input_map.player_rope = SDL_SCANCODE_E;
input_map.player_pull_rope = SDL_SCANCODE_Q;
}

1
controlscheme.h

@ -13,6 +13,7 @@ struct InputMap { @@ -13,6 +13,7 @@ struct InputMap {
SDL_Scancode player_left;
SDL_Scancode player_right;
SDL_Scancode player_rope;
SDL_Scancode player_pull_rope;
};
extern struct InputMap input_map;

145
game.c

@ -1,4 +1,6 @@ @@ -1,4 +1,6 @@
#include "game.h"
#define FLOOR_THICKNESS 200
player_st *glob_player;
/* array of all the things in the world and their kinds */
@ -20,6 +22,8 @@ player_st player; @@ -20,6 +22,8 @@ player_st 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);
void ratcheted_winch_motor_update(Motor* motor);
void winch_motor_update (struct motorstruct *motor);
// move the collision poly to the position of the player
void default_update_collision_poly(Body *body) {
@ -33,7 +37,6 @@ void default_update_collision_poly(Body *body) { @@ -33,7 +37,6 @@ void default_update_collision_poly(Body *body) {
}
}
// 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++) {
@ -60,7 +63,6 @@ void cast_update_collision_poly(Body *body) { @@ -60,7 +63,6 @@ void cast_update_collision_poly(Body *body) {
/*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)];*/
}
@ -70,7 +72,6 @@ void default_motor_curve(Motor *motor) { @@ -70,7 +72,6 @@ void default_motor_curve(Motor *motor) {
return;
}
#define FLOOR_THICKNESS 200
FloorPoly* generate_floor_simple(int num_polys, bool extend_down, int st_height) {
FloorPoly *floor = calloc(num_polys, sizeof(FloorPoly));
@ -218,7 +219,6 @@ player_st get_player(int x, int y) { @@ -218,7 +219,6 @@ player_st get_player(int x, int y) {
player.physics->strings = get_fixed_strings(1);
player.physics->strings->max_length = 210;
Vect *rect = player.physics->collision_shape;
rect[0].x = -10; rect[0].y = -10;
rect[1].x = 10; rect[1].y = -10;
@ -234,6 +234,10 @@ player_st get_player(int x, int y) { @@ -234,6 +234,10 @@ player_st get_player(int x, int y) {
set_motor_max_velocity(player.physics, M_PLAYER_WALK, 5); // has to be > grav
set_motor_max_velocity(player.physics, M_GRAVITY, 5);
// winch motor for string
add_motor(player.physics, 0.0, 0);
player.physics->motors[M_WINCH].update_motor = ratcheted_winch_motor_update;
return (player);
}
@ -558,12 +562,15 @@ void add_motor(Body *thing, double x, double y) { @@ -558,12 +562,15 @@ void add_motor(Body *thing, double x, double y) {
memset(&motor, 0, sizeof(Motor));
motor.x = x;
motor.y = y;
motor.stop = false;
motor.timeout = -1;
motor.max_velocity = 999899;
motor.update_motor = default_motor_curve;
motor.end_object = thing;
if (thing->num_motors == thing->max_motors) {
thing->motors = realloc(thing->motors, sizeof(Motor) * (thing->max_motors *=2));
}
@ -572,8 +579,71 @@ void add_motor(Body *thing, double x, double y) { @@ -572,8 +579,71 @@ void add_motor(Body *thing, double x, double y) {
thing->num_motors += 1;
}
void ratcheted_winch_motor_update(Motor* motor) {
Body *body = motor->end_object;
if (body->strings[0].max_length < 0.1
|| !body->strings[0].attached || motor->stop) {
motor->stop = true;
return;
}
winch_motor_update(motor);
Vect st;
st.x = body->position.x - body->strings[0].end_point.x;
st.y = body->position.y - body->strings[0].end_point.y;
body->strings[0].max_length = vect_mag(st);
}
void winch_motor_update (Motor* motor) {
Vect v;
v.x = motor->x;
v.y = motor->y;
double mod = vect_mag(v);
Body *body = motor->end_object;
uint32_t now = SDL_GetTicks();
if (body->strings[0].max_length < 0.1
|| !body->strings[0].attached) {
motor->stop = true;
return;
}
// set the motor direction to the string direction
Vect end_point = body->strings[0].end_point;
Vect start_point = body->position;
Vect dir = vect_add(end_point, vect_scalar(start_point, -1));
double arg = vect_arg(dir);
Vect force = vect_modarg(mod, arg);
motor->x = force.x;
motor->y = force.y;
}
void pull_rope(double newtons) {
if (!player.physics->strings[0].attached) {
return;
}
if (!player.physics->motors[M_WINCH].stop) {
return;
}
// set force
set_motor_newtons(player.physics, M_WINCH, 0, newtons);
// point it in the right direction
winch_motor_update(player.physics->motors + M_WINCH);
player.physics->motors[M_WINCH].stop = false;
}
void stop_pull_rope(void) {
player.physics->motors[M_WINCH].stop = true;
}
void add_rope(void) {
// testing
if (player.physics->strings[0].attached) {
return;
}
@ -585,7 +655,6 @@ void add_rope(void) { @@ -585,7 +655,6 @@ void add_rope(void) {
}
void delete_rope(void) {
// testing
player.physics->strings[0].attached = false;
}
@ -750,10 +819,6 @@ void advance_thing(Body * thing) { @@ -750,10 +819,6 @@ void advance_thing(Body * thing) {
thing->next_position.x += cos(angle) * disp;
thing->next_position.y += sin(angle) * disp;
/*Vect corrected_string;*/
/*corrected_string.x = cos(angle) * max_len;*/
/*corrected_string.y = sin(angle) * max_len;*/
// set velocity to 0 in direction of string
double corr_mag = vect_scalar_projection(thing->vel, string);
@ -765,17 +830,21 @@ void advance_thing(Body * thing) { @@ -765,17 +830,21 @@ void advance_thing(Body * thing) {
uint32_t now = SDL_GetTicks();
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");
thing->last_advance_time = now;
time_delta = 18;
}
printf("TimeDELTA: %d\n", time_delta);
// motors
for (int i = 0; i < thing->num_motors; i++) {
if (thing->motors[i].timeout < now) {
if (thing->motors[i].timeout < now
|| thing->motors[i].stop) {
continue;
}
if (thing->motors[i].update_motor) {
thing->motors[i].update_motor(thing->motors + i);
}
Vect F;
Vect V;
@ -799,7 +868,6 @@ void advance_thing(Body * thing) { @@ -799,7 +868,6 @@ void advance_thing(Body * thing) {
}
// accelerate based on accel
printf("time: %f", (float)time_delta);
thing->vel.x += thing->acc.x * (float)time_delta;
thing->vel.y += thing->acc.y * (float)time_delta;
@ -834,6 +902,7 @@ void advance_thing(Body * thing) { @@ -834,6 +902,7 @@ void advance_thing(Body * thing) {
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);
thing->last_advance_time = now; // in milliseconds
}
@ -988,6 +1057,8 @@ float get_abs(float x,float y) { @@ -988,6 +1057,8 @@ float get_abs(float x,float y) {
}
void walk_player(int x, int y) {
set_motor_newtons(player.physics, M_PLAYER_WALK, 0, 0);
if (y == -1) {
add_motor_newtons(glob_player->physics, M_PLAYER_WALK, 0, 100 * 10 * y);
return;
@ -996,43 +1067,37 @@ void walk_player(int x, int y) { @@ -996,43 +1067,37 @@ void walk_player(int x, int y) {
}
void handle_input_event(SDL_Event event) {
SDL_Scancode sc = event.key.keysym.scancode;
switch (event.type) {
case SDL_KEYDOWN:
if (event.key.keysym.scancode == input_map.player_rope) {
add_rope();
printf("add rope\n");
}
} if (sc == input_map.player_up) {
walk_player(0, -1);
} if ( sc == input_map.player_left) {
walk_player(-1, 0);
} if (sc == input_map.player_down) {
walk_player(0, 1);
} if (sc == input_map.player_right) {
walk_player(1, 0);
} if (sc == input_map.player_pull_rope) {
pull_rope(900);
}
break;
case SDL_KEYUP:
if (event.key.keysym.scancode == input_map.player_rope) {
delete_rope();
}
} if (sc == input_map.player_up || sc == input_map.player_down
|| sc == input_map.player_left
|| sc == input_map.player_right) {
set_motor_newtons(player.physics, M_PLAYER_WALK, 0, 0);
} if (sc == input_map.player_pull_rope) {
stop_pull_rope();
}
break;
}
}
void step(int interval) {
const uint8_t * keyboard;
keyboard = SDL_GetKeyboardState(NULL);
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_timeout(player.physics, M_PLAYER_WALK, SDL_GetTicks()+1000*2);
}
advance_things();
}

9
game.h

@ -15,7 +15,8 @@ @@ -15,7 +15,8 @@
enum motors {
M_GRAVITY = 0,
M_FRICTION = 1,
M_PLAYER_WALK = 2
M_PLAYER_WALK = 2,
M_WINCH = 3
};
enum world_thing_kind {
@ -35,11 +36,15 @@ typedef struct motorstruct { @@ -35,11 +36,15 @@ typedef struct motorstruct {
// does not apply force if the velocity in the
// direction of the motor vector is greater than
// max_velocity
uint32_t timeout;// absolute time (in ms, from when the program starts)
// for when the motor stops.
// for how long the motor runs before stopping
// automatically
// set to -1 for infinity
bool stop; // turn the motor off or on
void (*update_motor)(struct motorstruct *motor); // function pointer for generating
// the motor's output curve
struct BodyStruct *end_object;
} Motor;
typedef struct {

2
main.c

@ -26,8 +26,6 @@ struct SDL_Window* make_window(void) { @@ -26,8 +26,6 @@ struct SDL_Window* make_window(void) {
screen_width, screen_height, SDL_WINDOW_FULLSCREEN_DESKTOP);
}
void draw_pictures(struct SDL_Renderer * ren) {
logwrite(INFO, "Draw pictures\n");
// display an initial splash screen

18
vect.c

@ -16,6 +16,24 @@ Vect vect_scalar(Vect V, double s) { @@ -16,6 +16,24 @@ Vect vect_scalar(Vect V, double s) {
return ret;
}
double vect_arg(Vect v) {
return atan2(v.y, v.x);
}
Vect vect_modarg(double mod, double arg) {
Vect ret;
ret.x = mod * cos(arg);
ret.y = mod * sin(arg);
return ret;
}
Vect vect_rotate(Vect v, double radians) {
Vect res;
res.x = v.x * cos(radians) - v.y * sin(radians);
res.y = v.x * sin(radians) + v.y * cos(radians);
return res;
}
Vect vect_add(Vect v1, Vect v2) {
Vect res;

10
vect.h

@ -30,6 +30,16 @@ Vect project_vect(Vect one, Vect two); @@ -30,6 +30,16 @@ Vect project_vect(Vect one, Vect two);
/* Return the scalar projection of V onto P */
double vect_scalar_projection(Vect V, Vect P);
/* Return the vector v rotated by radians radians. */
Vect vect_rotate(Vect v, double radians);
/* Return the argument of v in radians */
double vect_arg(Vect v);
/* create a vector using modarg form */
Vect vect_modarg(double mod, double arg);
/* Return the distance between two point vectors A and B */
double vect_distance(Vect A, Vect B);
#endif

Loading…
Cancel
Save