Compare commits
2 Commits
d54fee8935
...
26fa9af6b8
Author | SHA1 | Date |
---|---|---|
|
26fa9af6b8 | |
|
ce8284ab39 |
|
@ -26,9 +26,10 @@ enum EntitySpawnSelection {
|
||||||
SPAWN_CRATE_BOMB,
|
SPAWN_CRATE_BOMB,
|
||||||
SPAWN_BOULDER,
|
SPAWN_BOULDER,
|
||||||
SPAWN_WATER_RUNNER,
|
SPAWN_WATER_RUNNER,
|
||||||
|
SPAWN_LEVEL_END,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_SPAWN_TYPE 15
|
#define MAX_SPAWN_TYPE 16
|
||||||
static unsigned int current_spawn_selection = 0;
|
static unsigned int current_spawn_selection = 0;
|
||||||
static bool metal_toggle = false;
|
static bool metal_toggle = false;
|
||||||
static bool crate_activation = false;
|
static bool crate_activation = false;
|
||||||
|
@ -58,6 +59,7 @@ static char* get_spawn_selection_string(enum EntitySpawnSelection sel)
|
||||||
case SPAWN_CRATE_BOMB: return (metal_toggle) ? "metal bomb crate" : "wooden bomb crate";
|
case SPAWN_CRATE_BOMB: return (metal_toggle) ? "metal bomb crate" : "wooden bomb crate";
|
||||||
case SPAWN_BOULDER: return "boulder";
|
case SPAWN_BOULDER: return "boulder";
|
||||||
case SPAWN_WATER_RUNNER: return "water runner";
|
case SPAWN_WATER_RUNNER: return "water runner";
|
||||||
|
case SPAWN_LEVEL_END: return "level end";
|
||||||
default: return "unknown";
|
default: return "unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -330,6 +332,12 @@ static void level_scene_render_func(Scene_t* scene)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sc_map_foreach_value(&scene->ent_manager.entities_map[LEVEL_END_TAG], p_ent)
|
||||||
|
{
|
||||||
|
CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
|
||||||
|
DrawCircleV(p_ct->position, tilemap.tile_size >> 1, (data->coins.current < data->coins.total)? RED : GREEN);
|
||||||
|
}
|
||||||
|
|
||||||
sc_map_foreach_value(&scene->ent_manager.entities_map[DYNMEM_ENT_TAG], p_ent)
|
sc_map_foreach_value(&scene->ent_manager.entities_map[DYNMEM_ENT_TAG], p_ent)
|
||||||
{
|
{
|
||||||
CWaterRunner_t* p_runner = get_component(p_ent, CWATERRUNNER_T);
|
CWaterRunner_t* p_runner = get_component(p_ent, CWATERRUNNER_T);
|
||||||
|
@ -597,6 +605,17 @@ static void toggle_block_system(Scene_t* scene)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SPAWN_LEVEL_END:
|
||||||
|
{
|
||||||
|
Entity_t* p_ent = create_level_end(&scene->ent_manager, &scene->engine->assets);
|
||||||
|
if (p_ent != NULL)
|
||||||
|
{
|
||||||
|
CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
|
||||||
|
p_ct->position.x = (tile_idx % tilemap.width) * tilemap.tile_size + (tilemap.tile_size >> 1);
|
||||||
|
p_ct->position.y = (tile_idx / tilemap.width) * tilemap.tile_size + (tilemap.tile_size >> 1);;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SPAWN_CHEST:
|
case SPAWN_CHEST:
|
||||||
if (data->coins.total < 65535)
|
if (data->coins.total < 65535)
|
||||||
{
|
{
|
||||||
|
@ -717,6 +736,11 @@ static void restart_editor_level(Scene_t* scene)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
@ -828,6 +852,7 @@ static void level_do_action(Scene_t* scene, ActionType_t action, bool pressed)
|
||||||
change_scene(scene->engine, 0);
|
change_scene(scene->engine, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ACTION_NEXTLEVEL:
|
||||||
case ACTION_RESTART:
|
case ACTION_RESTART:
|
||||||
restart_editor_level(scene);
|
restart_editor_level(scene);
|
||||||
break;
|
break;
|
||||||
|
@ -862,7 +887,7 @@ void init_sandbox_scene(LevelScene_t* scene)
|
||||||
BLACK, MAROON, ORANGE, ColorAlpha(RAYWHITE, 0.5), ColorAlpha(BLUE, 0.5),
|
BLACK, MAROON, ORANGE, ColorAlpha(RAYWHITE, 0.5), ColorAlpha(BLUE, 0.5),
|
||||||
ColorAlpha(RAYWHITE, 0.5), YELLOW, crate_colour, crate_colour, crate_colour,
|
ColorAlpha(RAYWHITE, 0.5), YELLOW, crate_colour, crate_colour, crate_colour,
|
||||||
crate_colour, crate_colour, crate_colour,
|
crate_colour, crate_colour, crate_colour,
|
||||||
ColorAlpha(RAYWHITE, 0.5), ColorAlpha(RAYWHITE, 0.5)
|
ColorAlpha(RAYWHITE, 0.5), ColorAlpha(RAYWHITE, 0.5), ColorAlpha(RAYWHITE, 0.5)
|
||||||
};
|
};
|
||||||
for (uint8_t i = 0; i < MAX_SPAWN_TYPE; ++i)
|
for (uint8_t i = 0; i < MAX_SPAWN_TYPE; ++i)
|
||||||
{
|
{
|
||||||
|
@ -918,6 +943,9 @@ void init_sandbox_scene(LevelScene_t* scene)
|
||||||
case SPAWN_WATER_RUNNER:
|
case SPAWN_WATER_RUNNER:
|
||||||
DrawCircleV(Vector2Add(draw_pos, half_size), half_size.x, ColorAlpha(BLUE, 0.2));
|
DrawCircleV(Vector2Add(draw_pos, half_size), half_size.x, ColorAlpha(BLUE, 0.2));
|
||||||
break;
|
break;
|
||||||
|
case SPAWN_LEVEL_END:
|
||||||
|
DrawCircleV(Vector2Add(draw_pos, half_size), half_size.x, GREEN);
|
||||||
|
break;
|
||||||
case TOGGLE_AIR_POCKET:
|
case TOGGLE_AIR_POCKET:
|
||||||
DrawRectangleLinesEx((Rectangle){draw_pos.x, draw_pos.y, SELECTION_TILE_SIZE, SELECTION_TILE_SIZE}, 2.0, ColorAlpha(BLUE, 0.5));
|
DrawRectangleLinesEx((Rectangle){draw_pos.x, draw_pos.y, SELECTION_TILE_SIZE, SELECTION_TILE_SIZE}, 2.0, ColorAlpha(BLUE, 0.5));
|
||||||
break;
|
break;
|
||||||
|
@ -961,6 +989,7 @@ void init_sandbox_scene(LevelScene_t* scene)
|
||||||
sc_array_add(&scene->scene.systems, &player_dir_reset_system);
|
sc_array_add(&scene->scene.systems, &player_dir_reset_system);
|
||||||
sc_array_add(&scene->scene.systems, &update_water_runner_system);
|
sc_array_add(&scene->scene.systems, &update_water_runner_system);
|
||||||
sc_array_add(&scene->scene.systems, &player_respawn_system);
|
sc_array_add(&scene->scene.systems, &player_respawn_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &level_end_detection_system);
|
||||||
sc_array_add(&scene->scene.systems, &toggle_block_system);
|
sc_array_add(&scene->scene.systems, &toggle_block_system);
|
||||||
|
|
||||||
// This avoid graphical glitch, not essential
|
// This avoid graphical glitch, not essential
|
||||||
|
|
|
@ -23,19 +23,21 @@ uint8_t find_AABB_overlap(const Vector2 tl1, const Vector2 sz1, const Vector2 tl
|
||||||
// Note that we include one extra pixel for checking
|
// Note that we include one extra pixel for checking
|
||||||
// This avoid overlapping on the border
|
// This avoid overlapping on the border
|
||||||
Vector2 l1, l2;
|
Vector2 l1, l2;
|
||||||
|
Vector2 tmp;
|
||||||
uint8_t overlap_x, overlap_y;
|
uint8_t overlap_x, overlap_y;
|
||||||
l1.x = tl1.x;
|
l1.x = tl1.x;
|
||||||
l1.y = tl1.x + sz1.x;
|
l1.y = tl1.x + sz1.x;
|
||||||
l2.x = tl2.x;
|
l2.x = tl2.x;
|
||||||
l2.y = tl2.x + sz2.x;
|
l2.y = tl2.x + sz2.x;
|
||||||
|
|
||||||
overlap_x = find_1D_overlap(l1, l2, &overlap->x);
|
overlap_x = find_1D_overlap(l1, l2, &tmp.x);
|
||||||
l1.x = tl1.y;
|
l1.x = tl1.y;
|
||||||
l1.y = tl1.y + sz1.y;
|
l1.y = tl1.y + sz1.y;
|
||||||
l2.x = tl2.y;
|
l2.x = tl2.y;
|
||||||
l2.y = tl2.y + sz2.y;
|
l2.y = tl2.y + sz2.y;
|
||||||
overlap_y = find_1D_overlap(l1, l2, &overlap->y);
|
overlap_y = find_1D_overlap(l1, l2, &tmp.y);
|
||||||
|
|
||||||
|
if (overlap) *overlap = tmp;
|
||||||
if (overlap_x == 2 && overlap_y == 2) return 2;
|
if (overlap_x == 2 && overlap_y == 2) return 2;
|
||||||
return (overlap_x < overlap_y) ? overlap_x : overlap_y;
|
return (overlap_x < overlap_y) ? overlap_x : overlap_y;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "sc/map/sc_map.h"
|
#include "sc/map/sc_map.h"
|
||||||
#include "sc/queue/sc_queue.h"
|
#include "sc/queue/sc_queue.h"
|
||||||
|
|
||||||
#define N_TAGS 8
|
#define N_TAGS 10
|
||||||
#define N_COMPONENTS 13
|
#define N_COMPONENTS 13
|
||||||
#define MAX_COMP_POOL_SIZE 1024
|
#define MAX_COMP_POOL_SIZE 1024
|
||||||
typedef struct EntityManager EntityManager_t;
|
typedef struct EntityManager EntityManager_t;
|
||||||
|
|
|
@ -9,6 +9,7 @@ typedef enum EntityTag {
|
||||||
CRATES_ENT_TAG,
|
CRATES_ENT_TAG,
|
||||||
CHEST_ENT_TAG,
|
CHEST_ENT_TAG,
|
||||||
BOULDER_ENT_TAG,
|
BOULDER_ENT_TAG,
|
||||||
|
LEVEL_END_TAG,
|
||||||
DESTRUCTABLE_ENT_TAG,
|
DESTRUCTABLE_ENT_TAG,
|
||||||
DYNMEM_ENT_TAG,
|
DYNMEM_ENT_TAG,
|
||||||
} EntityTag_t;
|
} EntityTag_t;
|
||||||
|
@ -27,5 +28,6 @@ Entity_t* create_arrow(EntityManager_t* ent_manager, Assets_t* assets, uint8_t d
|
||||||
Entity_t* create_bomb(EntityManager_t* ent_manager, Assets_t* assets, Vector2 launch_dir);
|
Entity_t* create_bomb(EntityManager_t* ent_manager, Assets_t* assets, Vector2 launch_dir);
|
||||||
Entity_t* create_explosion(EntityManager_t* ent_manager, Assets_t* assets);
|
Entity_t* create_explosion(EntityManager_t* ent_manager, Assets_t* assets);
|
||||||
Entity_t* create_chest(EntityManager_t* ent_manager, Assets_t* assets);
|
Entity_t* create_chest(EntityManager_t* ent_manager, Assets_t* assets);
|
||||||
|
Entity_t* create_level_end(EntityManager_t* ent_manager, Assets_t* assets);
|
||||||
|
|
||||||
#endif // __ENT_IMPL_H
|
#endif // __ENT_IMPL_H
|
||||||
|
|
|
@ -569,7 +569,6 @@ void spike_collision_system(Scene_t* scene)
|
||||||
tile_y1 = (tile_y1 < 0) ? 0 : tile_y1;
|
tile_y1 = (tile_y1 < 0) ? 0 : tile_y1;
|
||||||
tile_y2 = (tile_y2 >= tilemap.height) ? tilemap.height - 1 : tile_y2;
|
tile_y2 = (tile_y2 >= tilemap.height) ? tilemap.height - 1 : tile_y2;
|
||||||
|
|
||||||
Vector2 overlap;
|
|
||||||
for (unsigned int tile_y = tile_y1; tile_y <= tile_y2; tile_y++)
|
for (unsigned int tile_y = tile_y1; tile_y <= tile_y2; tile_y++)
|
||||||
{
|
{
|
||||||
for (unsigned int tile_x = tile_x1; tile_x <= tile_x2; tile_x++)
|
for (unsigned int tile_x = tile_x1; tile_x <= tile_x2; tile_x++)
|
||||||
|
@ -584,7 +583,7 @@ void spike_collision_system(Scene_t* scene)
|
||||||
tile_y * TILE_SIZE + tilemap.tiles[tile_idx].offset.y
|
tile_y * TILE_SIZE + tilemap.tiles[tile_idx].offset.y
|
||||||
},
|
},
|
||||||
tilemap.tiles[tile_idx].size,
|
tilemap.tiles[tile_idx].size,
|
||||||
&overlap);
|
NULL);
|
||||||
|
|
||||||
if (collide)
|
if (collide)
|
||||||
{
|
{
|
||||||
|
@ -1309,11 +1308,10 @@ void state_transition_update_system(Scene_t* scene)
|
||||||
|
|
||||||
uint32_t water_height = data->tilemap.tiles[tile_idx].water_level * WATER_BBOX_STEP;
|
uint32_t water_height = data->tilemap.tiles[tile_idx].water_level * WATER_BBOX_STEP;
|
||||||
Vector2 tl = {tile_x * data->tilemap.tile_size, (tile_y + 1) * data->tilemap.tile_size - water_height};
|
Vector2 tl = {tile_x * data->tilemap.tile_size, (tile_y + 1) * data->tilemap.tile_size - water_height};
|
||||||
Vector2 overlap;
|
|
||||||
in_water |= find_AABB_overlap(
|
in_water |= find_AABB_overlap(
|
||||||
p_ctransform->position, p_bbox->size,
|
p_ctransform->position, p_bbox->size,
|
||||||
tl, (Vector2){data->tilemap.tile_size, water_height}
|
tl, (Vector2){data->tilemap.tile_size, water_height}
|
||||||
, &overlap
|
, NULL
|
||||||
) > 0;
|
) > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1422,7 +1420,6 @@ void hitbox_update_system(Scene_t* scene)
|
||||||
if (tile_idx >= tilemap.n_tiles) break;
|
if (tile_idx >= tilemap.n_tiles) break;
|
||||||
unsigned int other_ent_idx;
|
unsigned int other_ent_idx;
|
||||||
Entity_t* p_other_ent;
|
Entity_t* p_other_ent;
|
||||||
Vector2 overlap;
|
|
||||||
|
|
||||||
if (tilemap.tiles[tile_idx].tile_type != EMPTY_TILE)
|
if (tilemap.tiles[tile_idx].tile_type != EMPTY_TILE)
|
||||||
{
|
{
|
||||||
|
@ -1431,7 +1428,7 @@ void hitbox_update_system(Scene_t* scene)
|
||||||
if (
|
if (
|
||||||
find_AABB_overlap(
|
find_AABB_overlap(
|
||||||
hitbox_pos, (Vector2){p_hitbox->boxes[i].width, p_hitbox->boxes[i].height},
|
hitbox_pos, (Vector2){p_hitbox->boxes[i].width, p_hitbox->boxes[i].height},
|
||||||
tile_pos, tilemap.tiles[tile_idx].size, &overlap
|
tile_pos, tilemap.tiles[tile_idx].size, NULL
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -1462,7 +1459,7 @@ void hitbox_update_system(Scene_t* scene)
|
||||||
if (
|
if (
|
||||||
find_AABB_overlap(
|
find_AABB_overlap(
|
||||||
hitbox_pos, (Vector2){p_hitbox->boxes[i].width, p_hitbox->boxes[i].height},
|
hitbox_pos, (Vector2){p_hitbox->boxes[i].width, p_hitbox->boxes[i].height},
|
||||||
hurtbox_pos, p_other_hurtbox->size, &overlap
|
hurtbox_pos, p_other_hurtbox->size, NULL
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -1732,3 +1729,43 @@ void camera_update_system(Scene_t* scene)
|
||||||
if (min.x > 0) lvl_scene->data.cam.offset.x = width/2.0f - min.x;
|
if (min.x > 0) lvl_scene->data.cam.offset.x = width/2.0f - min.x;
|
||||||
if (min.y > 0) lvl_scene->data.cam.offset.y = height/2.0f - min.y;
|
if (min.y > 0) lvl_scene->data.cam.offset.y = height/2.0f - min.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void level_end_detection_system(Scene_t* scene)
|
||||||
|
{
|
||||||
|
LevelScene_t* lvl_scene = CONTAINER_OF(scene, LevelScene_t, scene);
|
||||||
|
if (lvl_scene->data.coins.current < lvl_scene->data.coins.total) return;
|
||||||
|
Entity_t* p_flag;
|
||||||
|
|
||||||
|
TileGrid_t tilemap = lvl_scene->data.tilemap;
|
||||||
|
sc_map_foreach_value(&scene->ent_manager.entities_map[LEVEL_END_TAG], p_flag)
|
||||||
|
{
|
||||||
|
CTransform_t* p_ct = get_component(p_flag, CTRANSFORM_COMP_T);
|
||||||
|
unsigned int tile_idx = get_tile_idx(
|
||||||
|
p_ct->position.x,
|
||||||
|
p_ct->position.y,
|
||||||
|
tilemap.width
|
||||||
|
);
|
||||||
|
|
||||||
|
unsigned int other_ent_idx;
|
||||||
|
Entity_t* p_other_ent;
|
||||||
|
sc_map_foreach(&tilemap.tiles[tile_idx].entities_set, other_ent_idx, p_other_ent)
|
||||||
|
{
|
||||||
|
if (p_other_ent->m_tag != PLAYER_ENT_TAG) continue;
|
||||||
|
|
||||||
|
CTransform_t* p_other_ct = get_component(p_other_ent, CTRANSFORM_COMP_T);
|
||||||
|
CBBox_t* p_other_bbox = get_component(p_other_ent, CBBOX_COMP_T);
|
||||||
|
|
||||||
|
Vector2 pos = Vector2Subtract(p_ct->position,(Vector2){tilemap.tile_size >> 1, tilemap.tile_size >> 1});
|
||||||
|
if (
|
||||||
|
find_AABB_overlap(
|
||||||
|
pos, (Vector2){tilemap.tile_size, tilemap.tile_size},
|
||||||
|
p_other_ct->position, p_other_bbox->size, NULL
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
do_action(scene, ACTION_NEXTLEVEL, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -24,5 +24,6 @@ void player_dir_reset_system(Scene_t* scene);
|
||||||
void player_respawn_system(Scene_t* scene);
|
void player_respawn_system(Scene_t* scene);
|
||||||
void lifetimer_update_system(Scene_t* scene);
|
void lifetimer_update_system(Scene_t* scene);
|
||||||
void spike_collision_system(Scene_t* scene);
|
void spike_collision_system(Scene_t* scene);
|
||||||
|
void level_end_detection_system(Scene_t* scene);
|
||||||
|
|
||||||
#endif // __GAME_SYSTEMS_H
|
#endif // __GAME_SYSTEMS_H
|
||||||
|
|
|
@ -225,3 +225,12 @@ Entity_t* create_chest(EntityManager_t* ent_manager, Assets_t* assets)
|
||||||
|
|
||||||
return p_chest;
|
return p_chest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Entity_t* create_level_end(EntityManager_t* ent_manager, Assets_t* assets)
|
||||||
|
{
|
||||||
|
Entity_t* p_flag = add_entity(ent_manager, LEVEL_END_TAG);
|
||||||
|
if (p_flag == NULL) return NULL;
|
||||||
|
|
||||||
|
add_component(p_flag, CTRANSFORM_COMP_T);
|
||||||
|
return p_flag;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue