game.c (6393B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 #include "libs/raylib.h" 6 #include "entity.h" 7 #include "game.h" 8 #include "tile.h" 9 #include "util.h" 10 #include "player.h" 11 #include "const.h" 12 #include "level.h" 13 14 game_t *game_create(void) { 15 game_t *game = malloc(sizeof(game_t)); 16 game->state = STATE_GAME; 17 game->level = NULL, 18 game->quit = false; 19 game->defeat = false; 20 game->victory = false; 21 game->menu = menu_create(); 22 game->player = NULL; 23 game->tiles = NULL; 24 game->tiles_len = 0; 25 game->entities = NULL; 26 game->entities_len = 0; 27 game->effects = NULL; 28 game->effects_len = 0; 29 game->assets.tiles = texture_load("assets/tiles.png", SCALE); 30 game->assets.entities = texture_load("assets/entities.png", SCALE); 31 game->assets.font = texture_load("assets/font.png", SCALE - 1); 32 game->assets.images = texture_load("assets/images.png", SCALE); 33 game->camera = (Camera2D) { 34 .offset = (pos_t) { 0.0, 0.0 }, 35 .zoom = 1, 36 }; 37 game->xp = 0; 38 game->sceen_timer = 0; 39 level_load(game, LEVEL_1); 40 return game; 41 } 42 43 void game_update(game_t *game) { 44 switch (game->state) { 45 case STATE_MENU: { 46 menu_update(game->menu, game); 47 break; 48 } 49 case STATE_GAME: { 50 if (IsKeyPressed(KEY_ESCAPE)) { 51 game->state = STATE_MENU; 52 game->menu->idx = 0; 53 } 54 if (game->level != NULL) { 55 // defeat 56 if (game->defeat) { 57 if (game->sceen_timer == 100) { 58 level_unload(game); 59 level_load(game, LEVEL_1); 60 game->defeat = false; 61 game->xp = 0; 62 game->sceen_timer = 0; 63 } 64 else { 65 game->sceen_timer++; 66 } 67 } 68 // victory 69 int enemies_len = 0; 70 bool gates_frozen = true; 71 for (int i = 0; i < game->entities_len; i++) { 72 if(game->entities[i].type == ENTITY_ENEMY) { 73 enemies_len++; 74 } 75 if(game->entities[i].type == ENTITY_GATE) { 76 if (!game->entities[i].gate->frozen) { 77 gates_frozen = false; 78 } 79 } 80 } 81 if (enemies_len == 0 && gates_frozen) { 82 game->victory = true; 83 if (game->victory) { 84 if (game->sceen_timer == 100) { 85 if (game->level->type < LEVELS) { 86 level_e level = game->level->type; 87 level++; 88 level_unload(game); 89 level_load(game, level); 90 } 91 game->victory = false; 92 game->sceen_timer = 0; 93 } 94 else { 95 game->sceen_timer++; 96 } 97 } 98 } 99 if (!game->victory && !game->defeat) { 100 player_update(game->player, game); 101 } 102 for (int i = 0; i < game->tiles_len; i++) { 103 tile_update(game->tiles[i], game); 104 } 105 for (int i = 0; i < game->entities_len; i++) { 106 int len = game->entities_len; 107 entity_update(&game->entities[i], game); 108 // check if entity was removed 109 if (game->entities_len < len) { 110 i--; 111 } 112 } 113 for (int i = 0; i < game->effects_len; i++) { 114 int len = game->effects_len; 115 effect_update(game->effects[i], game); 116 // check if enemy was removed 117 if (game->effects_len < len) { 118 i--; 119 } 120 } 121 pos_t camera_pos = (pos_t) { 122 .x = WINDOW_WIDTH / 2.0 - game->player->pos.x - PLAYER_WIDTH / 2.0, 123 .y = WINDOW_HEIGHT / 2.0 - game->player->pos.y, 124 }; 125 if (camera_pos.x > 0.0) { 126 camera_pos.x = 0.0; 127 } 128 if (camera_pos.x + TILE_WIDTH * game->level->width < WINDOW_WIDTH) { 129 camera_pos.x = WINDOW_WIDTH - TILE_WIDTH * game->level->width; 130 } 131 if (camera_pos.y > 0.0) { 132 camera_pos.y = 0.0; 133 } 134 if (camera_pos.y + TILE_HEIGHT * game->level->height < WINDOW_HEIGHT) { 135 camera_pos.y = WINDOW_HEIGHT - TILE_HEIGHT * game->level->height; 136 } 137 game->camera.offset = pos_snap(camera_pos); 138 } 139 break; 140 } 141 } 142 } 143 144 void game_draw(game_t *game) { 145 BeginDrawing(); 146 ClearBackground(BLACK); 147 if (game->level != LEVEL_NULL) { 148 BeginMode2D(game->camera); 149 for (int i = 0; i < game->tiles_len; i++) { 150 tile_draw(game->tiles[i], game); 151 } 152 for (int i = 0; i < game->entities_len; i++) { 153 entity_draw(&game->entities[i], game); 154 } 155 player_draw(game->player, game); 156 for (int i = 0; i < game->effects_len; i++) { 157 effect_draw(game->effects[i], game); 158 } 159 EndMode2D(); 160 // draw interface 161 int i = 0; 162 for (i = 0; i < game->player->health / 2; i++) { 163 DrawTextureRec(game->assets.tiles, texture_rect(0, 1, TILE_WIDTH, TILE_HEIGHT), (pos_t) { TILE_WIDTH / 2.0 + i * (TILE_WIDTH + TILE_WIDTH / 4.0), TILE_WIDTH / 2.0 }, WHITE); 164 } 165 if (game->player->health % 2 != 0) { 166 DrawTextureRec(game->assets.tiles, texture_rect(1, 1, TILE_WIDTH, TILE_HEIGHT), (pos_t) { TILE_WIDTH / 2.0 + i * (TILE_WIDTH + TILE_WIDTH / 4.0), TILE_WIDTH / 2.0 }, WHITE); 167 i++; 168 } 169 for (; i < PLAYER_HEALTH / 2; i++) { 170 DrawTextureRec(game->assets.tiles, texture_rect(2, 1, TILE_WIDTH, TILE_HEIGHT), (pos_t) { TILE_WIDTH / 2.0 + i * (TILE_WIDTH + TILE_WIDTH / 4.0), TILE_WIDTH / 2.0 }, WHITE); 171 } 172 char xp_text[10]; 173 snprintf(xp_text, 10, "%dXP", game->xp); 174 pos_t xp_pos = (pos_t) { 175 .x = WINDOW_WIDTH - TILE_WIDTH / 2.0, 176 .y = TILE_WIDTH / 1.5, 177 }; 178 text_draw(xp_pos, xp_text, TEXT_ALIGNMENT_RIGHT, game); 179 char level_text[10]; 180 snprintf(level_text, 10, "L%d", game->level->type); 181 pos_t level_pos = (pos_t) { 182 .x = WINDOW_WIDTH - TILE_WIDTH / 2.0, 183 .y = TILE_WIDTH / 1.5 + 25, 184 }; 185 text_draw(level_pos, level_text, TEXT_ALIGNMENT_RIGHT, game); 186 if (game->defeat || game->victory) { 187 DrawRectangle(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, (Color) { 0, 0, 0, 255 / 100 * game->sceen_timer }); 188 } 189 } 190 if (game->state == STATE_MENU) { 191 menu_draw(game->menu, game); 192 } 193 EndDrawing(); 194 } 195 196 void game_free(game_t *game) { 197 menu_free(game->menu); 198 if (game->level != LEVEL_NULL) { 199 level_unload(game); 200 } 201 UnloadTexture(game->assets.tiles); 202 UnloadTexture(game->assets.entities); 203 UnloadTexture(game->assets.font); 204 UnloadTexture(game->assets.images); 205 free(game); 206 }