A retro platform game
git clone git://soophie.de/freezo
blob: c812a09052e75a9d184bfec81eddff7709f1c062 (8225 bytes)[raw]
1
#include <stdlib.h>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"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
};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
};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
};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
};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
};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 types123
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 entities176
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
}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
}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
}