Compare commits
3 Commits
f6f6d54ecf
...
e4b5695a15
Author | SHA1 | Date |
---|---|---|
|
e4b5695a15 | |
|
e37e89505a | |
|
019f39f84c |
|
@ -253,7 +253,6 @@ static inline void set_bbox(CBBox_t* p_bbox, unsigned int x, unsigned int y)
|
|||
}
|
||||
|
||||
struct Entity {
|
||||
Vector2 spawn_pos;
|
||||
Vector2 position;
|
||||
unsigned long m_id;
|
||||
unsigned int m_tag;
|
||||
|
|
|
@ -115,7 +115,6 @@ Entity_t *add_entity(EntityManager_t* p_manager, unsigned int tag)
|
|||
Entity_t* p_ent = new_entity_from_mempool(&e_idx);
|
||||
if (p_ent == NULL) return NULL;
|
||||
|
||||
p_ent->spawn_pos = (Vector2){0, 0};
|
||||
p_ent->m_tag = tag;
|
||||
sc_queue_add_last(&p_manager->to_add, e_idx);
|
||||
p_ent->manager = p_manager;
|
||||
|
|
|
@ -220,6 +220,12 @@ static void render_editor_game_scene(Scene_t* scene)
|
|||
);
|
||||
|
||||
BeginMode2D(data->camera.cam);
|
||||
|
||||
if (point_in_AABB(data->player_spawn, (Rectangle){min.x * tilemap.tile_size, min.y * tilemap.tile_size, data->game_rec.width, data->game_rec.height}))
|
||||
{
|
||||
DrawCircleV(data->player_spawn, 6, PURPLE);
|
||||
}
|
||||
|
||||
for (int tile_y = min.y; tile_y < max.y; tile_y++)
|
||||
{
|
||||
for (int tile_x = min.x; tile_x < max.x; tile_x++)
|
||||
|
@ -248,12 +254,6 @@ static void render_editor_game_scene(Scene_t* scene)
|
|||
{
|
||||
CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
|
||||
|
||||
// Draw the spawn point
|
||||
if (p_ent->m_tag == PLAYER_ENT_TAG)
|
||||
{
|
||||
DrawCircleV(p_ent->spawn_pos, 6, PURPLE);
|
||||
}
|
||||
|
||||
// Entity culling
|
||||
Vector2 box_size = {0};
|
||||
if (p_bbox != NULL) box_size = p_bbox->size;
|
||||
|
@ -887,6 +887,9 @@ static void level_do_action(Scene_t* scene, ActionType_t action, bool pressed)
|
|||
p_playerstate->locked = !p_playerstate->locked;
|
||||
}
|
||||
break;
|
||||
case ACTION_SET_SPAWNPOINT:
|
||||
data->player_spawn = p_player->position;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1062,9 +1065,6 @@ static void level_do_action(Scene_t* scene, ActionType_t action, bool pressed)
|
|||
data->show_grid = !data->show_grid;
|
||||
}
|
||||
break;
|
||||
case ACTION_SET_SPAWNPOINT:
|
||||
p_player->spawn_pos = p_player->position;
|
||||
break;
|
||||
case ACTION_TOGGLE_TIMESLOW:
|
||||
if (!pressed)
|
||||
{
|
||||
|
@ -1103,6 +1103,41 @@ static void level_do_action(Scene_t* scene, ActionType_t action, bool pressed)
|
|||
}
|
||||
}
|
||||
|
||||
static void at_level_start(Scene_t* scene)
|
||||
{
|
||||
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
|
||||
data->sm.state = LEVEL_STATE_RUNNING;
|
||||
}
|
||||
|
||||
static void at_level_dead(Scene_t* scene)
|
||||
{
|
||||
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
|
||||
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;
|
||||
}
|
||||
change_level_state(data, LEVEL_STATE_STARTING);
|
||||
}
|
||||
|
||||
static void at_level_complete(Scene_t* scene)
|
||||
{
|
||||
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
|
||||
data->sm.fractional += scene->delta_time;
|
||||
if (data->sm.fractional > 1.0f)
|
||||
{
|
||||
data->sm.fractional -= 1.0f;
|
||||
data->sm.counter++;
|
||||
}
|
||||
if (data->sm.counter >= 3)
|
||||
{
|
||||
do_action(scene, ACTION_NEXTLEVEL, true);
|
||||
at_level_dead(scene);
|
||||
}
|
||||
}
|
||||
|
||||
void init_sandbox_scene(LevelScene_t* scene)
|
||||
{
|
||||
init_scene(&scene->scene, &level_do_action);
|
||||
|
@ -1116,7 +1151,11 @@ void init_sandbox_scene(LevelScene_t* scene)
|
|||
&scene->data, MAX_N_TILES, all_tiles,
|
||||
(Rectangle){25, 25, VIEWABLE_EDITOR_MAP_WIDTH*TILE_SIZE, VIEWABLE_EDITOR_MAP_HEIGHT*TILE_SIZE}
|
||||
);
|
||||
scene->data.show_grid = true;
|
||||
scene->data.sm.state_functions[LEVEL_STATE_STARTING] = at_level_start;
|
||||
scene->data.sm.state_functions[LEVEL_STATE_RUNNING] = NULL;
|
||||
scene->data.sm.state_functions[LEVEL_STATE_DEAD] = at_level_dead;
|
||||
scene->data.sm.state_functions[LEVEL_STATE_COMPLETE] = at_level_complete;
|
||||
|
||||
scene->data.tile_sprites[ONEWAY_TILE] = get_sprite(&scene->scene.engine->assets, "tl_owp");
|
||||
scene->data.tile_sprites[LADDER] = get_sprite(&scene->scene.engine->assets, "tl_ldr");
|
||||
scene->data.tile_sprites[SPIKES] = get_sprite(&scene->scene.engine->assets, "d_spikes");
|
||||
|
@ -1363,8 +1402,8 @@ void init_sandbox_scene(LevelScene_t* scene)
|
|||
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, &check_player_dead_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, &level_state_management_system);
|
||||
sc_array_add(&scene->scene.systems, &render_editor_game_scene);
|
||||
sc_array_add(&scene->scene.systems, &level_scene_render_func);
|
||||
|
||||
|
|
|
@ -416,6 +416,19 @@ static void render_regular_game_scene(Scene_t* scene)
|
|||
EndTextureMode();
|
||||
}
|
||||
|
||||
static void at_level_start(Scene_t* scene)
|
||||
{
|
||||
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
|
||||
data->sm.state = LEVEL_STATE_RUNNING;
|
||||
}
|
||||
|
||||
static void at_level_complete(Scene_t* scene)
|
||||
{
|
||||
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
|
||||
do_action(scene, ACTION_NEXTLEVEL, true);
|
||||
data->sm.state = LEVEL_STATE_STARTING;
|
||||
}
|
||||
|
||||
void init_game_scene(LevelScene_t* scene)
|
||||
{
|
||||
init_scene(&scene->scene, &level_do_action);
|
||||
|
@ -433,6 +446,10 @@ void init_game_scene(LevelScene_t* scene)
|
|||
VIEWABLE_MAP_WIDTH*TILE_SIZE, VIEWABLE_MAP_HEIGHT*TILE_SIZE
|
||||
}
|
||||
);
|
||||
scene->data.sm.state_functions[LEVEL_STATE_STARTING] = at_level_start;
|
||||
scene->data.sm.state_functions[LEVEL_STATE_RUNNING] = NULL;
|
||||
scene->data.sm.state_functions[LEVEL_STATE_DEAD] = NULL;
|
||||
scene->data.sm.state_functions[LEVEL_STATE_COMPLETE] = at_level_complete;
|
||||
|
||||
scene->scene.bg_colour = LIGHTGRAY;
|
||||
add_scene_layer(
|
||||
|
@ -480,9 +497,10 @@ void init_game_scene(LevelScene_t* scene)
|
|||
sc_array_add(&scene->scene.systems, &sprite_animation_system);
|
||||
sc_array_add(&scene->scene.systems, &camera_update_system);
|
||||
sc_array_add(&scene->scene.systems, &player_dir_reset_system);
|
||||
sc_array_add(&scene->scene.systems, &check_player_dead_system);
|
||||
//sc_array_add(&scene->scene.systems, &player_respawn_system);
|
||||
sc_array_add(&scene->scene.systems, &update_water_runner_system);
|
||||
sc_array_add(&scene->scene.systems, &check_player_dead_system);
|
||||
sc_array_add(&scene->scene.systems, &level_end_detection_system);
|
||||
sc_array_add(&scene->scene.systems, &level_state_management_system);
|
||||
sc_array_add(&scene->scene.systems, &render_regular_game_scene);
|
||||
sc_array_add(&scene->scene.systems, &level_scene_render_func);
|
||||
// This avoid graphical glitch, not essential
|
||||
|
|
|
@ -231,7 +231,6 @@ void destroy_entity(Scene_t* scene, TileGrid_t* tilemap, Entity_t* p_ent)
|
|||
void check_player_dead_system(Scene_t* scene)
|
||||
{
|
||||
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
|
||||
TileGrid_t tilemap = data->tilemap;
|
||||
Entity_t* p_player;
|
||||
// Cannot create player while looping though the players
|
||||
// So have to create outside of the loop
|
||||
|
@ -245,25 +244,7 @@ void check_player_dead_system(Scene_t* scene)
|
|||
ent->position = p_player->position;
|
||||
}
|
||||
destroy_entity(scene, &data->tilemap, p_player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void player_respawn_system(Scene_t* scene)
|
||||
{
|
||||
Entity_t* p_player;
|
||||
// Cannot create player while looping though the players
|
||||
// So have to create outside of the loop
|
||||
sc_map_foreach_value(&scene->ent_manager.entities_map[PLAYER_ENT_TAG], p_player)
|
||||
{
|
||||
if (!p_player->m_alive)
|
||||
{
|
||||
|
||||
Entity_t* new_player = create_player(&scene->ent_manager);
|
||||
CTransform_t* p_ct = get_component(new_player, CTRANSFORM_COMP_T);
|
||||
new_player->position = p_player->spawn_pos;
|
||||
memset(&p_ct->velocity, 0, sizeof(p_ct->velocity));
|
||||
memset(&p_ct->accel, 0, sizeof(p_ct->accel));
|
||||
change_level_state(data, LEVEL_STATE_DEAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1486,10 +1467,8 @@ void update_tilemap_system(Scene_t* scene)
|
|||
{
|
||||
Entity_t* p_ent = get_entity(&scene->ent_manager, ent_idx);
|
||||
if (!p_ent->m_alive) continue;
|
||||
CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T);
|
||||
if (p_ctransform == NULL) continue;
|
||||
CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
|
||||
|
||||
CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
|
||||
// Update tilemap position
|
||||
for (size_t i = 0;i < p_tilecoord->n_tiles; ++i)
|
||||
{
|
||||
|
@ -2038,13 +2017,27 @@ void level_end_detection_system(Scene_t* scene)
|
|||
)
|
||||
)
|
||||
{
|
||||
do_action(scene, ACTION_NEXTLEVEL, true);
|
||||
destroy_entity(scene, &lvl_scene->data.tilemap, p_other_ent);
|
||||
change_level_state(&lvl_scene->data, LEVEL_STATE_COMPLETE);
|
||||
|
||||
|
||||
//do_action(scene, ACTION_NEXTLEVEL, true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void level_state_management_system(Scene_t* scene)
|
||||
{
|
||||
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
|
||||
|
||||
if (data->sm.state_functions[data->sm.state] != NULL)
|
||||
{
|
||||
data->sm.state_functions[data->sm.state](scene);
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool is_point_in_water(Vector2 pos, TileGrid_t tilemap)
|
||||
{
|
||||
unsigned int tile_idx = get_tile_idx(pos.x, pos.y, tilemap);
|
||||
|
|
|
@ -22,11 +22,11 @@ void boulder_destroy_wooden_tile_system(Scene_t* scene);
|
|||
void camera_update_system(Scene_t* scene);
|
||||
void container_destroy_system(Scene_t* scene);
|
||||
void player_dir_reset_system(Scene_t* scene);
|
||||
void player_respawn_system(Scene_t* scene);
|
||||
void check_player_dead_system(Scene_t* scene);
|
||||
void lifetimer_update_system(Scene_t* scene);
|
||||
void airtimer_update_system(Scene_t* scene);
|
||||
void spike_collision_system(Scene_t* scene);
|
||||
void level_end_detection_system(Scene_t* scene);
|
||||
void level_state_management_system(Scene_t* scene);
|
||||
|
||||
#endif // __GAME_SYSTEMS_H
|
||||
|
|
|
@ -256,6 +256,6 @@ Entity_t* create_level_end(EntityManager_t* ent_manager)
|
|||
Entity_t* p_flag = add_entity(ent_manager, LEVEL_END_TAG);
|
||||
if (p_flag == NULL) return NULL;
|
||||
|
||||
add_component(p_flag, CTRANSFORM_COMP_T);
|
||||
add_component(p_flag, CTILECOORD_COMP_T);
|
||||
return p_flag;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,22 @@ typedef struct LevelCamera {
|
|||
float range_limit;
|
||||
}LevelCamera_t;
|
||||
|
||||
typedef enum LevelSceneState {
|
||||
LEVEL_STATE_STARTING = 0,
|
||||
LEVEL_STATE_RUNNING,
|
||||
LEVEL_STATE_DEAD,
|
||||
LEVEL_STATE_COMPLETE,
|
||||
} LevelSceneState_t;
|
||||
|
||||
typedef struct LevelSceneStateMachine {
|
||||
LevelSceneState_t state;
|
||||
system_func_t state_functions[4];
|
||||
|
||||
// Engine has no timeline support, so make a pseudo timeline implementation
|
||||
float fractional;
|
||||
uint32_t counter;
|
||||
} LevelSceneStateMachine_t;
|
||||
|
||||
typedef struct LevelSceneData {
|
||||
TileGrid_t tilemap;
|
||||
// TODO: game_rec is actually obsolete since this is in the scene game layer
|
||||
|
@ -57,8 +73,17 @@ typedef struct LevelSceneData {
|
|||
unsigned int current_level;
|
||||
CoinCounter_t coins;
|
||||
bool show_grid;
|
||||
Vector2 player_spawn;
|
||||
LevelSceneStateMachine_t sm;
|
||||
}LevelSceneData_t;
|
||||
|
||||
static inline void change_level_state(LevelSceneData_t* data, LevelSceneState_t state)
|
||||
{
|
||||
data->sm.state = state;
|
||||
data->sm.counter = 0;
|
||||
data->sm.fractional = 0;
|
||||
}
|
||||
|
||||
typedef struct LevelScene {
|
||||
Scene_t scene;
|
||||
LevelSceneData_t data;
|
||||
|
|
|
@ -41,6 +41,8 @@ void init_level_scene_data(LevelSceneData_t* data, uint32_t max_tiles, Tile_t* t
|
|||
}
|
||||
memset(&data->coins, 0, sizeof(data->coins));
|
||||
data->show_grid = false;
|
||||
|
||||
memset(&data->sm, 0, sizeof(data->sm));
|
||||
}
|
||||
|
||||
void term_level_scene_data(LevelSceneData_t* data)
|
||||
|
@ -145,7 +147,6 @@ bool load_level_tilemap(LevelScene_t* scene, unsigned int level_num)
|
|||
Entity_t* ent = create_player(&scene->scene.ent_manager);
|
||||
ent->position.x = (i % scene->data.tilemap.width) * scene->data.tilemap.tile_size;
|
||||
ent->position.y = (i / scene->data.tilemap.width) * scene->data.tilemap.tile_size;
|
||||
ent->spawn_pos = ent->position;
|
||||
}
|
||||
break;
|
||||
case 23:
|
||||
|
|
Loading…
Reference in New Issue