NEWS: Welcome to my new homepage! <3

game.c - freezo - A retro platform game

freezo

A retro platform game
git clone git://192.168.2.2/freezo
Log | Files | Refs | README

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 }