diff options
Diffstat (limited to 'game-state.c')
-rw-r--r-- | game-state.c | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/game-state.c b/game-state.c new file mode 100644 index 0000000..420c6d9 --- /dev/null +++ b/game-state.c @@ -0,0 +1,150 @@ +#include "game-state.h" +#include <stdlib.h> + +/* const int ENEMY_COUNT_MAX = 1000; */ +/* const int TOWER_COUNT_MAX = 5; */ +const enemy_spawner_t DEFAULT_ENEMY_SPAWNER = { + .border = { .x = 0, .y = 0, .width = WINDOW_WIDTH, .height = WINDOW_HEIGHT }, + .cooldown = 100.0f, + .cooldown_max = 100.0f +}; + +float mouse_x(gs_t *gs){ + Camera2D *cam = &gs->player.camera; + return cam->target.x + GetMouseX() - cam->offset.x; +} + +float mouse_y(gs_t *gs){ + Camera2D *cam = &gs->player.camera; + return cam->target.y + GetMouseY() - cam->offset.y; +} + +void add_tower(gs_t *gs, tower_t tower){ + if (gs->tower_count == TOWER_COUNT_MAX){ + return; + } + gs->towers[gs->tower_count++] = tower; +} + +void add_enemy(gs_t *gs, enemy_t enemy){ + if (gs->enemy_count == ENEMY_COUNT_MAX){ + return; + } + gs->enemies[gs->enemy_count++] = enemy; +} + +void add_beam(gs_t *gs, tower_beam_t beam){ + if (gs->beam_count == MAX_BEAM_COUNT){ + return; + } + gs->beams[gs->beam_count++] = beam; +} + +void kill_enemy(gs_t *gs, int index){ + /* enemy_t temp = gs->enemies[index]; */ + gs->enemies[index].active = 0; + gs->enemies[index] = gs->enemies[gs->enemy_count - 1]; + /* gs->enemies[gs->enemy_count] = temp; */ + gs->enemy_count--; + /* printf("enemy <%d> killed\n", index); */ +} + +void update_game(gs_t *gs, float dt){ + update_player(&gs->player, dt); + for (int i = 0; i < gs->enemy_count; i++){ + update_enemy(gs->enemies + i, gs->player.position, dt); + } + for (int i = 0; i < gs->tower_count; i++){ + update_tower(&gs->towers[i], dt); + } + for (int i = 0; i < gs->tower_count; i++){ + tower_t *tow = &gs->towers[i]; + if (tow->cooldown <= 0){ + for (int j = 0; j < gs->enemy_count; j++){ + enemy_t *e = &gs->enemies[j]; + if /* (distance(gs->towers[i].center, gs->enemies[j].center) */ + /* < gs->towers[i].range) */ + (e->active && CheckCollisionCircleRec(tow->center, tow->range, e->hitbox)){ + add_beam(gs, make_beam(tow->position, + /* gs->enemies[j].center */ + e->position, 0.1)); + e->health -= tow->damage; + tow->cooldown = tow->cooldown_max; + PlaySound(BEAM_SOUND); + if (e->health <= 0){ + kill_enemy(gs, j); + } + break; + } + } + } + } + for (int i = 0; i < gs->enemy_count; i++){ + if (CheckCollisionRecs(gs->enemies[i].hitbox, gs->player.hitbox)){ + int remaining = take_damage(&gs->player, 1); + if (remaining == 0){ + Camera2D camera = gs->player.camera; + gs->player = make_player(&textures[T_PLAYER]); + gs->player.camera.zoom = camera.zoom; + } + /* printf("collision\n"); */ + } + } + for (int i = 0; i < gs->beam_count; i++){ + gs->beams[i].live_time -= dt; + if (gs->beams[i].live_time <= 0){ + gs->beams[i] = gs->beams[gs->beam_count]; + gs->beam_count--; + } + } + + if (can_spawn(&gs->spawner) && gs->enemy_count < ENEMY_COUNT_MAX){ + add_enemy(gs, spawn_enemy(&gs->spawner)); + } + update_spawner(&gs->spawner, dt); + + if (IsKeyPressed(KEY_T)){ + add_tower(gs, make_tower(1, 100, mouse_x(gs), mouse_y(gs), 20, 30, &textures[T_TOWER])); + } + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) { + paint_tile(gs); + } +} + +void draw_game(gs_t *gs){ + draw_player(&gs->player); + for (int i = 0; i < gs->tower_count; i++){ + draw_tower(gs->towers + i); + } + for (int i = 0; i < gs->enemy_count; i++){ + draw_enemy(gs->enemies + i); + } + for (int i = 0; i < gs->beam_count; i++){ + DrawLineV(gs->beams[i].src, gs->beams[i].dest, MAGENTA); + } + /* if (IsKeyDown(KEY_E)){ */ + + /* } */ + DrawCircle(mouse_x(gs), mouse_y(gs), 5, VIOLET); +} + +void paint_tile(gs_t *gs){ + float zoom = gs->player.camera.zoom; + float edge_len = 16 / zoom; + Camera2D *c = &gs->player.camera; + int edge = edge_len * c->zoom; + int x = mouse_x(gs) / edge; + int y = (WINDOW_HEIGHT - mouse_y(gs)) / edge; + /* int y = (GetMouseY() - gs.player.camera.target.y) / edge_len; */ + printf("drawing tile(%d, %d) at %d %d\n", x, y, x * edge, y * edge); + if /* (x >= 0 && x < WINDOW_WIDTH && y >= 0 && y < WINDOW_HEIGHT) */ + (1){ + BeginTextureMode(gs->bg_tiles); + DrawTextureRec(gs->textures[T_DIRT], (Rectangle){ 0, 0, 16, 16 }, + (Vector2){x * edge /* / zoom */, y * edge /* / zoom */} + /* (Vector2){0, edge_len * yy} */ + , WHITE); + EndTextureMode(); + /* yy++; */ + } +} |