#include #include #include #include #include "utils.h" #include "physics.h" #include "player.h" #define PLAYER_WIDTH 128 #define PLAYER_HEIGHT 128 #define COLLIDER_WIDTH 77 #define COLLIDER_HEIGHT 98 #define COLLIDER_XOFF 0 #define COLLIDER_YOFF 14 #define TOP_SPEEDX 100 #define TOP_SPEEDY 100 #define ACCEL_X 200 #define WALK_FRAME_TIME 0.2 extern Texture character_spritesheet; void add_player_animations(struct entity* player); void add_player(float xpos, float ypos) { struct entity player = { .flags = (ENTITY_ACTIVE | ENTITY_COLLISION_ACTIVE | ENTITY_VISIBLE | ENTITY_ANIMATED), .type = Player_Entity, .position = (Vector2) {xpos, ypos}, .texture = character_spritesheet, .sprite_source_rect = (Rectangle) { .x = 0, .y = 0, .width = 128, .height = 128 }, .collider = (Rectangle) { .x = -COLLIDER_WIDTH / 2 + COLLIDER_XOFF, .y = -COLLIDER_HEIGHT / 2 + COLLIDER_YOFF, .width = COLLIDER_WIDTH, .height = COLLIDER_HEIGHT }, .sprite_dest_rect = (Rectangle) { .x = -PLAYER_WIDTH / 2, .y = -PLAYER_HEIGHT / 2, .width = PLAYER_WIDTH, .height = PLAYER_HEIGHT }, .player_state = Player_Idle, .start_position = (Vector2) {xpos, ypos} }; add_player_animations(&player); add_entity(&player); } void player_accelerate(struct entity* player, float step) { if (IsKeyDown(KEY_A)) { player->velocity.x = fmaxf(player->velocity.x - step, -TOP_SPEEDX); } else if (IsKeyDown(KEY_D)) { player->velocity.x = fminf(player->velocity.x + step, TOP_SPEEDX); } else if (fabsf(player->velocity.x) > 0) { player->velocity.x = move_to(player->velocity.x, 0, step); } } void handle_movement(struct entity* player, float dt) { player_accelerate(player, ACCEL_X * dt * 0.5); player->velocity.y += GRAVITY * 0.5 * dt; move_and_collide(player, dt); player_accelerate(player, ACCEL_X * dt * 0.5); player->velocity.y += GRAVITY * 0.5 * dt; } void jump(struct entity* player) { player->velocity.y = -200; if (IsKeyDown(KEY_A) && player->velocity.x > 0) player->velocity.x = 0; else if (IsKeyDown(KEY_D) && player->velocity.x < 0) player->velocity.x = 0; } void handle_input(struct entity* player) { if (IsKeyPressed(KEY_SPACE) && player->player_state == Player_Idle) { jump(player); } } void reset_position(struct entity* player) { player->position = player->start_position; } void handle_fall(struct entity* player) { if (player->position.y > WINDOW_HEIGHT + 100) reset_position(player); } void handle_flip(struct entity* player) { if (IsKeyDown(KEY_A)) { player->flip = true; } else if (IsKeyDown(KEY_D)){ player->flip = false; } } void update_player(struct entity* player, float dt) { //Collision unsets it I didn't find a better way to do this //with the current setup player->player_state = Player_Air; handle_movement(player, dt); handle_input(player); handle_fall(player); handle_flip(player); update_animation(&player->animations[player->current_animation], dt); } void player_handle_collision ( struct entity* player, struct entity* other, enum direction collision_direction ) { switch (other->type) { case Wall_Entity: if (collision_direction == Direction_Left || collision_direction == Direction_Right) { player->velocity.x = 0.0; } else if (collision_direction == Direction_Down || collision_direction == Direction_Up) { player->velocity.y = 0.0; } if (collision_direction == Direction_Down) { player->player_state = Player_Idle; } break; default: break; } } void add_player_animations(struct entity* player) { //Walking animation player->animations[0] = (struct animation) { .frame_count = 2, .is_looping = true, .source_rects = { {.x = 0, .y = 129, .width = 128, .height = 128}, {.x = 129, .y = 129, .width = 128, .height = 128} }, .frame_times = {WALK_FRAME_TIME, WALK_FRAME_TIME} }; }