diff options
author | quou <quou@disroot.org> | 2023-05-06 10:39:19 +1000 |
---|---|---|
committer | quou <quou@disroot.org> | 2023-05-06 10:39:19 +1000 |
commit | 91aef268319a77ee8f5a082ca89264bf2671e212 (patch) | |
tree | 7deb9a4a9e928d4b78f7c3398e7d9c97a4649140 | |
parent | 2ab411c4b8855d11d48454a93262e8eae3ba7fc7 (diff) |
Map rendering and camera movement.
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | asset.c | 3 | ||||
-rw-r--r-- | asset.h | 3 | ||||
-rw-r--r-- | game.c | 12 | ||||
-rw-r--r-- | game_config.h | 6 | ||||
-rw-r--r-- | intermediate/map.bmp | bin | 0 -> 8330 bytes | |||
-rw-r--r-- | map.c | 95 | ||||
-rw-r--r-- | map.h | 19 | ||||
-rw-r--r-- | player.c | 22 | ||||
-rw-r--r-- | render.c | 119 | ||||
-rw-r--r-- | render.h | 17 | ||||
-rw-r--r-- | sprite.c | 10 | ||||
-rw-r--r-- | sprite.h | 4 | ||||
-rw-r--r-- | sprite_system.c | 7 | ||||
-rw-r--r-- | world.h | 4 |
15 files changed, 314 insertions, 8 deletions
@@ -95,6 +95,7 @@ sources = \ game.c \ main.c \ malware.c \ + map.c \ menu.c \ platform.c \ player.c \ @@ -9,7 +9,8 @@ static const char* const asset_vpaths[] = { /* asset_id_usr */ "data/usr.img", /* asset_id_char */ "data/char.img", /* asset_id_bullet */ "data/bullet.img", - /* asset_id_enemy */ "data/enemy.img" + /* asset_id_enemy */ "data/enemy.img", + /* asset_id_map */ "data/map.img" }; static struct { @@ -3,13 +3,14 @@ #include "render.h" -#define bitmap_asset_count 4 +#define bitmap_asset_count 5 typedef enum { asset_id_usr = 0, asset_id_char, asset_id_bullet, asset_id_enemy, + asset_id_map, asset_count } Asset_ID; @@ -87,18 +87,22 @@ static void menu_deinit(Game* game) { static void gameplay_init(Game* game) { init_world(&game->world); - + init_map(&game->world.map); init_player(&game->world.player, &game->world); - new_skull(&game->world, 0, 0); } static void gameplay_update(Game* game) { + int cx, cy; + cx = game->world.cam_x; + cy = game->world.cam_y; + update_player(&game->world.player, &game->world); enemy_system(&game->world); bullet_system(&game->world); collision_system(&game->world); animation_system(&game->world); + render_map(&game->world.map, cx, cy); sprite_system(&game->world); } @@ -127,11 +131,15 @@ static void dead_init(Game* game) { static void dead_update(Game* game) { const BM_Font* font; + int cx, cy; font = get_default_font(); update_menu(&game->menu); + cx = game->world.cam_x; + cy = game->world.cam_y; + render_map(&game->world.map, cx, cy); sprite_system(&game->world); rfont_text( diff --git a/game_config.h b/game_config.h index b2d569f..8609814 100644 --- a/game_config.h +++ b/game_config.h @@ -11,4 +11,10 @@ #define skull_shoot_cooldown 15 #define enemy_bullet_speed 10 +#define map_width 32 +#define map_height 32 +#define map_tile_size 16 +#define mbmp_w (map_width * map_tile_size) +#define mbmp_h (map_height * map_tile_size) + #endif diff --git a/intermediate/map.bmp b/intermediate/map.bmp Binary files differnew file mode 100644 index 0000000..e6a66ee --- /dev/null +++ b/intermediate/map.bmp @@ -0,0 +1,95 @@ +#include "map.h" +#include "sprite.h" +#include "standard.h" + +void init_map(Map* map) { + const Sprite* floor, * bricks; + const Bitmap* fbmp, * bbmp; + Bitmap bitmap; + int i, x, y; + + bitmap.pixels = map->pixels; + bitmap.w = mbmp_w; + bitmap.h = mbmp_h; + + floor = get_sprite(sprite_floor_tile); + bricks = get_sprite(sprite_bricks); + fbmp = get_bitmap(floor->bitmap); + bbmp = get_bitmap(bricks->bitmap); + + for (i = 0; i < mbmp_w * mbmp_h; i++) { + bitmap.pixels[i] = make_black(); + } + + for (x = 1; x < map_width - 1; x++) { + for (y = 1; y < map_height - 1; y++) { + blit( + &bitmap, + fbmp, + map_tile_size * x, + map_tile_size * y, + &floor->rect + ); + } + } + + for (x = 0; x < map_width; x++) { + blit( + &bitmap, + bbmp, + map_tile_size * x, + 0, + &bricks->rect + ); + blit( + &bitmap, + bbmp, + map_tile_size * x, + (map_height - 1) * map_tile_size, + &bricks->rect + ); + } + + for (y = 0; y < map_height; y++) { + blit( + &bitmap, + bbmp, + 0, + map_tile_size * y, + &bricks->rect + ); + blit( + &bitmap, + bbmp, + (map_width - 1) * map_tile_size, + map_tile_size * y, + &bricks->rect + ); + } + + for (i = 0; i < 20; i++) { + x = rand_range(0, map_width - 1) * map_tile_size; + y = rand_range(0, map_height - 1) * map_tile_size; + blit( + &bitmap, + bbmp, + x, + y, + &bricks->rect + ); + } +} + +void render_map(Map* map, int cx, int cy) { + Bitmap bitmap; + Rectangle rect; + + bitmap.pixels = map->pixels; + bitmap.w = mbmp_w; + bitmap.h = mbmp_h; + rect.x = 0; + rect.y = 0; + rect.w = bitmap.w; + rect.h = bitmap.h; + render_bitmap(&bitmap, -cx >> fbits, -cy >> fbits, &rect); +} @@ -0,0 +1,19 @@ +#ifndef map_h +#define map_h + +#include "game_config.h" +#include "render.h" + +typedef struct { + Colour pixels[ + map_width * + map_tile_size * + map_height * + map_tile_size + ]; +} Map; + +void init_map(Map* map); +void render_map(Map* map, int cx, int cy); + +#endif @@ -55,7 +55,7 @@ void init_player(Player* player, World* world) { } void update_player(Player* player, World* world) { - int dx, dy; + int dx, dy, cbx, cby; int face, moving = 0; Entity e; CPosition* pos; @@ -132,6 +132,26 @@ void update_player(Player* player, World* world) { game_change_state(&game, game_state_dead); } + world->cam_x = pos->x - ((renderer_w / 2) << fbits); + world->cam_y = pos->y - ((renderer_h / 2) << fbits); + + if (world->cam_x < 0) { + world->cam_x = 0; + } + + if (world->cam_y < 0) { + world->cam_y = 0; + } + + cbx = (mbmp_w - renderer_w) << fbits; + if (world->cam_x > cbx) { + world->cam_x = cbx; + } + cby = (mbmp_h - renderer_h) << fbits; + if (world->cam_y > cby) { + world->cam_y = cby; + } + player->shoot_countdown--; } @@ -261,3 +261,122 @@ void render_bitmap_col( src += sstride; } } + +void blit( + Bitmap* to, + const Bitmap* from, + int x, + int y, + const Rectangle* rect +) { + int i, j, stride, sstride, n; + Colour* dst; + const Colour* src; + Rectangle sub; + + sub = *rect; + + if (sub.w <= 0) { return; } + if (sub.h <= 0) { return; } + if (sub.w > from->w) { return; } + if (sub.h > from->h) { return; } + + if ((n = -x) > 0) { + sub.w -= n; + sub.x += n; + x += n; + } + + if ((n = -y) > 0) { + sub.h -= n; + sub.y += n; + y += n; + } + + if ((n = x + sub.w - to->w) > 0) { + sub.w -= n; + } + + if ((n = y + sub.h - to->h) > 0) { + sub.h -= n; + } + + if (sub.w <= 0) { return; } + if (sub.h <= 0) { return; } + + dst = to->pixels + (x + y * to->w); + src = from->pixels + (sub.x + sub.y * from->w); + + stride = to->w - sub.w; + sstride = from->w - sub.w; + + for (i = 0; i < sub.h; i++) { + for (j = 0; j < sub.w; j++) { + *dst = blend(*dst, *src); + dst++; + src++; + } + dst += stride; + src += sstride; + } +} + +void blit_col( + Bitmap* to, + const Bitmap* from, + int x, + int y, + const Rectangle* rect, + Colour colour +) { + int i, j, stride, sstride, n; + Colour* dst; + const Colour* src; + Rectangle sub; + + sub = *rect; + + if (sub.w <= 0) { return; } + if (sub.h <= 0) { return; } + if (sub.w > from->w) { return; } + if (sub.h > from->h) { return; } + + if ((n = -x) > 0) { + sub.w -= n; + sub.x += n; + x += n; + } + + if ((n = -y) > 0) { + sub.h -= n; + sub.y += n; + y += n; + } + + if ((n = x + sub.w - to->w) > 0) { + sub.w -= n; + } + + if ((n = y + sub.h - to->h) > 0) { + sub.h -= n; + } + + if (sub.w <= 0) { return; } + if (sub.h <= 0) { return; } + + dst = to->pixels + (x + y * to->w); + src = from->pixels + (sub.x + sub.y * from->w); + + stride = to->w - sub.w; + sstride = from->w - sub.w; + + for (i = 0; i < sub.h; i++) { + for (j = 0; j < sub.w; j++) { + *dst = blend_mod(*dst, *src, colour); + dst++; + src++; + } + dst += stride; + src += sstride; + } +} @@ -84,4 +84,21 @@ void render_bitmap_col( Colour colour ); +void blit( + Bitmap* dst, + const Bitmap* src, + int x, + int y, + const Rectangle* rect +); + +void blit_col( + Bitmap* dst, + const Bitmap* src, + int x, + int y, + const Rectangle* rect, + Colour colour +); + #endif @@ -70,6 +70,16 @@ static const Sprite sprites[] = { { asset_id_usr, { 0, 80, 171, 10 } + }, + /* sprite_floor_tile */ + { + asset_id_map, + { 0, 0, 16, 16 } + }, + /* sprite_bricks */ + { + asset_id_map, + { 16, 0, 16, 16 } } }; @@ -19,7 +19,9 @@ typedef enum { sprite_skull_debris_5, sprite_enemy_bullet, sprite_author, - sprite_free + sprite_free, + sprite_floor_tile, + sprite_bricks } Sprite_ID; typedef struct { diff --git a/sprite_system.c b/sprite_system.c index 526c097..b94886e 100644 --- a/sprite_system.c +++ b/sprite_system.c @@ -5,7 +5,7 @@ #include "world.h" void sprite_system(const World* world) { - int i; + int i, x, y; unsigned bits; const CSprite* sprite; const CPosition* pos; @@ -17,8 +17,11 @@ void sprite_system(const World* world) { pos = &world->positions[i]; sprite = &world->sprites[i]; + x = pos->x - world->cam_x; + y = pos->y - world->cam_y; + b = get_bitmap(sprite->id); - render_bitmap(b, pos->x >> fbits, pos->y >> fbits, &sprite->rect); + render_bitmap(b, x >> fbits, y >> fbits, &sprite->rect); } } } @@ -3,6 +3,7 @@ #include "components.h" #include "config.h" +#include "map.h" #include "player.h" typedef int Entity; @@ -23,7 +24,10 @@ struct World { CEnemy enemies [max_entities]; CCollider colliders [max_entities]; + int cam_x, cam_y; + Player player; + Map map; }; void init_world(World* world); |