From b50f8d403e36137d6f8dccd847efd4e220f2c505 Mon Sep 17 00:00:00 2001 From: "Juan J. Martinez" Date: Sun, 18 Jun 2023 00:08:28 +0100 Subject: Enter the player! --- src/game.c | 11 ++++ src/player.c | 206 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/player.h | 10 +++ 3 files changed, 227 insertions(+) create mode 100644 src/player.c create mode 100644 src/player.h (limited to 'src') diff --git a/src/game.c b/src/game.c index bde5036..b39b0ca 100644 --- a/src/game.c +++ b/src/game.c @@ -8,6 +8,8 @@ #include "data.h" #include "timer.h" +#include "player.h" + #include "game.h" static uint32_t hiscore = 15000; @@ -78,6 +80,9 @@ void run_game() map_init(binary_stage_start); map_render(); + player_init(16, 128); + player_draw(); + timer_start(GAME_TIME_MAX, &clock_updated); while (!keys[KEY_ESC]) @@ -91,6 +96,12 @@ void run_game() if (hud) hud_render(); + player_erase(); + + player_update(); + + player_draw(); + wait_vsync(); blit_update(); } diff --git a/src/player.c b/src/player.c new file mode 100644 index 0000000..b0960bc --- /dev/null +++ b/src/player.c @@ -0,0 +1,206 @@ +#include + +#include "keyb.h" +#include "vga.h" +#include "map.h" +#include "data.h" + +#include "player.h" + +#define DIR_RIGHT 0 +#define DIR_LEFT 1 + +#define FRAME_STANDING 0 +#define FRAME_JUMPING 4 +#define FRAME_DYING 5 + +#define WALK_CYCLE_FRAMES 4 +#define WALK_DELAY 8 + +#define GRAVITY_OFF 0 +/* XXX: subtract 1 to get the value from gravity_seq */ +#define GRAVITY_DOWN 14 +#define GRAVITY_UP 1 + +#define GRAVITY_SEQ_LEN 24 + +#define IS_GOING_DOWN(x) ((x)>=GRAVITY_DOWN) + +static uint16_t x, y; +static uint8_t dir, frame, delay, gravity, jump; + +const uint8_t gravity_seq[GRAVITY_SEQ_LEN] = { + 6, 4, 4, 2, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 4 +}; + +static uint8_t bg[256]; + +static const Rect frames[2][6] = +{ + { + /* walk cycle */ + { 0, 0, 144, 144 }, + { 16, 0, 144, 144 }, + { 0, 0, 144, 144 }, + { 32, 0, 144, 144 }, + + /* jump */ + { 48, 0, 144, 144 }, + + /* dying */ + { 128, 0, 144, 144 }, + }, + { + /* walk cycle */ + { 64, 0, 144, 144 }, + { 80, 0, 144, 144 }, + { 64, 0, 144, 144 }, + { 96, 0, 144, 144 }, + + /* jump */ + { 112, 0, 144, 144 }, + + /* dying */ + { 128, 0, 144, 144 }, + }, +}; + +void player_init(uint16_t start_x, uint8_t start_y) +{ + dir = DIR_RIGHT; + frame = FRAME_STANDING; + delay = 0; + jump = 0; + + x = start_x; + y = start_y; + gravity = GRAVITY_OFF; +} + +void player_update() +{ + uint8_t moved = 0; + + if (gravity == GRAVITY_OFF + && !map_is_blocked(x + 4, y + 16) + && !map_is_blocked(x + 11, y + 16)) + { + gravity = GRAVITY_DOWN; + frame = FRAME_JUMPING; + moved = 1; + } + + if (keys[KEY_UP]) + { + if (gravity == GRAVITY_OFF && !jump) + { + jump = 1; + frame = FRAME_JUMPING; + gravity = GRAVITY_UP; + } + } + else + jump = 0; + + if (keys[KEY_RIGHT] && !keys[KEY_LEFT]) + { + moved = 1; + dir = DIR_RIGHT; + + /* XXX: off limits */ + if (x < MAP_W * MAP_TILE_W - 16) + { + if ((IS_GOING_DOWN(gravity) && !map_is_blocked(x + 16, y + 15)) + || (!IS_GOING_DOWN(gravity) + && !(map_is_blocked(x + 16, y + 15) + && map_is_blocked(x + 16, y + 7)))) + x++; + } + } + + if (keys[KEY_LEFT] && !keys[KEY_RIGHT]) + { + moved = 1; + dir = DIR_LEFT; + + /* XXX: off limits */ + if (x) + { + if ((IS_GOING_DOWN(gravity) && !map_is_blocked(x - 1, y + 15)) + || (!IS_GOING_DOWN(gravity) + && !(map_is_blocked(x - 1, y + 15) + && map_is_blocked(x - 1, y + 7)))) + x--; + } + } + + if (gravity != GRAVITY_OFF) + { + uint8_t steps = gravity_seq[gravity - 1]; + + moved = 1; + + if (gravity > GRAVITY_DOWN) + { + /* going down! */ + for (uint8_t i = 0; i < steps; i++) + { + /* hit the floor */ + if ((map_is_blocked(x + 11, y + 16) + || map_is_blocked(x + 4, y + 16)) + && !map_is_blocked(x + 4, y + 15) + && !map_is_blocked(x + 11, y + 15)) + { + gravity = GRAVITY_OFF; + frame = FRAME_STANDING; + break; + } + y++; + } + } + else + { + /* going up! */ + if (y < steps) + y = 0; + else + y -= steps; + } + + if (gravity != GRAVITY_OFF && gravity != GRAVITY_SEQ_LEN) + gravity++; + } + + if (moved) + { + if (delay++ == WALK_DELAY) + { + delay = 0; + if (frame != FRAME_JUMPING) + { + frame++; + if (frame == WALK_CYCLE_FRAMES) + frame = FRAME_STANDING; + } + } + } + else + { + delay = 0; + frame = FRAME_STANDING; + } +} + +void player_erase() +{ + Rect dst = { x, y + MAP_OFFS_Y, 16, 16 }; + blit(bg, &dst); +} + +void player_draw() +{ + Rect dst = { x, y + MAP_OFFS_Y, 16, 16 }; + + read_buffer(bg, &dst); + blitrc(binary_sprites_start, &frames[dir][frame], &dst); +} diff --git a/src/player.h b/src/player.h new file mode 100644 index 0000000..56bbd22 --- /dev/null +++ b/src/player.h @@ -0,0 +1,10 @@ +#ifndef _PLAYER_H +#define _PLAYER_H + +void player_init(uint16_t start_x, uint8_t start_y); +void player_update(); + +void player_erase(); +void player_draw(); + +#endif /* _PLAYER_H */ -- cgit v1.2.3