level.c (6037B)
1 #include <stdlib.h> 2 3 #include "enemy.h" 4 #include "level.h" 5 #include "const.h" 6 #include "tile.h" 7 #include "entity.h" 8 9 const char *LEVEL_MAP_1 = { 10 "........................" 11 "........................" 12 "........................" 13 "........................" 14 "........................" 15 "........................" 16 "......e................." 17 "....xxxx................" 18 "........................" 19 "...........--...xxx....." 20 "................e......." 21 "...............--xxxxx.." 22 "....p..................." 23 "..ggggggggg---xxxxxxxx.." 24 "........................" 25 "........................" 26 }; 27 28 const char *LEVEL_MAP_2 = { 29 "........................" 30 "........................" 31 "........................" 32 "........................" 33 "........................" 34 "..............xxxx......" 35 "........s.e............." 36 "....xxxxxxxxxtxxx--x...." 37 ".............w.........." 38 ".............w...--....." 39 ".............w.........." 40 ".........----x...--....." 41 "....p...............e..." 42 "..ggggg....xxxxxxxxxxx.." 43 "........................" 44 "........................" 45 }; 46 47 const char *LEVEL_MAP_3 = { 48 "........................................" 49 "........................................" 50 "........................................" 51 "........................................" 52 "........................................" 53 "........................................" 54 "........................................" 55 "........................................" 56 "........................................" 57 "........................................" 58 "......e..................e...s.........." 59 "....ggggg...--...xxxxxxxxxxxxxxxxx......" 60 "........................................" 61 "............--.........................." 62 "....................e..................." 63 "............--...xxxxxxxxt-............." 64 ".........................w.............." 65 "............--...........w-............." 66 "..............e.......s..w..e..........." 67 "..........xxxxxxxxxxxxxxxxxxxxxxxt--x..." 68 ".................................w......" 69 ".................................w--...." 70 ".................................w......" 71 ".................................w--...." 72 "........................e........w......" 73 "....................xxtxxxtxx----x--...." 74 "....p.......e.........w...w............." 75 "..ggggg..-----...xxxxxxxxxxxxxxxxxxxxx.." 76 "........................................" 77 "........................................" 78 }; 79 80 void level_generate(game_t *game, const char *map, int width, int height) { 81 game->player = NULL; 82 game->tiles = malloc(sizeof(tile_t) * width * height); 83 game->tiles_len = width * height; 84 game->entities = NULL; 85 game->entities_len = 0; 86 game->effects = NULL; 87 game->effects_len = 0; 88 for (int y = 0; y < height; y++) { 89 for (int x = 0; x < width; x++) { 90 int idx = y * width + x; 91 char c = map[idx]; 92 game->tiles[idx] = tile_create((pos_t) { 93 .x = x * TILE_WIDTH, 94 .y = y * TILE_HEIGHT, 95 }, TILE_AIR); 96 tile_t *tile = game->tiles[idx]; 97 // generate tile types 98 switch (c) { 99 case 'x': 100 tile->type = TILE_STONE; 101 break; 102 case 'g': 103 tile->type = TILE_GRASS; 104 break; 105 case '-': 106 tile->type = TILE_WOOD_PLATFORM; 107 break; 108 case 't': 109 tile->type = TILE_STONE_JOINT; 110 break; 111 case 'w': 112 tile->type = TILE_STONE_WALL; 113 break; 114 case 'i': 115 tile->type = TILE_SNOW; 116 break; 117 case 'n': 118 tile->type = TILE_SAND; 119 break; 120 default: 121 break; 122 } 123 // spawn entities 124 switch (c) { 125 case 'p': { 126 game->player = player_create((pos_t) { 127 .x = x * TILE_WIDTH + (TILE_WIDTH - PLAYER_WIDTH) / 2.0, 128 .y = y * TILE_HEIGHT + TILE_HEIGHT - PLAYER_HEIGHT, 129 }); 130 break; 131 } 132 case 'e': { 133 game->entities = realloc(game->entities, sizeof(enemy_t) * (game->entities_len + 1)); 134 enemy_t *enemy = enemy_create((pos_t) { 135 .x = x * TILE_WIDTH + (TILE_WIDTH - ENEMY_WIDTH) / 2.0, 136 .y = y * TILE_HEIGHT + TILE_HEIGHT - ENEMY_HEIGHT, 137 }, ENEMY_TEST); 138 game->entities[game->entities_len] = (entity_t) { 139 .type = ENTITY_ENEMY, 140 .enemy = enemy, 141 }; 142 game->entities_len++; 143 break; 144 } 145 case 's': { 146 game->entities = realloc(game->entities, sizeof(enemy_t) * (game->entities_len + 1)); 147 gate_t *gate = gate_create((pos_t) { 148 .x = x * TILE_WIDTH + (TILE_WIDTH - ENEMY_WIDTH) / 2.0, 149 .y = y * TILE_HEIGHT, 150 }, 5, 500); 151 game->entities[game->entities_len] = (entity_t) { 152 .type = ENTITY_GATE, 153 .gate = gate, 154 }; 155 game->entities_len++; 156 break; 157 } 158 default: 159 break; 160 } 161 } 162 } 163 } 164 165 void level_load(game_t *game, level_e type) { 166 level_t *level = malloc(sizeof(level_t)); 167 level->type = type; 168 switch (type) { 169 case LEVEL_NULL: 170 break; 171 case LEVEL_1: { 172 level_generate(game, LEVEL_MAP_1, 24, 16); 173 level->width = 24; 174 level->height = 16; 175 break; 176 } 177 case LEVEL_2: { 178 level_generate(game, LEVEL_MAP_2, 24, 16); 179 level->width = 24; 180 level->height = 16; 181 break; 182 } 183 case LEVEL_3: { 184 level_generate(game, LEVEL_MAP_3, 40, 30); 185 level->width = 40; 186 level->height = 30; 187 break; 188 } 189 } 190 game->level = level; 191 } 192 193 void level_unload(game_t *game) { 194 player_free(game->player); 195 for (int i = 0; i < game->tiles_len; i++) { 196 tile_free(game->tiles[i]); 197 } 198 free(game->tiles); 199 for (int i = 0; i < game->entities_len; i++) { 200 entity_detach(&game->entities[i]); 201 } 202 free(game->entities); 203 for (int i = 0; i < game->effects_len; i++) { 204 effect_free(game->effects[i]); 205 } 206 free(game->effects); 207 free(game->level); 208 }