diff --git a/CMakeLists.txt b/CMakeLists.txt index f5b9016..eabb342 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,13 +28,15 @@ set(ASSETS_cg assets-cg/img/wall.png assets-cg/img/spike.png assets-cg/img/end.png + assets-cg/img/door.png + assets-cg/img/key.png # ... ) fxconv_declare_assets(${ASSETS} ${ASSETS_fx} ${ASSETS_cg} WITH_METADATA) add_executable(myaddin ${SOURCES} ${ASSETS} ${ASSETS_${FXSDK_PLATFORM}}) -target_compile_options(myaddin PRIVATE -Wall -Wextra -Os) +target_compile_options(myaddin PRIVATE -Wall -Wextra -Os -Wno-missing-braces) target_link_libraries(myaddin Gint::Gint) if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G) diff --git a/assets-cg/img/door.png b/assets-cg/img/door.png new file mode 100644 index 0000000..f073bfd Binary files /dev/null and b/assets-cg/img/door.png differ diff --git a/assets-cg/img/fxconv-metadata.txt b/assets-cg/img/fxconv-metadata.txt index 38c561a..e66bf67 100644 --- a/assets-cg/img/fxconv-metadata.txt +++ b/assets-cg/img/fxconv-metadata.txt @@ -12,4 +12,12 @@ spike.png: end.png: type: bopti-image - name: img_end \ No newline at end of file + name: img_end + +door.png: + type: bopti-image + name: img_door + +key.png: + type: bopti-image + name: img_key \ No newline at end of file diff --git a/assets-cg/img/key.png b/assets-cg/img/key.png new file mode 100644 index 0000000..0d5b4d7 Binary files /dev/null and b/assets-cg/img/key.png differ diff --git a/assets-cg/img/player.png b/assets-cg/img/player.png index e011918..39f4684 100644 Binary files a/assets-cg/img/player.png and b/assets-cg/img/player.png differ diff --git a/include/main.h b/include/main.h index b1da36a..1b552bd 100644 --- a/include/main.h +++ b/include/main.h @@ -3,6 +3,7 @@ #define LEVEL_NB 2 #define LEVEL_SIZE 16 #define TILE_SIZE 12 +#define PLAYER_SIZE 10 /* struct for a pair of values */ typedef struct Vec2 { @@ -21,4 +22,5 @@ typedef int tile_t; Vec2 search(tile_t x, tile_t level[LEVEL_SIZE][LEVEL_SIZE]); int collide_pixel(Vec2 pos, tile_t obj, tile_t level[LEVEL_SIZE][LEVEL_SIZE]); int collide(Vec2 pos, int h, tile_t obj, tile_t level[LEVEL_SIZE][LEVEL_SIZE]); -Player level_reset(Player player, tile_t level[LEVEL_SIZE][LEVEL_SIZE]); +int object_delete(Vec2 pos, tile_t obj, tile_t level[LEVEL_SIZE][LEVEL_SIZE]); +Player player_reset(Player player, tile_t level[LEVEL_SIZE][LEVEL_SIZE]); diff --git a/levels/level2.kble b/levels/level2.kble index dbe7d27..7968393 100644 Binary files a/levels/level2.kble and b/levels/level2.kble differ diff --git a/levels/level3.kble b/levels/level3.kble new file mode 100644 index 0000000..924eff0 Binary files /dev/null and b/levels/level3.kble differ diff --git a/levels/tileset.png b/levels/tileset.png index e2e4558..afdba74 100644 Binary files a/levels/tileset.png and b/levels/tileset.png differ diff --git a/src/levels.c b/src/levels.c index 57fc33d..1001129 100644 --- a/src/levels.c +++ b/src/levels.c @@ -22,20 +22,20 @@ const tile_t level[LEVEL_NB][LEVEL_SIZE][LEVEL_SIZE] = { { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, + 2, 0, 6, 0, 0, 4, 0, 0, 0, 0, 4, 0, 0, 6, 0, 2, + 2, 0, 0, 0, 4, 2, 0, 0, 0, 0, 2, 4, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, - 2, 0, 2, 2, 2, 0, 3, 0, 0, 0, 0, 0, 2, 0, 0, 2, - 2, 0, 2, 0, 0, 0, 0, 0, 2, 2, 2, 0, 2, 2, 0, 2, - 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 0, 2, - 2, 0, 2, 2, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, - 2, 0, 0, 0, 0, 0, 2, 2, 0, 2, 0, 0, 2, 2, 0, 2, - 2, 0, 4, 0, 4, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, - 2, 0, 0, 4, 0, 0, 2, 2, 0, 2, 0, 0, 2, 2, 0, 2, - 2, 0, 4, 0, 4, 0, 0, 2, 0, 2, 0, 0, 2, 0, 0, 2, - 2, 0, 0, 0, 0, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, + 2, 2, 2, 2, 0, 0, 0, 2, 2, 0, 0, 0, 2, 2, 2, 2, + 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 5, 0, 3, 2, + 2, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 5, 0, 0, 2, + 2, 2, 2, 2, 0, 0, 0, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, - 2, 0, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 2, - 2, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 4, 0, 0, 0, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 4, 2, 4, 2, 2, 2, 2, 2 - } + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 2, 0, 0, 0, 4, 2, 0, 0, 0, 0, 2, 4, 0, 0, 0, 2, + 2, 0, 6, 0, 0, 4, 0, 0, 0, 0, 4, 0, 0, 6, 0, 2, + 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 + } }; \ No newline at end of file diff --git a/src/main.c b/src/main.c index e5ee7c1..d18c15b 100644 --- a/src/main.c +++ b/src/main.c @@ -3,6 +3,7 @@ #include #include +#include #include "main.h" Vec2 search(tile_t x, tile_t level[16][16]) { @@ -36,7 +37,7 @@ int collide(Vec2 pos, int h, tile_t obj, tile_t level[LEVEL_SIZE][LEVEL_SIZE]) { /* tl = top left */ /* br = bottom right */ const Vec2 pos_tl = (Vec2){pos.x + h, pos.y + h}; - const Vec2 pos_br = (Vec2){pos.x + TILE_SIZE - h - 1, pos.y + TILE_SIZE - h - 1}; + const Vec2 pos_br = (Vec2){pos.x + PLAYER_SIZE - h - 1, pos.y + PLAYER_SIZE - h - 1}; /* Check if there's something in */ /* the square (x + 1, y + 1, x + 11, y + 11) */ /* The size of the hitbox changes with h */ @@ -50,7 +51,28 @@ int collide(Vec2 pos, int h, tile_t obj, tile_t level[LEVEL_SIZE][LEVEL_SIZE]) { return 0; } -Player level_reset(Player player, tile_t level[LEVEL_SIZE][LEVEL_SIZE]) { +int object_delete(Vec2 pos, tile_t obj, tile_t level[LEVEL_SIZE][LEVEL_SIZE]) { + /* delete the object if it touches the player */ + const Vec2 pos_tl = (Vec2){pos.x, pos.y}; + const Vec2 pos_br = (Vec2){pos.x + PLAYER_SIZE - 1, pos.y + PLAYER_SIZE - 1}; + + if(collide_pixel(pos_tl, obj, level)) { + level[pos_tl.y / TILE_SIZE][pos_tl.x / TILE_SIZE] = 0; + } + if(collide_pixel(pos_br, obj, level)) { + level[pos_br.y / TILE_SIZE][pos_br.x / TILE_SIZE] = 0; + } + if(collide_pixel((Vec2){pos_tl.x, pos_br.y}, obj, level)) { + level[pos_br.y / TILE_SIZE][pos_tl.x / TILE_SIZE] = 0; + } + if(collide_pixel((Vec2){pos_br.x, pos_tl.y}, obj, level)) { + level[pos_tl.y / TILE_SIZE][pos_br.x / TILE_SIZE] = 0; + } + return 1; +} + +Player player_reset(Player player, tile_t level[LEVEL_SIZE][LEVEL_SIZE]) { + /* reset the level */ player.spawn = search(1, level); player.pos = player.spawn; return player; @@ -61,12 +83,15 @@ int main(void) { extern bopti_image_t img_wall; extern bopti_image_t img_spike; extern bopti_image_t img_end; + extern bopti_image_t img_door; + extern bopti_image_t img_key; extern tile_t level[LEVEL_NB][LEVEL_SIZE][LEVEL_SIZE]; int running = 1; int timer = 0; /* lol */ int lvl = 0; + tile_t curr_level[LEVEL_SIZE][LEVEL_SIZE]; /* player */ Player player = { @@ -74,7 +99,8 @@ int main(void) { .spawn = {0, 0} }; - player = level_reset(player, level[lvl]); + memcpy(curr_level, level[lvl], sizeof(level[lvl])); + player = player_reset(player, curr_level); /* main loop */ while(running) { @@ -84,7 +110,7 @@ int main(void) { /* drawing the level */ for(int m = 0; m < LEVEL_SIZE; ++m) { for(int n = 0; n < LEVEL_SIZE; ++n) { - switch(level[lvl][n][m]) { + switch(curr_level[n][m]) { case 2: /* walls */ dimage(m * TILE_SIZE, n * TILE_SIZE, &img_wall); @@ -98,7 +124,15 @@ int main(void) { /* spikes */ dimage(m * TILE_SIZE, n * TILE_SIZE, &img_spike); break; - + case 5: + /* door */ + dimage(m * TILE_SIZE, n * TILE_SIZE, &img_door); + break; + case 6: + /* key ring */ + dsubimage(m * TILE_SIZE, n * TILE_SIZE, &img_key, + ((timer / 30) % 4) * 12, 0, 12, 12, 0); + break; } } } @@ -115,27 +149,49 @@ int main(void) { clearevents(); /* trying to move the player >w< */ - if(!collide((Vec2){player.pos.x + mov.x, player.pos.y}, 1, 2, level[lvl])) { + if(!collide((Vec2){player.pos.x + mov.x, player.pos.y}, 0, 2, curr_level) && + !collide((Vec2){player.pos.x + mov.x, player.pos.y}, 1, 5, curr_level)) { player.pos.x += mov.x; } - if(!collide((Vec2){player.pos.x, player.pos.y + mov.y}, 1, 2, level[lvl])) { + if(!collide((Vec2){player.pos.x, player.pos.y + mov.y}, 0, 2, curr_level) && + !collide((Vec2){player.pos.x, player.pos.y + mov.y}, 1, 5, curr_level)) { player.pos.y += mov.y; } /* d i e */ - if(collide(player.pos, 2, 4, level[lvl])) { - player = level_reset(player, level[lvl]); + if(collide(player.pos, 2, 4, curr_level)) { + tile_t curr_level[LEVEL_SIZE][LEVEL_SIZE]; + memcpy(curr_level, level[lvl], sizeof(level[lvl])); + player = player_reset(player, curr_level); } + /* keys */ + if(collide(player.pos, 0, 6, curr_level)) { + object_delete(player.pos, 6, curr_level); + /* check if there is any key */ + Vec2 key_pos = search(6, curr_level); + if(key_pos.x == 0 && key_pos.y == 0) { + for(int m = 0; m < LEVEL_SIZE; ++m) { + for(int n = 0; n < LEVEL_SIZE; ++n) { + if(curr_level[m][n] == 5) { + curr_level[m][n] = 0; + } + } + } + } + } + + /* end */ if(keydown(KEY_EXIT)) { running = 0; } - if(collide(player.pos, 0, 3, level[lvl])) { + if(collide(player.pos, 0, 3, curr_level)) { if(lvl != LEVEL_NB - 1) { - player = level_reset(player, level[lvl]); ++lvl; + memcpy(curr_level, level[lvl], sizeof(level[lvl])); + player = player_reset(player, curr_level); } else { running = 0;