From d3ea551024da72a05570403a311986e1571881a5 Mon Sep 17 00:00:00 2001 From: En Yi Date: Tue, 27 Aug 2024 15:49:05 +0800 Subject: [PATCH 1/4] Tweak engine config to allow web build Internal Changelog: - Reduce particles number - Use webGL2 --- CMakeLists.txt | 2 +- engine/engine_conf.h | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4cec5e2..1de6547 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ set(LIBZSTD_DIR /usr/local/lib CACHE FILEPATH "directory to zstd") if (EMSCRIPTEN) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPLATFORM_WEB") -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY -s TOTAL_MEMORY=16777216 -s TOTAL_STACK=1048576 --preload-file ./res ") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY -s MIN_WEBGL_VERSION=2 -s MAX_WEBGL_VERSION=2 -s TOTAL_MEMORY=16777216 -s TOTAL_STACK=1048576 --preload-file ./res ") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") set(CMAKE_EXECUTABLE_SUFFIX ".html") diff --git a/engine/engine_conf.h b/engine/engine_conf.h index 5727363..5a2569c 100644 --- a/engine/engine_conf.h +++ b/engine/engine_conf.h @@ -1,11 +1,13 @@ #ifndef _ENGINE_CONF_H #define _ENGINE_CONF_H -#define MAX_SCENES_TO_RENDER 16 +// Take care tuning these params. Web build doesn't work +// if memory used too high +#define MAX_SCENES_TO_RENDER 8 #define MAX_RENDER_LAYERS 4 #define MAX_ENTITIES 2047 #define MAX_TEXTURES 16 -#define MAX_SPRITES 128 +#define MAX_SPRITES 127 #define MAX_SOUNDS 32 #define MAX_FONTS 4 #define MAX_N_TILES 16384 @@ -14,8 +16,8 @@ #define N_SFX 32 #define MAX_EMITTER_CONF 8 //#define MAX_PARTICLE_EMITTER 8 -#define MAX_ACTIVE_PARTICLE_EMITTER 512 -#define MAX_PARTICLES 64 +#define MAX_ACTIVE_PARTICLE_EMITTER 255 +#define MAX_PARTICLES 32 #define MAX_TILE_TYPES 16 #define N_TAGS 10 From e00e1ff8d241bdf0b82bcece94592ce677bcad60 Mon Sep 17 00:00:00 2001 From: En Yi Date: Tue, 27 Aug 2024 15:49:21 +0800 Subject: [PATCH 2/4] Remove player on finish level --- scenes/player_ent.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scenes/player_ent.c b/scenes/player_ent.c index 0ec1583..15f003d 100644 --- a/scenes/player_ent.c +++ b/scenes/player_ent.c @@ -144,6 +144,9 @@ static unsigned int player_finish_transition_func(Entity_t* ent) if (p_spr->current_frame == p_spr->sprites[p_spr->current_idx].sprite->frame_count - 1) { p_spr->pause = true; + // This entity has no special init, so it's fine to remove + // at end of animation + remove_entity(ent->manager, ent->m_id); } return p_spr->current_idx; } From c8059300ace55e441251d4624fcd19b007078d75 Mon Sep 17 00:00:00 2001 From: En Yi Date: Tue, 27 Aug 2024 16:02:55 +0800 Subject: [PATCH 3/4] Fix freecam bug on game restart Changelog: - Lock player if freecam is active --- scenes/editor_scene.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scenes/editor_scene.c b/scenes/editor_scene.c index 2bad01e..7dd0beb 100644 --- a/scenes/editor_scene.c +++ b/scenes/editor_scene.c @@ -119,7 +119,7 @@ static void level_scene_render_func(Scene_t* scene) selection_rec.x + current_spawn_selection * SELECTION_TILE_SIZE, selection_rec.y, SELECTION_TILE_SIZE, SELECTION_TILE_SIZE, GREEN ); - DrawText("R to reset the map, Q/E to cycle the selection,\nF to toggle metal crates. T to toggle crate spawn behaviour\nB to toggle grid, V to set spawn point", selection_rec.x, selection_rec.y + selection_rec.height + 2, 14, BLACK); + DrawText("R to reset the map, Q/E to cycle the selection,\nF to toggle metal crates. T to toggle crate spawn behaviour\nZ to change tileset, X to toggle grid\nC to set spawn point, V to toggle free cam", selection_rec.x, selection_rec.y + selection_rec.height + 2, 14, BLACK); draw_pos.x = game_rec.x + (MAX_SPAWN_TYPE + 1) * SELECTION_TILE_SIZE; sprintf(buffer, "Selection: %s", get_spawn_selection_string(current_spawn_selection)); @@ -850,6 +850,11 @@ static void restart_editor_level(Scene_t* scene) Entity_t* p_player = create_player(&scene->ent_manager); p_player->position = data->player_spawn; + CPlayerState_t* p_pstate = get_component(p_player, CPLAYERSTATE_T); + if (data->camera.mode == CAMERA_RANGED_MOVEMENT) + { + p_pstate->locked = true; + } update_entity_manager(&scene->ent_manager); for (size_t i = 0; i < tilemap.width; ++i) From 41585f6938867e455e8b47c397e311061afd5e47 Mon Sep 17 00:00:00 2001 From: En Yi Date: Mon, 2 Sep 2024 21:58:11 +0800 Subject: [PATCH 4/4] Simplify edge velocity check Internal Changelog: - Use tile collision to determine which side has collided and perform the velocity zeroing, instead of separating out. --- scenes/editor_scene.c | 2 +- scenes/game_scene.c | 1 - scenes/game_systems.c | 86 +++++++++++++++++++++++-------------------- scenes/game_systems.h | 1 - 4 files changed, 47 insertions(+), 43 deletions(-) diff --git a/scenes/editor_scene.c b/scenes/editor_scene.c index 7dd0beb..1548122 100644 --- a/scenes/editor_scene.c +++ b/scenes/editor_scene.c @@ -1413,7 +1413,7 @@ void init_sandbox_scene(LevelScene_t* scene) sc_array_add(&scene->scene.systems, &hitbox_update_system); sc_array_add(&scene->scene.systems, &player_crushing_system); sc_array_add(&scene->scene.systems, &spike_collision_system); - sc_array_add(&scene->scene.systems, &edge_velocity_check_system); + //sc_array_add(&scene->scene.systems, &edge_velocity_check_system); sc_array_add(&scene->scene.systems, &state_transition_update_system); sc_array_add(&scene->scene.systems, &update_entity_emitter_system); sc_array_add(&scene->scene.systems, &player_ground_air_transition_system); diff --git a/scenes/game_scene.c b/scenes/game_scene.c index 95f3b28..c719b81 100644 --- a/scenes/game_scene.c +++ b/scenes/game_scene.c @@ -534,7 +534,6 @@ void init_game_scene(LevelScene_t* scene) sc_array_add(&scene->scene.systems, &hitbox_update_system); sc_array_add(&scene->scene.systems, &player_crushing_system); sc_array_add(&scene->scene.systems, &spike_collision_system); - sc_array_add(&scene->scene.systems, &edge_velocity_check_system); sc_array_add(&scene->scene.systems, &state_transition_update_system); sc_array_add(&scene->scene.systems, &update_entity_emitter_system); sc_array_add(&scene->scene.systems, &player_ground_air_transition_system); diff --git a/scenes/game_systems.c b/scenes/game_systems.c index 1e50abd..7d1a69d 100644 --- a/scenes/game_systems.c +++ b/scenes/game_systems.c @@ -69,7 +69,7 @@ static inline void destroy_tile(LevelSceneData_t* lvl_data, unsigned int tile_id // ------------------------- Collision functions ------------------------------------ // Do not subtract one for the size for any collision check, just pass normally. The extra one is important for AABB test -static bool check_collision_and_move( +static uint8_t check_collision_and_move( TileGrid_t* tilemap, Entity_t* ent, Vector2* other_pos, Vector2 other_bbox, SolidType_t other_solid @@ -81,6 +81,7 @@ static bool check_collision_and_move( Vector2 overlap = {0,0}; Vector2 prev_overlap = {0,0}; uint8_t overlap_mode = find_AABB_overlap(ent->position, p_bbox->size, *other_pos, other_bbox, &overlap); + uint8_t collided_side = 0; if (overlap_mode == 1) { // If there is collision, use previous overlap to determine direction @@ -108,6 +109,24 @@ static bool check_collision_and_move( offset.y = overlap.y; } } + + if (offset.y < 0) + { + collided_side |= 1; + } + else if (offset.y > 0) + { + collided_side |= (1<<1); + } + else if (offset.x < 0) + { + collided_side |= (1<<2); + } + else if (offset.x > 0) + { + collided_side |= (1<<3); + } + ent->position = Vector2Add(ent->position, offset); } else if (overlap_mode == 2) @@ -120,6 +139,7 @@ static bool check_collision_and_move( if (!check_collision_at(ent, point_to_test, p_bbox->size, tilemap)) { ent->position = point_to_test; + collided_side |= 1; goto collision_end; } @@ -128,6 +148,7 @@ static bool check_collision_and_move( if (!check_collision_at(ent, point_to_test, p_bbox->size, tilemap)) { ent->position = point_to_test; + collided_side |= (1<<2); goto collision_end; } @@ -136,6 +157,7 @@ static bool check_collision_and_move( if (!check_collision_at(ent, point_to_test, p_bbox->size, tilemap)) { ent->position = point_to_test; + collided_side |= (1<<3); goto collision_end; } @@ -144,6 +166,7 @@ static bool check_collision_and_move( if (!check_collision_at(ent, point_to_test, p_bbox->size, tilemap)) { ent->position = point_to_test; + collided_side |= (1<<1); goto collision_end; } // If no free space, Move up no matter what @@ -151,7 +174,7 @@ static bool check_collision_and_move( ent->position.y = other_pos->y - p_bbox->size.y + 1; } collision_end: - return overlap_mode > 0; + return collided_side; } static void destroy_entity(Scene_t* scene, TileGrid_t* tilemap, Entity_t* p_ent) @@ -736,6 +759,7 @@ void tile_collision_system(Scene_t* scene) for (unsigned int tile_x = tile_x1; tile_x <= tile_x2; tile_x++) { unsigned int tile_idx = tile_y * tilemap.width + tile_x; + uint8_t collide_side = 0; if(tilemap.tiles[tile_idx].tile_type != EMPTY_TILE) { Vector2 other; @@ -756,7 +780,7 @@ void tile_collision_system(Scene_t* scene) && p_ent->position.y + p_bbox->size.y > other.y ) ? SOLID : NOT_SOLID; } - check_collision_and_move( + collide_side = check_collision_and_move( &tilemap, p_ent, &other, (Vector2){tilemap.tile_size, tilemap.tile_size}, @@ -784,51 +808,33 @@ void tile_collision_system(Scene_t* scene) { solid = NOT_SOLID; } - check_collision_and_move( + collide_side = check_collision_and_move( &tilemap, p_ent, &p_other_ent->position, p_other_bbox->size, solid ); } } + + if (collide_side & (1<<3)) + { + if (p_ctransform->velocity.x < 0) p_ctransform->velocity.x = 0; + } + if (collide_side & (1<<2)) + { + if (p_ctransform->velocity.x > 0) p_ctransform->velocity.x = 0; + } + if (collide_side & (1<<1)) + { + if (p_ctransform->velocity.y < 0) p_ctransform->velocity.y = 0; + } + if (collide_side & (1)) + { + if (p_ctransform->velocity.y > 0) p_ctransform->velocity.y = 0; + } + } } - } -} - -void edge_velocity_check_system(Scene_t* scene) -{ - LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data); - unsigned int ent_idx; - CBBox_t* p_bbox; - sc_map_foreach(&scene->ent_manager.component_map[CBBOX_COMP_T], ent_idx, p_bbox) - { - Entity_t* p_ent = get_entity(&scene->ent_manager, ent_idx); - CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T); - if (!p_ctransform->active) continue; - // Post movement edge check to zero out velocity - uint8_t edges = check_bbox_edges( - &data->tilemap, p_ent, - p_bbox->size, false - ); - if (edges & (1<<3)) - { - if (p_ctransform->velocity.x < 0) p_ctransform->velocity.x = 0; - } - if (edges & (1<<2)) - { - if (p_ctransform->velocity.x > 0) p_ctransform->velocity.x = 0; - } - if (edges & (1<<1)) - { - if (p_ctransform->velocity.y < 0) p_ctransform->velocity.y = 0; - } - if (edges & (1)) - { - if (p_ctransform->velocity.y > 0) p_ctransform->velocity.y = 0; - } - - // Deal with float precision, by rounding when it is near to an integer enough by 2 dp float decimal; float fractional = modff(p_ent->position.x, &decimal); if (fractional > 0.99) diff --git a/scenes/game_systems.h b/scenes/game_systems.h index f0cfd61..3bbb188 100644 --- a/scenes/game_systems.h +++ b/scenes/game_systems.h @@ -16,7 +16,6 @@ void state_transition_update_system(Scene_t* scene); void update_entity_emitter_system(Scene_t* scene); void update_tilemap_system(Scene_t* scene); void hitbox_update_system(Scene_t* scene); -void edge_velocity_check_system(Scene_t* scene); void sprite_animation_system(Scene_t* scene); void boulder_destroy_wooden_tile_system(Scene_t* scene); void camera_update_system(Scene_t* scene);