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_JUMP 550.0f
15 #define PLAYER_GRAVITY 1500.0f
26 static const vec_t opposing_rect_side_forces[RECT_SIDE_N] = {
27 { .x = 1.0f, .y = 0.0f }, /* RECT_SIDE_LEFT = 0, */
28 { .x = -1.0f, .y = 0.0f }, /* RECT_SIDE_RIGHT, */
29 { .x = 0.0f, .y = 1.0f, }, /* RECT_SIDE_TOP, */
30 { .x = 0.0f, .y = -1.0f, } /* RECT_SIDE_BOTTOM, */
33 static vec_t opposing_force_by_sides(int sides[RECT_SIDE_N])
35 vec_t opposing_force = {
40 for (rect_side_t side = 0; side < RECT_SIDE_N; ++side) {
44 opposing_rect_side_forces[side]);
48 return opposing_force;
51 player_t *create_player(float x, float y)
53 player_t *player = malloc(sizeof(player_t));
56 throw_error(ERROR_TYPE_LIBC);
60 player->position.x = x;
61 player->position.y = y;
62 player->velocity.x = 0.0f;
63 player->velocity.y = 0.0f;
64 player->movement.x = 0.0f;
65 player->movement.y = 0.0f;
66 player->height = PLAYER_HEIGHT;
67 player->width = PLAYER_WIDTH;
68 player->jump_count = 2;
73 player_t *create_player_from_stream(FILE *stream)
75 float x = 0.0f, y = 0.0f;
77 if (fscanf(stream, "%f%f", &x, &y) == EOF) {
78 throw_error(ERROR_TYPE_LIBC);
82 return create_player(x, y);
85 void destroy_player(player_t * player)
90 rect_t player_hitbox(const player_t *player)
93 .x = player->position.x - player->width / 2,
94 .y = player->position.y - player->height,
102 int render_player(const player_t * player,
103 SDL_Renderer *renderer,
104 const camera_t *camera)
110 if (SDL_SetRenderDrawColor(renderer, 96, 255, 96, 255) < 0) {
111 throw_error(ERROR_TYPE_SDL2);
114 rect_t player_object = player_hitbox(player);
117 return camera_fill_rect(camera, renderer, &player_object);
120 void update_player(player_t *player,
121 const platforms_t *platforms,
127 float d = (float) delta_time / 1000.0f;
129 player->velocity.y += PLAYER_GRAVITY * d;
130 player->position = vec_sum(
137 player->position.y = fmodf(player->position.y, 800.0f);
139 int sides[RECT_SIDE_N] = { 0, 0, 0, 0 };
141 platforms_rect_object_collide(platforms, player_hitbox(player), sides);
142 vec_t opposing_force = opposing_force_by_sides(sides);
144 if (sides[RECT_SIDE_BOTTOM]) {
145 player->jump_count = 2;
148 for (int i = 0; i < 1000 && vec_length(opposing_force) > 1e-6; ++i) {
149 player->position = vec_sum(
155 if (fabs(opposing_force.x) > 1e-6 && (opposing_force.x < 0.0f) != ((player->velocity.x + player->movement.x) < 0.0f)) {
156 player->velocity.x = 0.0f;
157 player->movement.x = 0.0f;
160 if (fabs(opposing_force.y) > 1e-6 && (opposing_force.y < 0.0f) != ((player->velocity.y + player->movement.y) < 0.0f)) {
161 player->velocity.y = 0.0f;
162 player->movement.y = 0.0f;
165 platforms_rect_object_collide(
167 player_hitbox(player),
169 opposing_force = opposing_force_by_sides(sides);
173 void player_move_left(player_t *player)
177 player->movement.x = -PLAYER_SPEED;
178 player->movement.y = 0.0f;
181 void player_move_right(player_t *player)
185 player->movement.x = PLAYER_SPEED;
186 player->movement.y = 0.0f;
189 void player_stop(player_t *player)
193 player->movement.x = 0.0f;
194 player->movement.y = 0.0f;
197 void player_jump(player_t *player)
201 if (player->jump_count > 0) {
202 player->velocity.y = -PLAYER_JUMP;
203 --player->jump_count;
207 void player_focus_camera(player_t *player,
213 camera_center_at(camera, vec_sum(player->position, vec(0.0f, -player->height * 0.5f)));
216 void player_hide_goals(const player_t *player,
221 goals_hide(goals, player->position);