level.c (8225B)
1 #include <stdlib.h> 2 3 #include "../include/enemy.h" 4 #include "../include/level.h" 5 #include "../include/const.h" 6 #include "../include/tile.h" 7 #include "../include/entity.h" 8 9 const char *LEVEL_MAP_1 = { 10 "........................" 11 "........................" 12 "........................" 13 "..I....................." 14 "........................" 15 "........................" 16 ".............o.........." 17 "..................2....." 18 "........................" 19 "........................" 20 ".....3........e....u...." 21 "............--xxxxxxxx.." 22 "....p..................." 23 "..xxxxxxxxxxx..........." 24 "........................" 25 "........................" 26 }; 27 28 const char *LEVEL_MAP_2 = { 29 "........................" 30 "........................" 31 "........k.......O......." 32 "..1....................." 33 "........................" 34 "........................" 35 "......e......3.........." 36 "....xxxxx..............." 37 ".....b.................." 38 "...........--...xxx....." 39 "................e......." 40 "...........2...--xxxxx.." 41 "....p....u.............." 42 "..xxxxxxxxx---xxxxxxxx.." 43 "........................" 44 "........................" 45 }; 46 47 const char *LEVEL_MAP_3 = { 48 "........................" 49 "........................" 50 "......3....b............" 51 "........................" 52 "................u......." 53 "...............xxxx....." 54 ".........s.e............" 55 ".......xxxxxxtxxx--xx..." 56 "...o.........w.........." 57 ".........2...w...--.1..." 58 ".............w.........." 59 ".........----x...--....." 60 "....p...............e..." 61 "..xxxxx....xxxxxxxxxxx.." 62 "........................" 63 "........................" 64 }; 65 66 const char *LEVEL_MAP_4 = { 67 "........................" 68 "............o..........." 69 "..1....................." 70 ".........e.........u...." 71 "........---.......---..." 72 "......s................." 73 "...xxtxxxxxx..-.....3..." 74 ".....w...b.............." 75 "...e.w............j....." 76 "..---x...........ejj...." 77 "..............xtxxxxxx.." 78 "...2.....---...w........" 79 "....p..........w........" 80 "..xxxxx................." 81 "........................" 82 "........................" 83 }; 84 85 const char *LEVEL_MAP_5 = { 86 "........................" 87 "........................" 88 "...b.....1........k....." 89 ".........z..-txx-......." 90 ".............w.........." 91 "............-w..-......." 92 ".............w......u..." 93 "..x---xxxxxxxtxxx--xxx.." 94 "....e........w....e....." 95 "...---....2..w--txxx...." 96 "....3........w..w......." 97 "........-----w.........." 98 "....p.......ewj....s...." 99 "..xxxx....xxxxxxxxxxxx.." 100 "........................" 101 "........................" 102 }; 103 104 void level_generate(game_t *game, const char *map, int width, int height) { 105 game->player = NULL; 106 game->tiles = malloc(sizeof(tile_t) * width * height); 107 game->tiles_len = width * height; 108 game->entities = NULL; 109 game->entities_len = 0; 110 game->effects = NULL; 111 game->effects_len = 0; 112 game->xp = 0; 113 for (int y = 0; y < height; y++) { 114 for (int x = 0; x < width; x++) { 115 int idx = y * width + x; 116 char c = map[idx]; 117 game->tiles[idx] = tile_create((pos_t) { 118 .x = x * TILE_WIDTH, 119 .y = y * TILE_HEIGHT, 120 }, TILE_AIR); 121 tile_t *tile = game->tiles[idx]; 122 // generate tile types 123 switch (c) { 124 case 'x': 125 tile->type = TILE_STONE; 126 break; 127 case 'g': 128 tile->type = TILE_GRASS; 129 break; 130 case '-': 131 tile->type = TILE_WOOD_PLATFORM; 132 break; 133 case 't': 134 tile->type = TILE_STONE_JOINT; 135 break; 136 case 'w': 137 tile->type = TILE_STONE_WALL; 138 break; 139 case 'i': 140 tile->type = TILE_SNOW; 141 break; 142 case 'n': 143 tile->type = TILE_SAND; 144 break; 145 case 'j': 146 tile->type = TILE_BOX; 147 break; 148 case 'k': 149 tile->type = TILE_BG_CHANDELIER; 150 break; 151 case 'O': 152 tile->type = TILE_BG_WINDOW_1; 153 break; 154 case 'o': 155 tile->type = TILE_BG_WINDOW_2; 156 break; 157 case 'b': 158 tile->type = TILE_BG_BANNER; 159 break; 160 case '1': 161 tile->type = TILE_BG_BRICK_1; 162 break; 163 case '2': 164 tile->type = TILE_BG_BRICK_2; 165 break; 166 case '3': 167 tile->type = TILE_BG_BRICK_3; 168 break; 169 case 'I': 170 tile->type = TILE_BG_INFO; 171 break; 172 default: 173 break; 174 } 175 // spawn entities 176 switch (c) { 177 case 'p': { 178 game->player = player_create((pos_t) { 179 .x = x * TILE_WIDTH + (TILE_WIDTH - PLAYER_WIDTH) / 2.0, 180 .y = y * TILE_HEIGHT + TILE_HEIGHT - PLAYER_HEIGHT, 181 }); 182 break; 183 } 184 case 'e': { 185 game->entities = realloc(game->entities, sizeof(enemy_t) * (game->entities_len + 1)); 186 enemy_t *enemy = enemy_create((pos_t) { 187 .x = x * TILE_WIDTH + (TILE_WIDTH - ENEMY_WIDTH) / 2.0, 188 .y = y * TILE_HEIGHT + TILE_HEIGHT - ENEMY_HEIGHT, 189 }, ENEMY_TEST); 190 game->entities[game->entities_len] = (entity_t) { 191 .type = ENTITY_ENEMY, 192 .enemy = enemy, 193 .is_bad = true, 194 }; 195 game->entities_len++; 196 break; 197 } 198 case 's': { 199 game->entities = realloc(game->entities, sizeof(enemy_t) * (game->entities_len + 1)); 200 gate_t *gate = gate_create((pos_t) { 201 .x = x * TILE_WIDTH + (TILE_WIDTH - ENEMY_WIDTH) / 2.0, 202 .y = y * TILE_HEIGHT, 203 }, 5, 500); 204 game->entities[game->entities_len] = (entity_t) { 205 .type = ENTITY_GATE, 206 .gate = gate, 207 .is_bad = true, 208 }; 209 game->entities_len++; 210 break; 211 } 212 case 'u': { 213 game->entities = realloc(game->entities, sizeof(enemy_t) * (game->entities_len + 1)); 214 door_t *door = door_create((pos_t) { 215 .x = x * TILE_WIDTH + (TILE_WIDTH - ENEMY_WIDTH) / 2.0, 216 .y = y * TILE_HEIGHT, 217 }); 218 game->entities[game->entities_len] = (entity_t) { 219 .type = ENTITY_DOOR, 220 .door = door, 221 .is_bad = false, 222 }; 223 game->entities_len++; 224 break; 225 } 226 case 'z': { 227 game->entities = realloc(game->entities, sizeof(enemy_t) * (game->entities_len + 1)); 228 boss_t *boss = boss_create((pos_t) { 229 .x = x * TILE_WIDTH + (TILE_WIDTH - ENEMY_WIDTH) / 2.0, 230 .y = y * TILE_HEIGHT, 231 }, BOSS_TEST); 232 game->entities[game->entities_len] = (entity_t) { 233 .type = ENTITY_BOSS, 234 .boss = boss, 235 .is_bad = true, 236 }; 237 game->entities_len++; 238 break; 239 } 240 default: 241 break; 242 } 243 } 244 } 245 } 246 247 void level_load(game_t *game, level_e type) { 248 level_t *level = malloc(sizeof(level_t)); 249 level->type = type; 250 switch (type) { 251 case LEVEL_NULL: 252 break; 253 case LEVEL_1: { 254 level_generate(game, LEVEL_MAP_1, 24, 16); 255 level->width = 24; 256 level->height = 16; 257 break; 258 } 259 case LEVEL_2: { 260 level_generate(game, LEVEL_MAP_2, 24, 16); 261 level->width = 24; 262 level->height = 16; 263 break; 264 } 265 case LEVEL_3: { 266 level_generate(game, LEVEL_MAP_3, 24, 16); 267 level->width = 24; 268 level->height = 16; 269 break; 270 } 271 case LEVEL_4: { 272 level_generate(game, LEVEL_MAP_4, 24, 16); 273 level->width = 24; 274 level->height = 16; 275 break; 276 } 277 case LEVEL_5: { 278 level_generate(game, LEVEL_MAP_5, 24, 16); 279 level->width = 24; 280 level->height = 16; 281 break; 282 } 283 } 284 game->level = level; 285 } 286 287 void level_unload(game_t *game) { 288 player_free(game->player); 289 for (int i = 0; i < game->tiles_len; i++) { 290 tile_free(game->tiles[i]); 291 } 292 free(game->tiles); 293 for (int i = 0; i < game->entities_len; i++) { 294 entity_detach(&game->entities[i]); 295 } 296 free(game->entities); 297 for (int i = 0; i < game->effects_len; i++) { 298 effect_free(game->effects[i]); 299 } 300 free(game->effects); 301 free(game->level); 302 }