X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fplayer.c;h=7e1a1a7717f4b1e6d4d4d39f733f4d0aa86b03b8;hb=5af75a0cd35d57d9de638d886f826ac4764c8697;hp=71270255b05a677d0aabc9ba1bcabfd8aaaa9ffb;hpb=0ffa4ece0d16281c1a423c7f89bddcdb762e4a83;p=nothing.git diff --git a/src/player.c b/src/player.c index 71270255..7e1a1a77 100644 --- a/src/player.c +++ b/src/player.c @@ -1,37 +1,68 @@ +#include #include #include #include #include "./player.h" #include "./platforms.h" +#include "./point.h" +#include "./error.h" #define PLAYER_WIDTH 50.0f #define PLAYER_HEIGHT 50.0f #define PLAYER_SPEED 500.0f #define PLAYER_GRAVITY 1500.0f +#define PLAYER_INFLATION 100.0f struct player_t { vec_t position; vec_t velocity; vec_t movement; + float height; + float width; }; -/* static const vec_t impact_vecs[RECT_SIDE_N] = { */ -/* /\* left *\/ */ -/* { .x = 1.0f, .y = 0.0f }, */ -/* /\* right *\/ */ -/* { .x = -1.0f, .y = 0.0f }, */ -/* /\* top *\/ */ -/* { .x = 0.0f, .y = 1.0f }, */ -/* /\* bottom *\/ */ -/* { .x = 0.0f, .y = -1.0f } */ -/* }; */ +static const vec_t opposing_rect_side_forces[RECT_SIDE_N] = { + { .x = 1.0f, .y = 0.0f }, /* RECT_SIDE_LEFT = 0, */ + { .x = -1.0f, .y = 0.0f }, /* RECT_SIDE_RIGHT, */ + { .x = 0.0f, .y = 1.0f, }, /* RECT_SIDE_TOP, */ + { .x = 0.0f, .y = -1.0f, } /* RECT_SIDE_BOTTOM, */ +}; + +static vec_t opposing_force_by_sides(int sides[RECT_SIDE_N]) +{ + vec_t opposing_force = { + .x = 0.0f, + .y = 0.0f + }; + + for (rect_side_t side = 0; side < RECT_SIDE_N; ++side) { + if (sides[side]) { + vec_add( + &opposing_force, + opposing_rect_side_forces[side]); + } + } + + return opposing_force; +} + +static int squishing_horizontal_force(int sides[RECT_SIDE_N]) +{ + return sides[RECT_SIDE_LEFT] && sides[RECT_SIDE_RIGHT]; +} + +static int squishing_vertical_force(int sides[RECT_SIDE_N]) +{ + return sides[RECT_SIDE_TOP] && sides[RECT_SIDE_BOTTOM]; +} player_t *create_player(float x, float y) { player_t *player = malloc(sizeof(player_t)); if (player == NULL) { + throw_error(ERROR_TYPE_LIBC); return NULL; } @@ -41,6 +72,8 @@ player_t *create_player(float x, float y) player->velocity.y = 0.0f; player->movement.x = 0.0f; player->movement.y = 0.0f; + player->height = PLAYER_HEIGHT; + player->width = PLAYER_WIDTH; return player; } @@ -50,86 +83,142 @@ void destroy_player(player_t * player) free(player); } +rect_t player_hitbox(const player_t *player) +{ + rect_t hitbox = { + .x = player->position.x - player->width / 2, + .y = player->position.y - player->height, + .w = player->width, + .h = player->height + }; + + return hitbox; +} + int render_player(const player_t * player, SDL_Renderer *renderer, const camera_t *camera) { + assert(player); + assert(renderer); + assert(camera); + if (SDL_SetRenderDrawColor(renderer, 96, 255, 96, 255) < 0) { + throw_error(ERROR_TYPE_SDL2); return -1; } - rect_t player_object = { - .x = player->position.x, - .y = player->position.y, - .w = PLAYER_WIDTH, - .h = PLAYER_HEIGHT - }; + rect_t player_object = player_hitbox(player); return camera_fill_rect(camera, renderer, &player_object); } -void update_player(player_t * player, +void update_player(player_t *player, const platforms_t *platforms, Uint32 delta_time) { + assert(player); + assert(platforms); + float d = (float) delta_time / 1000.0f; - float x = player->position.x; - float y = player->position.y; + player->velocity.y += PLAYER_GRAVITY * d; + player->position = vec_sum( + player->position, + vec_scala_mult( + vec_sum( + player->velocity, + player->movement), + d)); + player->position.y = fmodf(player->position.y, 800.0f); - rect_t player_object = { - .x = x + (player->velocity.x + player->movement.x) * d, - .y = y + (player->velocity.y + player->movement.y) * d, - .w = PLAYER_WIDTH, - .h = PLAYER_HEIGHT - }; + player->height = fminf(player->height + PLAYER_INFLATION * d, PLAYER_HEIGHT); + player->width = (PLAYER_WIDTH * PLAYER_HEIGHT) / player->height; - int sides[4] = {0, 0, 0, 0}; - platforms_rect_object_collide(platforms, &player_object, sides); + int sides[RECT_SIDE_N] = { 0, 0, 0, 0 }; - if (sides[RECT_SIDE_LEFT] || sides[RECT_SIDE_RIGHT]) { - player->velocity.x = 0.0f; - player->movement.x = 0.0f; - } + platforms_rect_object_collide(platforms, player_hitbox(player), sides); + vec_t opposing_force = opposing_force_by_sides(sides); - if (sides[RECT_SIDE_TOP] || sides[RECT_SIDE_BOTTOM]) { - player->velocity.y = 0.0f; - player->movement.y = 0.0f; + if (opposing_force.y < 0.0f && (player->velocity.y + player->movement.y) > 800.0f) { + player->height = PLAYER_HEIGHT / 2; } - player->position.x += (player->velocity.x + player->movement.x) * d; - player->position.y += (player->velocity.y + player->movement.y) * d; - player->velocity.y += PLAYER_GRAVITY * d; + for (int i = 0; i < 1000 + && (vec_length(opposing_force) > 1e-6 + || squishing_vertical_force(sides) + || squishing_horizontal_force(sides)); ++i) { + player->position = vec_sum( + player->position, + vec_scala_mult( + opposing_force, + 1e-2f)); + + if (fabs(opposing_force.x) > 1e-6 && (opposing_force.x < 0.0f) != ((player->velocity.x + player->movement.x) < 0.0f)) { + player->velocity.x = 0.0f; + player->movement.x = 0.0f; + } + + if (fabs(opposing_force.y) > 1e-6 && (opposing_force.y < 0.0f) != ((player->velocity.y + player->movement.y) < 0.0f)) { + player->velocity.y = 0.0f; + player->movement.y = 0.0f; + } + + if (squishing_vertical_force(sides)) { + player->height -= 1e-2f; + /* player->width = (PLAYER_WIDTH * PLAYER_HEIGHT) / player->height; */ + } + + if (squishing_horizontal_force(sides)) { + player->width -= 1e-2f; + /* player->height = (PLAYER_WIDTH * PLAYER_HEIGHT) / player->width; */ + } + + platforms_rect_object_collide( + platforms, + player_hitbox(player), + sides); + opposing_force = opposing_force_by_sides(sides); + } } void player_move_left(player_t *player) { + assert(player); + player->movement.x = -PLAYER_SPEED; player->movement.y = 0.0f; } void player_move_right(player_t *player) { + assert(player); + player->movement.x = PLAYER_SPEED; player->movement.y = 0.0f; } void player_stop(player_t *player) { + assert(player); + player->movement.x = 0.0f; player->movement.y = 0.0f; } void player_jump(player_t *player) { - player->velocity.y = -1000.0f; + assert(player); + + player->velocity.y = -500.0f; } void player_focus_camera(player_t *player, camera_t *camera) { - camera_translate(camera, - player->position.x - 800.0f * 0.5f + PLAYER_WIDTH * 0.5f, - player->position.y - 600.0f * 0.5f + PLAYER_HEIGHT * 0.5f); + assert(player); + assert(camera); + + camera_center_at(camera, player->position); }