QUOTE: Be the change, make a difference.

level.c - freezo - A retro platform game

freezo

A retro platform game
git clone git@soophie.de:/srv/git/freezo
log | files | refs | readme

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 }