Simplify and unify level restarting

Changelog:
- Add function to clear all game entities
- This functions is called in both editor and main game
main
En Yi 2024-08-24 00:25:33 +08:00
parent 2fe3faf08f
commit 03a4240c6d
4 changed files with 38 additions and 37 deletions

View File

@ -844,40 +844,14 @@ static void restart_editor_level(Scene_t* scene)
tilemap.tiles[i].water_level = 0; tilemap.tiles[i].water_level = 0;
tilemap.tiles[i].wet = false; tilemap.tiles[i].wet = false;
tilemap.tiles[i].size = (Vector2){TILE_SIZE, TILE_SIZE}; 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); update_entity_manager(&scene->ent_manager);
for (size_t i = 0; i < tilemap.width; ++i) for (size_t i = 0; i < tilemap.width; ++i)
{ {
unsigned int tile_idx = (tilemap.height - 1) * tilemap.width + i; unsigned int tile_idx = (tilemap.height - 1) * tilemap.width + i;
@ -1086,7 +1060,10 @@ static void level_do_action(Scene_t* scene, ActionType_t action, bool pressed)
break; break;
case ACTION_NEXTLEVEL: case ACTION_NEXTLEVEL:
case ACTION_RESTART: case ACTION_RESTART:
restart_editor_level(scene); if (!pressed)
{
restart_editor_level(scene);
}
break; break;
case ACTION_TOGGLE_GRID: case ACTION_TOGGLE_GRID:
if (!pressed) if (!pressed)
@ -1230,7 +1207,7 @@ void init_sandbox_scene(LevelScene_t* scene)
p_cspr->flip_x = true; p_cspr->flip_x = true;
p_player->position.x = 100; 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.player_spawn = p_player->position;
scene->data.camera.target_pos = p_player->position; scene->data.camera.target_pos = p_player->position;
scene->data.camera.cam.target = p_player->position; scene->data.camera.cam.target = p_player->position;
@ -1479,6 +1456,7 @@ void init_sandbox_scene(LevelScene_t* scene)
void free_sandbox_scene(LevelScene_t* scene) void free_sandbox_scene(LevelScene_t* scene)
{ {
clear_all_game_entities(scene);
free_scene(&scene->scene); free_scene(&scene->scene);
term_level_scene_data(&scene->data); term_level_scene_data(&scene->data);
} }

View File

@ -568,6 +568,7 @@ void init_game_scene(LevelScene_t* scene)
void free_game_scene(LevelScene_t* scene) void free_game_scene(LevelScene_t* scene)
{ {
clear_all_game_entities(scene);
free_scene(&scene->scene); free_scene(&scene->scene);
term_level_scene_data(&scene->data); 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 init_sandbox_scene(LevelScene_t* scene);
void free_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 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 term_level_scene_data(LevelSceneData_t* data);
void reload_level_tilemap(LevelScene_t* scene); void reload_level_tilemap(LevelScene_t* scene);
void load_next_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) bool load_level_tilemap(LevelScene_t* scene, unsigned int level_num)
{ {
if (level_num >= scene->data.level_pack->n_levels) return false; 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.current = 0;
scene->data.coins.total = lvl_map.n_chests; 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++) 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].offset = (Vector2){0, 0};
scene->data.tilemap.tiles[i].size = (Vector2){TILE_SIZE, TILE_SIZE}; scene->data.tilemap.tiles[i].size = (Vector2){TILE_SIZE, TILE_SIZE};
scene->data.tilemap.tiles[i].def = 0; 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) 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) 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].size = (Vector2){SPIKE_HITBOX_SHORTSIDE, SPIKE_HITBOX_LONGSIDE};
tilemap->tiles[tile_idx].rotation = TILE_90CCWROT; tilemap->tiles[tile_idx].rotation = TILE_90CCWROT;
} }