QUOTE: Enjoy small things, cherish moments.

freezo

A retro platform game

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
      9const 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
     28const 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
     47const 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
     66const 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
     85const 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
    104void 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
    247void 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
    287void 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}