126 lines
3.5 KiB
C
126 lines
3.5 KiB
C
// Copyright 2025 Bill Rossi
|
|
//
|
|
// This file is part of Starship Futuretime
|
|
//
|
|
// Starship Futuretime is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
//
|
|
// Starship Futuretime is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License along with Starship Futuretime. If not, see <https://www.gnu.org/licenses/>.
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
#include <raylib.h>
|
|
|
|
#include "game.h"
|
|
#include "enemy.h"
|
|
#include "bullet.h"
|
|
|
|
#define FOREACH_ENEMY for (size_t i = 0; i < g->enemies->count; i++)
|
|
#define INIT_ENEMY Entity *e = g->enemies->entities[i]
|
|
#define FOREACH_BULLET for (size_t i = 0; i < g->bullets->count; i++)
|
|
#define INIT_BULLET Entity *e = g->bullets->entities[i]
|
|
|
|
void initialize_game(Game *g) {
|
|
g->should_close = false;
|
|
g->player = malloc(sizeof(Player));
|
|
initialize_player(g->player);
|
|
g->enemies = malloc(sizeof(Entities));
|
|
g->enemies->entities = malloc(10 * sizeof(Entity*));
|
|
g->enemies->count = 0;
|
|
g->enemies->capacity = 10;
|
|
g->bullets = malloc(sizeof(Entities));
|
|
g->bullets->entities = malloc(10 * sizeof(Entity*));
|
|
g->bullets->count = 0;
|
|
g->bullets->capacity = 10;
|
|
}
|
|
|
|
void add_entity(Entities *entities, Entity *e) {
|
|
if (entities->count >= entities->capacity) {
|
|
entities->capacity *= 2;
|
|
entities->entities = realloc(entities->entities, entities->capacity * sizeof(Entity*));
|
|
}
|
|
entities->entities[entities->count++] = e;
|
|
}
|
|
|
|
void remove_entity(Entities *entities, Entity *e) {
|
|
size_t i;
|
|
for (i = 0; entities->entities[i] != e; i++) {
|
|
if (i > entities->count) {
|
|
printf("Couldn't find entity %s\n", e->name);
|
|
return;
|
|
}
|
|
}
|
|
for (; i < entities->count - 1; i++) {
|
|
entities->entities[i] = entities->entities[i + 1];
|
|
}
|
|
entities->count--;
|
|
}
|
|
|
|
void handle_input(Game *g) {
|
|
handle_player_input(g->player);
|
|
if (IsKeyPressed(KEY_S)) {
|
|
add_entity(g->enemies, spawn_enemy());
|
|
}
|
|
if (IsKeyPressed(KEY_SPACE)) {
|
|
add_entity(g->bullets, spawn_bullet(g->player->position));
|
|
}
|
|
}
|
|
|
|
void process_bullet_collisions(Game *g, Entity *bullet) {
|
|
FOREACH_ENEMY {
|
|
INIT_ENEMY;
|
|
Rectangle bullet_rec = ((BulletProperties*)bullet->properties)->position;
|
|
Rectangle enemy_rec = ((EnemyProperties*)e->properties)->position;
|
|
if (CheckCollisionRecs(bullet_rec, enemy_rec)) {
|
|
remove_entity(g->bullets, bullet);
|
|
remove_entity(g->enemies, e);
|
|
}
|
|
}
|
|
}
|
|
|
|
void run_frame(Game *g) {
|
|
handle_input(g);
|
|
move_player(g->player);
|
|
FOREACH_ENEMY {
|
|
INIT_ENEMY;
|
|
if (entity_expired(e)) {
|
|
remove_entity(g->enemies, e);
|
|
continue;
|
|
}
|
|
e->tick(e, GetFrameTime());
|
|
}
|
|
|
|
FOREACH_BULLET {
|
|
INIT_BULLET;
|
|
if (entity_expired(e)) {
|
|
remove_entity(g->bullets, e);
|
|
continue;
|
|
}
|
|
e->tick(e, GetFrameTime());
|
|
process_bullet_collisions(g, e);
|
|
}
|
|
}
|
|
|
|
void draw_frame(Game *g) {
|
|
BeginDrawing();
|
|
ClearBackground(RAYWHITE);
|
|
draw_player(g->player);
|
|
FOREACH_ENEMY {
|
|
INIT_ENEMY;
|
|
e->draw(e);
|
|
}
|
|
FOREACH_BULLET {
|
|
INIT_BULLET;
|
|
e->draw(e);
|
|
}
|
|
EndDrawing();
|
|
}
|
|
|
|
void run_until_closing(Game *g) {
|
|
while (!WindowShouldClose() && !g->should_close) {
|
|
run_frame(g);
|
|
draw_frame(g);
|
|
}
|
|
}
|