From bb8164a07e966d343cd33dadd88b4fea841aec97 Mon Sep 17 00:00:00 2001 From: KikooDX Date: Thu, 4 Mar 2021 10:24:06 +0100 Subject: [PATCH] Level generation done, player code progress. --- include/conf.h | 4 +--- include/player.h | 24 +++++++++++++++++++++--- include/tiles.h | 4 ++-- kble.py | 2 +- src/level.c | 3 ++- src/player.c | 39 ++++++++++++++++++++++++++++++++------- src/tiles.c | 2 +- 7 files changed, 60 insertions(+), 18 deletions(-) diff --git a/include/conf.h b/include/conf.h index 99241d8..2b28028 100644 --- a/include/conf.h +++ b/include/conf.h @@ -13,6 +13,4 @@ #define LEVEL_HEIGHT 16 #define LEVEL_SIZE (LEVEL_WIDTH * LEVEL_HEIGHT) #define DRAW_OFFSET_X 70 -#define DRAW_OFFSET_Y 0 -#define PLAYER_WIDTH 12 -#define PLAYER_HEIGHT 12 +#define DRAW_OFFSET_Y -16 diff --git a/include/player.h b/include/player.h index 2a79598..caad457 100644 --- a/include/player.h +++ b/include/player.h @@ -11,9 +11,26 @@ #include "level.h" #include "input.h" +#define PLAYER_WIDTH 12 +#define PLAYER_HEIGHT 12 +#define GRAVITY 0.2 +#define JUMP_SPD -5.8 +#define JUMP_BUFFER 6 +#define COYOT 6 +#define FALL_RESISTANCE 0.04 +#define FASTFALL_RESISTANCE 0.01 +#define MAX_HORIZONTAL_SPEED 2.0 +#define GROUND_ACCELERATION 0.4 +#define AIR_ACCELERATION 1.0 +#define GROUND_FRICTION (GROUND_ACCELERATION / MAX_HORIZONTAL_SPEED) +#define AIR_FRICTION (AIR_ACCELERATION / MAX_HORIZONTAL_SPEED) +#define KNOCKBACK_Y (0 - JUMP_SPD + 2.0) +#define KNOCKBACK_X MAX_HORIZONTAL_SPEED + typedef struct Player{ Vec2 pos; - Vec2 spd; + float spd_x; + float spd_y; int8_t facing; bool stun; bool knocked; @@ -27,5 +44,6 @@ void player_update(Player *player, Level *level, Input input, uint8_t *level_id) void player_draw(Player player); /* Helper functions. */ bool player_collide(Level level, Vec2 pos, tile_t tile, uint8_t margin); -bool player_move(Player *player, Level level, vec2_int_t spd_x, vec2_int_t spd_y); -int8_t sign(vec2_int_t value); +bool player_move(Player *player, Level level, int8_t spd_x, int8_t spd_y); +int8_t sign(int8_t value); +int8_t round(float value); diff --git a/include/tiles.h b/include/tiles.h index d9e6665..c56eb94 100644 --- a/include/tiles.h +++ b/include/tiles.h @@ -8,13 +8,13 @@ typedef uint8_t tile_t; enum { - AIR_TILE, + AIR_TILE = 0, SOLID_TILE, PAIN_TILE, SPAWN_TILE, EXIT_TILE, KEY_TILE, - SEMI_SOLID, + SEMI_SOLID_TILE, CHECKY_TILE, }; #define OUT_OF_BOUNDS AIR_TILE diff --git a/kble.py b/kble.py index 05b9c88..b0f2e57 100644 --- a/kble.py +++ b/kble.py @@ -103,7 +103,7 @@ if __name__ == "__main__": start_x, start_y = x, y c_file.write("},\n") c_file.write("\t\t.start_pos = (Vec2){") - c_file.write(f"{start_x}, {start_y}") + c_file.write(f"{start_x} * TILE_SIZE, {start_y} * TILE_SIZE") c_file.write("}\n\t},\n") c_file.write("};") diff --git a/src/level.c b/src/level.c index 843f256..9d409ab 100644 --- a/src/level.c +++ b/src/level.c @@ -8,6 +8,7 @@ #include #include "level.h" #include "tiles.h" +#include "conf.h" #include "vec2.h" void level_draw(Level level) { @@ -39,7 +40,7 @@ tile_t level_get_tile_at_px(Level level, Vec2 pos) { uint8_t x = pos.x / TILE_SIZE; uint8_t y = pos.y / TILE_SIZE; /* Out of bounds check. */ - if (pos.x >= LEVEL_WIDTH || pos.y >= LEVEL_HEIGHT) + if (pos.x >= LEVEL_WIDTH * TILE_SIZE || pos.y >= LEVEL_HEIGHT * TILE_SIZE) return OUT_OF_BOUNDS; /* If everything is OK, get the tile and return it. */ return level.content[x + y * LEVEL_WIDTH]; diff --git a/src/player.c b/src/player.c index eb5cba2..d990945 100644 --- a/src/player.c +++ b/src/player.c @@ -17,7 +17,8 @@ Player player_init() { return (Player){ .pos = (Vec2){}, - .spd = (Vec2){}, + .spd_x = 0.0, + .spd_y = 0.0, .facing = 1, .stun = false, .knocked = false, @@ -28,13 +29,34 @@ Player player_init() { } void player_update(Player *player, Level *level, Input input, uint8_t *level_id) { + const Vec2 one_px_down = (Vec2){player->pos.x, player->pos.y + 1}; + const bool on_ground = + player_collide(*level, one_px_down, SOLID_TILE, 0) || + player_collide(*level, one_px_down, SEMI_SOLID_TILE, 0); if (!player->stun) { /* Get input. */ const int8_t move_x = input_is_down(input, K_RIGHT) - input_is_down(input, K_LEFT); + const bool fastfall = input_is_down(input, K_DOWN); + const bool jump_pressed = input_is_pressed(input, K_JUMP); + const bool jump_held = input_is_down(input, K_JUMP); + /* Facing direction. */ + if (move_x != 0) + player->facing = move_x; + /* Friction. */ + if (on_ground) + player->spd_x *= 1 - GROUND_FRICTION; + else + player->spd_x *= 1 - AIR_FRICTION; + /* Acceleration. */ + if (on_ground) + player->spd_x += (float)(move_x) * GROUND_ACCELERATION; + else + player->spd_x += (float)(move_x) * AIR_ACCELERATION; /* Move the player. */ - if (move_x) player_move(player, *level, move_x, 0); + player_move(player, *level, round(player->spd_x), 0); + player_move(player, *level, 0, round(player->spd_y)); } } @@ -63,16 +85,15 @@ bool player_collide(Level level, Vec2 pos, tile_t tile, uint8_t margin) { (tile == level_get_tile_at_px(level, (Vec2){right, down}))); } -bool player_move(Player *player, Level level, vec2_int_t spd_x, vec2_int_t spd_y) -{ +bool player_move(Player *player, Level level, int8_t spd_x, int8_t spd_y) { player->pos.x += spd_x; player->pos.y += spd_y; /* If player is in solid, move back until it ain't. */ if (player_collide(level, player->pos, SOLID_TILE, 0)) { const uint8_t sign_spd_x = sign(spd_x); const uint8_t sign_spd_y = sign(spd_y); - if (sign_spd_x != 0) player->spd.x = 0; - if (sign_spd_y != 0) player->spd.y = 0; + if (sign_spd_x != 0) player->spd_x = 0; + if (sign_spd_y != 0) player->spd_y = 0; while (player_collide(level, player->pos, SOLID_TILE, 0)) { player->pos.x -= sign_spd_x; player->pos.y -= sign_spd_y; @@ -82,7 +103,7 @@ bool player_move(Player *player, Level level, vec2_int_t spd_x, vec2_int_t spd_y return false; } -int8_t sign(vec2_int_t value) { +int8_t sign(int8_t value) { if (value > 0) return 1; else if (value < 0) @@ -90,3 +111,7 @@ int8_t sign(vec2_int_t value) { else return 0; } + +int8_t round(float value) { + return (int8_t)value; +} diff --git a/src/tiles.c b/src/tiles.c index 9a90446..32cec79 100644 --- a/src/tiles.c +++ b/src/tiles.c @@ -16,7 +16,7 @@ int tile_color(tile_t tile) { case SPAWN_TILE: color = C_RGB(20/4, 220/4, 20/4); break; case EXIT_TILE: color = C_RGB(250/4, 220/4, 10/4); break; case KEY_TILE: color = C_RGB(210/4, 210/4, 210/4); break; - case SEMI_SOLID: color = C_RGB(5/4, 105/4, 90/4); break; + case SEMI_SOLID_TILE: color = C_RGB(5/4, 105/4, 90/4); break; } return color; }