so://phie

freezo

A retro platform game
git clone git://soophie.de/freezo

blob: c812a09052e75a9d184bfec81eddff7709f1c062 (8225 bytes)[raw]

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}