Compare commits

...

4 Commits

Author SHA1 Message Date
En Yi fb0f16d984 Add addr sanitisation for main game 2024-08-24 00:26:17 +08:00
En Yi 24b407fec2 Free level select scene on exit 2024-08-24 00:26:05 +08:00
En Yi 03a4240c6d Simplify and unify level restarting
Changelog:
- Add function to clear all game entities
- This functions is called in both editor and main game
2024-08-24 00:25:33 +08:00
En Yi 2fe3faf08f Update exit rendering 2024-08-24 00:23:17 +08:00
6 changed files with 57 additions and 40 deletions

View File

@ -34,6 +34,10 @@ add_executable(${PROJECT_NAME}
main.c
)
if (NOT EMSCRIPTEN)
target_compile_options(${PROJECT_NAME} PRIVATE -fsanitize=address -gdwarf-4)
target_link_options(${PROJECT_NAME} PRIVATE -fsanitize=address -gdwarf-4)
endif ()
target_include_directories(${PROJECT_NAME}
PRIVATE
${CMAKE_CURRENT_LIST_DIR}

2
main.c
View File

@ -116,10 +116,10 @@ int main(void)
{
sc_queue_clear(&key_buffer);
}
}
free_sandbox_scene(&sandbox_scene);
free_game_scene(&level_scene);
free_level_select_scene(&level_sel_scene);
free_menu_scene(&menu_scene);
deinit_engine(&engine);
}

View File

@ -266,7 +266,13 @@ static void render_editor_game_scene(Scene_t* scene)
if (p_cspr->flip_x) offset.x *= -1;
pos = Vector2Add(pos, offset);
draw_sprite(spr.sprite, (data->coins.current < data->coins.total) ? 0 : 1, pos, 0.0f, p_cspr->flip_x);
draw_sprite(
spr.sprite,
2 * data->selected_solid_tilemap + (
(data->coins.current < data->coins.total) ? 0 : 1
),
pos, 0.0f, p_cspr->flip_x
);
}
}
else
@ -838,40 +844,14 @@ static void restart_editor_level(Scene_t* scene)
tilemap.tiles[i].water_level = 0;
tilemap.tiles[i].wet = false;
tilemap.tiles[i].size = (Vector2){TILE_SIZE, TILE_SIZE};
Entity_t* ent;
unsigned int m_id;
sc_map_foreach(&tilemap.tiles[i].entities_set, m_id, ent)
{
if (ent->m_tag == PLAYER_ENT_TAG) continue;
CTileCoord_t* p_tilecoord = get_component(
ent, CTILECOORD_COMP_T
);
for (size_t i = 0;i < p_tilecoord->n_tiles; ++i)
{
// Use previously store tile position
// Clear from those positions
unsigned int tile_idx = p_tilecoord->tiles[i];
sc_map_del_64v(&(tilemap.tiles[tile_idx].entities_set), m_id);
}
//remove_entity(&scene->ent_manager, m_id);
CWaterRunner_t* p_crunner = get_component(ent, CWATERRUNNER_T);
if (p_crunner == NULL)
{
remove_entity(&scene->ent_manager, m_id);
}
else
{
free_water_runner(ent, &scene->ent_manager);
}
}
}
Entity_t* p_ent;
sc_map_foreach_value(&scene->ent_manager.entities_map[LEVEL_END_TAG], p_ent)
{
remove_entity(&scene->ent_manager, p_ent->m_id);
}
clear_all_game_entities(CONTAINER_OF(scene, LevelScene_t, scene));
Entity_t* p_player = create_player(&scene->ent_manager);
p_player->position = data->player_spawn;
update_entity_manager(&scene->ent_manager);
for (size_t i = 0; i < tilemap.width; ++i)
{
unsigned int tile_idx = (tilemap.height - 1) * tilemap.width + i;
@ -1080,7 +1060,10 @@ static void level_do_action(Scene_t* scene, ActionType_t action, bool pressed)
break;
case ACTION_NEXTLEVEL:
case ACTION_RESTART:
restart_editor_level(scene);
if (!pressed)
{
restart_editor_level(scene);
}
break;
case ACTION_TOGGLE_GRID:
if (!pressed)
@ -1224,7 +1207,7 @@ void init_sandbox_scene(LevelScene_t* scene)
p_cspr->flip_x = true;
p_player->position.x = 100;
p_player->position.y = (scene->data.tilemap.height - 2) * scene->data.tilemap.tile_size;
p_player->position.y = (scene->data.tilemap.height - 1) * scene->data.tilemap.tile_size - PLAYER_HEIGHT;
scene->data.player_spawn = p_player->position;
scene->data.camera.target_pos = p_player->position;
scene->data.camera.cam.target = p_player->position;
@ -1473,6 +1456,7 @@ void init_sandbox_scene(LevelScene_t* scene)
void free_sandbox_scene(LevelScene_t* scene)
{
clear_all_game_entities(scene);
free_scene(&scene->scene);
term_level_scene_data(&scene->data);
}

View File

@ -195,7 +195,13 @@ static void render_regular_game_scene(Scene_t* scene)
if (p_cspr->flip_x) offset.x *= -1;
pos = Vector2Add(pos, offset);
draw_sprite(spr.sprite, (data->coins.current < data->coins.total) ? 0 : 1, pos, 0.0f, p_cspr->flip_x);
draw_sprite(
spr.sprite,
2 * data->selected_solid_tilemap + (
(data->coins.current < data->coins.total) ? 0 : 1
),
pos, 0.0f, p_cspr->flip_x
);
}
}
else
@ -562,6 +568,7 @@ void init_game_scene(LevelScene_t* scene)
void free_game_scene(LevelScene_t* scene)
{
clear_all_game_entities(scene);
free_scene(&scene->scene);
term_level_scene_data(&scene->data);
}

View File

@ -94,6 +94,7 @@ void free_game_scene(LevelScene_t* scene);
void init_sandbox_scene(LevelScene_t* scene);
void free_sandbox_scene(LevelScene_t* scene);
void init_level_scene_data(LevelSceneData_t* data, uint32_t max_tiles, Tile_t* tiles, Rectangle view_zone);
void clear_all_game_entities(LevelScene_t* scene);
void term_level_scene_data(LevelSceneData_t* data);
void reload_level_tilemap(LevelScene_t* scene);
void load_next_level_tilemap(LevelScene_t* scene);

View File

@ -53,6 +53,29 @@ void term_level_scene_data(LevelSceneData_t* data)
}
}
void clear_all_game_entities(LevelScene_t* scene)
{
Entity_t* ent;
sc_map_foreach_value(&scene->scene.ent_manager.entities, ent)
{
CWaterRunner_t* p_crunner = get_component(ent, CWATERRUNNER_T);
if (p_crunner != NULL)
{
free_water_runner(ent, &scene->scene.ent_manager);
}
CEmitter_t* p_emitter = get_component(ent, CEMITTER_T);
if (p_emitter != NULL)
{
unload_emitter_handle(&scene->scene.part_sys, p_emitter->handle);
}
}
clear_entity_manager(&scene->scene.ent_manager);
for (size_t i = 0; i < scene->data.tilemap.n_tiles;i++)
{
sc_map_clear_64v(&scene->data.tilemap.tiles[i].entities_set);
}
}
bool load_level_tilemap(LevelScene_t* scene, unsigned int level_num)
{
if (level_num >= scene->data.level_pack->n_levels) return false;
@ -68,7 +91,7 @@ bool load_level_tilemap(LevelScene_t* scene, unsigned int level_num)
scene->data.coins.current = 0;
scene->data.coins.total = lvl_map.n_chests;
clear_entity_manager(&scene->scene.ent_manager);
clear_all_game_entities(scene);
for (size_t i = 0; i < scene->data.tilemap.n_tiles;i++)
{
@ -81,8 +104,6 @@ bool load_level_tilemap(LevelScene_t* scene, unsigned int level_num)
scene->data.tilemap.tiles[i].offset = (Vector2){0, 0};
scene->data.tilemap.tiles[i].size = (Vector2){TILE_SIZE, TILE_SIZE};
scene->data.tilemap.tiles[i].def = 0;
sc_map_clear_64v(&scene->data.tilemap.tiles[i].entities_set);
if (lvl_map.tiles[i].tile_type == 1)
{
@ -279,7 +300,7 @@ void change_a_tile(TileGrid_t* tilemap, unsigned int tile_idx, TileType_t new_ty
}
else if ((tile_idx + 1) % tilemap->width != 0 && tilemap->tiles[tile_idx + 1].tile_type == SOLID_TILE)
{
tilemap->tiles[tile_idx].offset = (Vector2){SPIKE_HITBOX_SHORTSIDE >> 1,0};
tilemap->tiles[tile_idx].offset = (Vector2){tilemap->tile_size - SPIKE_HITBOX_SHORTSIDE,0};
tilemap->tiles[tile_idx].size = (Vector2){SPIKE_HITBOX_SHORTSIDE, SPIKE_HITBOX_LONGSIDE};
tilemap->tiles[tile_idx].rotation = TILE_90CCWROT;
}