7 #include "./platforms.h"
11 #define PLAYER_WIDTH 50.0f
12 #define PLAYER_HEIGHT 50.0f
13 #define PLAYER_SPEED 500.0f
14 #define PLAYER_GRAVITY 1500.0f
25 static const vec_t opposing_rect_side_forces[RECT_SIDE_N] = {
26 { .x = 1.0f, .y = 0.0f }, /* RECT_SIDE_LEFT = 0, */
27 { .x = -1.0f, .y = 0.0f }, /* RECT_SIDE_RIGHT, */
28 { .x = 0.0f, .y = 1.0f, }, /* RECT_SIDE_TOP, */
29 { .x = 0.0f, .y = -1.0f, } /* RECT_SIDE_BOTTOM, */
32 static vec_t opposing_force_by_sides(int sides[RECT_SIDE_N])
34 vec_t opposing_force = {
39 for (rect_side_t side = 0; side < RECT_SIDE_N; ++side) {
43 opposing_rect_side_forces[side]);
47 return opposing_force;
50 player_t *create_player(float x, float y)
52 player_t *player = malloc(sizeof(player_t));
55 throw_error(ERROR_TYPE_LIBC);
59 player->position.x = x;
60 player->position.y = y;
61 player->velocity.x = 0.0f;
62 player->velocity.y = 0.0f;
63 player->movement.x = 0.0f;
64 player->movement.y = 0.0f;
65 player->height = PLAYER_HEIGHT;
66 player->width = PLAYER_WIDTH;
67 player->jump_count = 2;
72 player_t *create_player_from_stream(FILE *stream)
74 float x = 0.0f, y = 0.0f;
76 if (fscanf(stream, "%f%f", &x, &y) == EOF) {
77 throw_error(ERROR_TYPE_LIBC);
81 return create_player(x, y);
84 void destroy_player(player_t * player)
89 rect_t player_hitbox(const player_t *player)
92 .x = player->position.x - player->width / 2,
93 .y = player->position.y - player->height,
101 int render_player(const player_t * player,
102 SDL_Renderer *renderer,
103 const camera_t *camera)
109 if (SDL_SetRenderDrawColor(renderer, 96, 255, 96, 255) < 0) {
110 throw_error(ERROR_TYPE_SDL2);
113 rect_t player_object = player_hitbox(player);
116 return camera_fill_rect(camera, renderer, &player_object);
119 void update_player(player_t *player,
120 const platforms_t *platforms,
126 float d = (float) delta_time / 1000.0f;
128 player->velocity.y += PLAYER_GRAVITY * d;
129 player->position = vec_sum(
136 player->position.y = fmodf(player->position.y, 800.0f);
138 int sides[RECT_SIDE_N] = { 0, 0, 0, 0 };
140 platforms_rect_object_collide(platforms, player_hitbox(player), sides);
141 vec_t opposing_force = opposing_force_by_sides(sides);
143 if (sides[RECT_SIDE_BOTTOM]) {
144 player->jump_count = 2;
147 for (int i = 0; i < 1000 && vec_length(opposing_force) > 1e-6; ++i) {
148 player->position = vec_sum(
154 if (fabs(opposing_force.x) > 1e-6 && (opposing_force.x < 0.0f) != ((player->velocity.x + player->movement.x) < 0.0f)) {
155 player->velocity.x = 0.0f;
156 player->movement.x = 0.0f;
159 if (fabs(opposing_force.y) > 1e-6 && (opposing_force.y < 0.0f) != ((player->velocity.y + player->movement.y) < 0.0f)) {
160 player->velocity.y = 0.0f;
161 player->movement.y = 0.0f;
164 platforms_rect_object_collide(
166 player_hitbox(player),
168 opposing_force = opposing_force_by_sides(sides);
172 void player_move_left(player_t *player)
176 player->movement.x = -PLAYER_SPEED;
177 player->movement.y = 0.0f;
180 void player_move_right(player_t *player)
184 player->movement.x = PLAYER_SPEED;
185 player->movement.y = 0.0f;
188 void player_stop(player_t *player)
192 player->movement.x = 0.0f;
193 player->movement.y = 0.0f;
196 void player_jump(player_t *player)
200 if (player->jump_count > 0) {
201 player->velocity.y = -500.0f;
202 --player->jump_count;
206 void player_focus_camera(player_t *player,
212 camera_center_at(camera, player->position);