From c7ef3f473f93c70753bf0ba5480ad869bbecb689 Mon Sep 17 00:00:00 2001 From: En Yi Date: Thu, 22 Jun 2023 23:14:07 +0800 Subject: [PATCH] Add spike destruction Changelog: - Spike collision is now checked against all bboxes - Non player will destroy it - Add moveable flag for each tile to determine whether a boulder can move into it --- scenes/editor_scene.c | 14 +++++++++++++- scenes/game_systems.c | 43 ++++++++++++++++++++++++++----------------- scenes/game_systems.h | 2 +- scenes/scene_impl.h | 1 + 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/scenes/editor_scene.c b/scenes/editor_scene.c index 1a33279..8d515e9 100644 --- a/scenes/editor_scene.c +++ b/scenes/editor_scene.c @@ -98,6 +98,12 @@ static void level_scene_render_func(Scene_t* scene) Color water_colour = ColorAlpha(BLUE, 0.5); DrawRectangle(x, y, TILE_SIZE, TILE_SIZE, water_colour); } + if (tilemap.tiles[i].moveable) + { + // Draw water tile + Color water_colour = ColorAlpha(GREEN, 0.2); + DrawRectangle(x, y, TILE_SIZE, TILE_SIZE, water_colour); + } } char buffer[64] = {0}; @@ -390,6 +396,10 @@ static void toggle_block_system(Scene_t* scene) tilemap.tiles[tile_idx].size = (Vector2){32,32}; } last_tile_idx = tile_idx; + tilemap.tiles[tile_idx].moveable = ( + tilemap.tiles[tile_idx].tile_type == EMPTY_TILE + || tilemap.tiles[tile_idx].tile_type == SPIKES + ); } } else if (IsMouseButtonDown(MOUSE_RIGHT_BUTTON)) @@ -493,7 +503,7 @@ void init_level_scene(LevelScene_t* scene) sc_array_add(&scene->scene.systems, &update_tilemap_system); sc_array_add(&scene->scene.systems, &hitbox_update_system); sc_array_add(&scene->scene.systems, &player_crushing_system); - sc_array_add(&scene->scene.systems, &player_spike_collision_system); + sc_array_add(&scene->scene.systems, &spike_collision_system); sc_array_add(&scene->scene.systems, &state_transition_update_system); sc_array_add(&scene->scene.systems, &player_ground_air_transition_system); sc_array_add(&scene->scene.systems, &sprite_animation_system); @@ -524,6 +534,7 @@ void init_level_scene(LevelScene_t* scene) { all_tiles[i].solid = NOT_SOLID; all_tiles[i].tile_type = EMPTY_TILE; + all_tiles[i].moveable = true; sc_map_init_64v(&all_tiles[i].entities_set, 16, 0); all_tiles[i].size = (Vector2){TILE_SIZE, TILE_SIZE}; } @@ -532,6 +543,7 @@ void init_level_scene(LevelScene_t* scene) unsigned int tile_idx = (scene->data.tilemap.height - 1) * scene->data.tilemap.width + i; all_tiles[tile_idx].solid = SOLID; // for testing all_tiles[tile_idx].tile_type = SOLID_TILE; // for testing + all_tiles[tile_idx].moveable = false; } create_player(&scene->scene.ent_manager, &scene->scene.engine->assets); diff --git a/scenes/game_systems.c b/scenes/game_systems.c index d14013d..161fa03 100644 --- a/scenes/game_systems.c +++ b/scenes/game_systems.c @@ -732,15 +732,17 @@ void player_crushing_system(Scene_t* scene) } } -void player_spike_collision_system(Scene_t* scene) +void spike_collision_system(Scene_t* scene) { LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data); TileGrid_t tilemap = data->tilemap; - Entity_t* p_player; - sc_map_foreach_value(&scene->ent_manager.entities_map[PLAYER_ENT_TAG], p_player) + //Entity_t* p_player; + CBBox_t* p_bbox; + unsigned int ent_idx; + sc_map_foreach(&scene->ent_manager.component_map[CBBOX_COMP_T], ent_idx, p_bbox) { - CTransform_t* p_ctransform = get_component(p_player, CTRANSFORM_COMP_T); - CBBox_t* p_bbox = get_component(p_player, CBBOX_COMP_T); + Entity_t* p_ent = get_entity(&scene->ent_manager, ent_idx); + CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T); unsigned int tile_x1 = (p_ctransform->position.x) / TILE_SIZE; unsigned int tile_y1 = (p_ctransform->position.y) / TILE_SIZE; unsigned int tile_x2 = (p_ctransform->position.x + p_bbox->size.x - 1) / TILE_SIZE; @@ -753,17 +755,26 @@ void player_spike_collision_system(Scene_t* scene) unsigned int tile_idx = tile_y * tilemap.width + tile_x; if(tilemap.tiles[tile_idx].tile_type == SPIKES) { - if (find_AABB_overlap( + uint8_t collide = find_AABB_overlap( p_ctransform->position, p_bbox->size, (Vector2){ tile_x * TILE_SIZE + tilemap.tiles[tile_idx].offset.x, tile_y * TILE_SIZE + tilemap.tiles[tile_idx].offset.y }, tilemap.tiles[tile_idx].size, - &overlap)) + &overlap); + + if (collide) { - p_player->m_alive = false; - return; + if (p_ent->m_tag == PLAYER_ENT_TAG) + { + p_ent->m_alive = false; + return; + } + else + { + tilemap.tiles[tile_idx].tile_type = EMPTY_TILE; + } } } } @@ -1070,10 +1081,7 @@ void moveable_update_system(Scene_t* scene) { unsigned int tile_idx1 = tile_y * tilemap.width + tile_x; unsigned int tile_idx2 = tile_y2 * tilemap.width + tile_x; - if ( - tilemap.tiles[tile_idx1].tile_type == EMPTY_TILE - && tilemap.tiles[tile_idx2].tile_type == EMPTY_TILE - ) + if ( tilemap.tiles[tile_idx1].moveable && tilemap.tiles[tile_idx2].moveable ) { bool any_solid = false; unsigned int idx_to_check; @@ -1102,9 +1110,7 @@ void moveable_update_system(Scene_t* scene) { unsigned int tile_idx1 = tile_y * tilemap.width + tile_x; unsigned int tile_idx2 = tile_y2 * tilemap.width + tile_x; - if (tilemap.tiles[tile_idx1].tile_type == EMPTY_TILE - && tilemap.tiles[tile_idx2].tile_type == EMPTY_TILE - ) + if ( tilemap.tiles[tile_idx1].moveable && tilemap.tiles[tile_idx2].moveable ) { bool any_solid = false; unsigned int idx_to_check; @@ -1215,7 +1221,7 @@ void player_pushing_system(Scene_t* scene) { unsigned int target_tile_idx = tile_y * tilemap.width + tile_x; if ( - tilemap.tiles[target_tile_idx].tile_type == EMPTY_TILE + tilemap.tiles[target_tile_idx].moveable && sc_map_size_64v(&tilemap.tiles[target_tile_idx].entities_set) == 0 ) { @@ -1558,15 +1564,18 @@ void boulder_destroy_wooden_tile_system(Scene_t* scene) { tilemap.tiles[tile_idx].tile_type = EMPTY_TILE; tilemap.tiles[tile_idx].solid = NOT_SOLID; + tilemap.tiles[tile_idx].moveable = true; if (tile_x > 0 && tilemap.tiles[tile_idx - 1].tile_type == ONEWAY_TILE) { tilemap.tiles[tile_idx - 1].tile_type = EMPTY_TILE; tilemap.tiles[tile_idx - 1].solid = NOT_SOLID; + tilemap.tiles[tile_idx - 1].moveable = true; } if (tile_x < tilemap.width && tilemap.tiles[tile_idx + 1].tile_type == ONEWAY_TILE) { tilemap.tiles[tile_idx + 1].tile_type = EMPTY_TILE; tilemap.tiles[tile_idx + 1].solid = NOT_SOLID; + tilemap.tiles[tile_idx + 1].moveable = true; } } } diff --git a/scenes/game_systems.h b/scenes/game_systems.h index a436b0c..a9032e6 100644 --- a/scenes/game_systems.h +++ b/scenes/game_systems.h @@ -22,5 +22,5 @@ void boulder_destroy_wooden_tile_system(Scene_t* scene); void camera_update_system(Scene_t* scene); void player_dir_reset_system(Scene_t* scene); void player_respawn_system(Scene_t* scene); -void player_spike_collision_system(Scene_t* scene); +void spike_collision_system(Scene_t* scene); #endif // __GAME_SYSTEMS_H diff --git a/scenes/scene_impl.h b/scenes/scene_impl.h index e9ae142..68d8c57 100644 --- a/scenes/scene_impl.h +++ b/scenes/scene_impl.h @@ -34,6 +34,7 @@ typedef struct Tile { struct sc_map_64v entities_set; Vector2 offset; Vector2 size; + bool moveable; }Tile_t; typedef struct TileGrid {