RogueLife/src/game.c

122 lines
3.0 KiB
C
Raw Normal View History

2021-06-04 15:14:12 +02:00
#include "game.h"
#include <stdlib.h>
bool game_load(game_t *g, level_t *level)
{
game_unload(g);
map_t *m = &g->map;
m->width = level->width;
m->height = level->height;
m->tiles = malloc(m->width * m->height * sizeof *m->tiles);
if(!m->tiles) {
game_unload(g);
return false;
}
for(int y = 0; y < m->height; y++)
for(int x = 0; x < m->width; x++) {
struct tile *t = map_tile(m, x, y);
t->base = level->tiles[level->width * y + x].base;
t->decor = level->tiles[level->width * y + x].decor;
t->solid = (t->base == 0) || (t->base >= 16);
}
camera_init(&g->camera, m);
g->entities = NULL;
g->entity_count = 0;
return true;
}
void game_unload(game_t *g)
{
g->map.width = 0;
g->map.height = 0;
free(g->map.tiles);
for(int i = 0; i < g->entity_count; i++)
free(g->entities[i]);
free(g->entities);
}
void game_add_entity(game_t *g, entity_t *entity)
{
size_t new_size = (g->entity_count + 1) * sizeof *g->entities;
entity_t **new_entities = realloc(g->entities, new_size);
if(!new_entities) return;
g->entities = new_entities;
g->entities[g->entity_count] = entity;
g->entity_count++;
}
void game_add_effect_area(game_t *g, effect_area_t *ea)
{
size_t new_size = (g->effect_area_count + 1) * sizeof *g->effect_areas;
effect_area_t **new_effect_areas = realloc(g->effect_areas, new_size);
if(!new_effect_areas) return;
g->effect_areas = new_effect_areas;
g->effect_areas[g->effect_area_count] = ea;
g->effect_area_count++;
}
/* Remove an effect area and rearrange the array. */
static void game_remove_effect_area(game_t *g, int i)
{
if(i < 0 || i >= g->effect_area_count) return;
free(g->effect_areas[i]);
g->effect_areas[i] = g->effect_areas[--g->effect_area_count];
/* Don't realloc, we'll likely add new areas soon enough and space will be
reclaimed as needed at that time. Don't need to add heap work now. */
}
/* Remove all dead effect areas */
static void game_remove_dead_effect_areas(game_t *g)
{
int i = 0;
while(i < g->effect_area_count) {
effect_area_t *ea = g->effect_areas[i];
if(ea->lifetime <= 0)
game_remove_effect_area(g, i);
else
i++;
}
}
bool game_rect_collides(game_t *g, entity_t const *e, frect_t hitbox)
2021-06-04 15:14:12 +02:00
{
/* Collision against map */
if(map_entity_collides(&g->map, hitbox))
return true;
return false;
}
2021-06-09 20:47:39 +02:00
void game_update_animations(game_t *g, fixed_t dt)
{
for(int i = 0; i < g->entity_count; i++) {
entity_t *e = g->entities[i];
anim_state_update(&e->anim, dt);
}
for(int i = 0; i < g->effect_area_count; i++) {
effect_area_t *ea = g->effect_areas[i];
anim_state_update(&ea->anim, dt);
}
}
void game_update_effect_areas(game_t *g, fixed_t dt)
{
for(int i = 0; i < g->effect_area_count; i++) {
effect_area_t *ea = g->effect_areas[i];
ea->lifetime -= dt;
}
game_remove_dead_effect_areas(g);
2021-06-09 20:47:39 +02:00
}