diff --git a/actions.h b/actions.h index cc5a21e..4c74d3a 100644 --- a/actions.h +++ b/actions.h @@ -7,5 +7,7 @@ typedef enum ActionType ACTION_LEFT, ACTION_RIGHT, ACTION_JUMP, + ACTION_NEXT_SPAWN, + ACTION_PREV_SPAWN, }ActionType_t; #endif // __ACTIONS_H diff --git a/components.h b/components.h index 5dd8184..50e4819 100644 --- a/components.h +++ b/components.h @@ -4,7 +4,7 @@ #include // TODO: Look at sc to use macros to auto generate functions -#define N_COMPONENTS 6 +#define N_COMPONENTS 7 enum ComponentEnum { CBBOX_COMP_T, @@ -12,7 +12,8 @@ enum ComponentEnum CTILECOORD_COMP_T, CMOVEMENTSTATE_T, CJUMP_COMP_T, - CPLAYERSTATE_T + CPLAYERSTATE_T, + CCONTAINER_T, }; typedef enum ComponentEnum ComponentEnum_t; @@ -69,6 +70,29 @@ typedef struct _CPlayerState_t uint8_t is_crouch: 1; }CPlayerState_t; +typedef enum ContainerItem +{ + CONTAINER_EMPTY, + CONTAINER_LEFT_ARROW, + CONTAINER_RIGHT_ARROW, + CONTAINER_UP_ARROW, + CONTAINER_DOWN_ARROW, + CONTAINER_COIN, + CONTAINER_BOMB, +}ContainerItem_t; + +typedef enum ContainerMaterial +{ + WOODEN_CONTAINER, + METAL_CONTAINER, +}ContainerMaterial_t; + +typedef struct _CContainer_t +{ + ContainerMaterial_t material; + ContainerItem_t item; +}CContainer_t; + static inline void set_bbox(CBBox_t* p_bbox, unsigned int x, unsigned int y) { diff --git a/entity.h b/entity.h index 4adbed3..c1ec0cb 100644 --- a/entity.h +++ b/entity.h @@ -3,12 +3,13 @@ #include #include "sc/map/sc_map.h" -#define N_TAGS 3 +#define N_TAGS 4 enum EntityTag { NO_ENT_TAG, PLAYER_ENT_TAG, ENEMY_ENT_TAG, + CRATES_ENT_TAG, }; typedef enum EntityTag EntityTag_t; typedef struct Entity diff --git a/mempool.c b/mempool.c index 657c5de..9c573a5 100644 --- a/mempool.c +++ b/mempool.c @@ -10,6 +10,7 @@ static CTileCoord_t ctilecoord_buffer[MAX_COMP_POOL_SIZE]; static CMovementState_t cmstate_buffer[MAX_COMP_POOL_SIZE]; static CJump_t cjump_buffer[1]; // Only player is expected to have this static CPlayerState_t cplayerstate_buffer[1]; // Only player is expected to have this +static CContainer_t ccontainer_buffer[MAX_COMP_POOL_SIZE]; // Use hashmap as a Set // Use list will be used to check if an object exist @@ -35,6 +36,7 @@ static MemPool_t comp_mempools[N_COMPONENTS] = {cmstate_buffer, MAX_COMP_POOL_SIZE, sizeof(CMovementState_t), NULL, {0}}, {cjump_buffer, 1, sizeof(CJump_t), NULL, {0}}, {cplayerstate_buffer, 1, sizeof(CPlayerState_t), NULL, {0}}, + {ccontainer_buffer, MAX_COMP_POOL_SIZE, sizeof(CContainer_t), NULL, {0}}, }; static MemPool_t ent_mempool = {entity_buffer, MAX_COMP_POOL_SIZE, sizeof(Entity_t), NULL, {0}}; diff --git a/scene_impl.c b/scene_impl.c index 5dca330..6314a07 100644 --- a/scene_impl.c +++ b/scene_impl.c @@ -11,6 +11,14 @@ static Tile_t all_tiles[MAX_N_TILES] = {0}; static const Vector2 GRAVITY = {0, GRAV_ACCEL}; static const Vector2 UPTHRUST = {0, -GRAV_ACCEL * 1.1}; +enum EntitySpawnSelection +{ + TOGGLE_TILE = 0, + SPAWN_CRATE, +}; +#define MAX_SPAWN_TYPE 2 +static unsigned int current_spawn_selection = 0; + static inline unsigned int get_tile_idx(int x, int y, unsigned int tilemap_width) { unsigned int tile_x = x / TILE_SIZE; @@ -179,6 +187,26 @@ static void level_scene_render_func(Scene_t* scene) LevelSceneData_t *data = (LevelSceneData_t *)scene->scene_data; TileGrid_t tilemap = data->tilemap; + Entity_t *p_ent; + sc_map_foreach_value(&scene->ent_manager.entities, p_ent) + { + CTransform_t* p_ct = get_component(&scene->ent_manager, p_ent, CTRANSFORM_COMP_T); + CBBox_t* p_bbox = get_component(&scene->ent_manager, p_ent, CBBOX_COMP_T); + Color colour; + switch(p_ent->m_tag) + { + case PLAYER_ENT_TAG: + colour = RED; + break; + case CRATES_ENT_TAG: + colour = BROWN; + break; + default: + colour = BLACK; + } + DrawRectangle(p_ct->position.x, p_ct->position.y, p_bbox->size.x, p_bbox->size.y, colour); + } + for (size_t i=0; ient_manager.entities, p_ent) - { - CTransform_t* p_ct = get_component(&scene->ent_manager, p_ent, CTRANSFORM_COMP_T); - CBBox_t* p_bbox = get_component(&scene->ent_manager, p_ent, CBBOX_COMP_T); - DrawRectangle(p_ct->position.x, p_ct->position.y, p_bbox->size.x, p_bbox->size.y, RED); - } - // Draw tile grid for (size_t i=0; iwater_state & 1? "YES":"NO"); DrawText(buffer, tilemap.width * TILE_SIZE + 1, 120, 12, BLACK); + sprintf(buffer, "Spawn Entity: %u", current_spawn_selection); + DrawText(buffer, tilemap.width * TILE_SIZE + 1, 240, 12, BLACK); } } @@ -509,17 +531,19 @@ static void player_ground_air_transition_system(Scene_t* scene) } } -static void player_collision_system(Scene_t *scene) +static void tile_collision_system(Scene_t *scene) { LevelSceneData_t *data = (LevelSceneData_t *)scene->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) + unsigned int ent_idx; + CBBox_t* p_bbox; + //sc_map_foreach_value(&scene->ent_manager.entities_map[PLAYER_ENT_TAG], p_player) + sc_map_foreach(&scene->ent_manager.component_map[CBBOX_COMP_T], ent_idx, p_bbox) { - CTransform_t* p_ctransform = get_component(&scene->ent_manager, p_player, CTRANSFORM_COMP_T); - CBBox_t* p_bbox = get_component(&scene->ent_manager, p_player, CBBOX_COMP_T); + Entity_t *p_ent = get_entity(&scene->ent_manager, ent_idx); + CTransform_t* p_ctransform = get_component(&scene->ent_manager, p_ent, CTRANSFORM_COMP_T); // Get the occupied tiles // For each tile, loop through the entities and find overlaps // exclude self @@ -543,7 +567,6 @@ static void player_collision_system(Scene_t *scene) Vector2 other; if(tilemap.tiles[tile_idx].solid) { - other.x = (tile_idx % tilemap.width) * TILE_SIZE; other.y = (tile_idx / tilemap.width) * TILE_SIZE; // Precision loss is intentional if (find_AABB_overlap(p_ctransform->position, p_bbox->size, other, TILE_SZ, &overlap)) @@ -714,6 +737,35 @@ static void update_tilemap_system(Scene_t *scene) } } +static void spawn_crate(Scene_t *scene, unsigned int tile_idx) +{ + LevelSceneData_t *data = (LevelSceneData_t *)scene->scene_data; + Entity_t *p_crate = add_entity(&scene->ent_manager, CRATES_ENT_TAG); + CBBox_t *p_bbox = add_component(&scene->ent_manager, p_crate, CBBOX_COMP_T); + set_bbox(p_bbox, TILE_SIZE, TILE_SIZE); + CTransform_t *p_ctransform = add_component(&scene->ent_manager, p_crate, CTRANSFORM_COMP_T); + p_ctransform->position.x = (tile_idx % data->tilemap.width) * TILE_SIZE; + p_ctransform->position.y = (tile_idx / data->tilemap.width) * TILE_SIZE; + add_component(&scene->ent_manager, p_crate, CMOVEMENTSTATE_T); + add_component(&scene->ent_manager, p_crate, CTILECOORD_COMP_T); +} + +static void spawn_player(Scene_t *scene) +{ + Entity_t *p_ent = add_entity(&scene->ent_manager, PLAYER_ENT_TAG); + + CBBox_t *p_bbox = add_component(&scene->ent_manager, p_ent, CBBOX_COMP_T); + set_bbox(p_bbox, 30, 45); + add_component(&scene->ent_manager, p_ent, CTRANSFORM_COMP_T); + CJump_t *p_cjump = add_component(&scene->ent_manager, p_ent, CJUMP_COMP_T); + p_cjump->jump_speed = 680; + p_cjump->jumps = 1; + p_cjump->max_jumps = 1; + add_component(&scene->ent_manager, p_ent, CPLAYERSTATE_T); + add_component(&scene->ent_manager, p_ent, CTILECOORD_COMP_T); + add_component(&scene->ent_manager, p_ent, CMOVEMENTSTATE_T); +} + static void toggle_block_system(Scene_t *scene) { // TODO: This system is not good as the interface between raw input and actions is broken @@ -724,10 +776,19 @@ static void toggle_block_system(Scene_t *scene) if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) { unsigned int tile_idx = get_tile_idx(GetMouseX(), GetMouseY(), tilemap.width); + enum EntitySpawnSelection sel = (enum EntitySpawnSelection)current_spawn_selection; if (tile_idx != last_tile_idx) { - tilemap.tiles[tile_idx].solid = !tilemap.tiles[tile_idx].solid; - tilemap.tiles[tile_idx].water_level = 0; + switch (sel) + { + case TOGGLE_TILE: + tilemap.tiles[tile_idx].solid = !tilemap.tiles[tile_idx].solid; + tilemap.tiles[tile_idx].water_level = 0; + break; + case SPAWN_CRATE: + spawn_crate(scene, tile_idx); + break; + } last_tile_idx = tile_idx; } } @@ -777,6 +838,20 @@ void level_do_action(Scene_t *scene, ActionType_t action, bool pressed) case ACTION_JUMP: p_playerstate->jump_pressed = pressed; break; + case ACTION_NEXT_SPAWN: + if (!pressed) + { + current_spawn_selection++; + current_spawn_selection &= 1; + } + break; + case ACTION_PREV_SPAWN: + if (!pressed) + { + current_spawn_selection--; + current_spawn_selection &= 1; + } + break; } } } @@ -791,8 +866,8 @@ void init_level_scene(LevelScene_t *scene) sc_array_add(&scene->scene.systems, &player_bbox_update_system); sc_array_add(&scene->scene.systems, &global_external_forces_system); sc_array_add(&scene->scene.systems, &movement_update_system); + sc_array_add(&scene->scene.systems, &tile_collision_system); sc_array_add(&scene->scene.systems, &update_tilemap_system); - sc_array_add(&scene->scene.systems, &player_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, &toggle_block_system); @@ -805,6 +880,8 @@ void init_level_scene(LevelScene_t *scene) sc_map_put_64(&scene->scene.action_map, KEY_LEFT, ACTION_LEFT); sc_map_put_64(&scene->scene.action_map, KEY_RIGHT, ACTION_RIGHT); sc_map_put_64(&scene->scene.action_map, KEY_SPACE, ACTION_JUMP); + sc_map_put_64(&scene->scene.action_map, KEY_O, ACTION_PREV_SPAWN); + sc_map_put_64(&scene->scene.action_map, KEY_P, ACTION_NEXT_SPAWN); scene->data.tilemap.width = 32; scene->data.tilemap.height = 16; @@ -820,6 +897,9 @@ void init_level_scene(LevelScene_t *scene) { all_tiles[15*32+i].solid = true; // for testing } + + spawn_player(&scene->scene); + update_entity_manager(&scene->scene.ent_manager); } void free_level_scene(LevelScene_t *scene) diff --git a/scene_test.c b/scene_test.c index 7466ef0..5afc7e4 100644 --- a/scene_test.c +++ b/scene_test.c @@ -14,20 +14,6 @@ int main(void) init_memory_pools(); LevelScene_t scene; init_level_scene(&scene); - Entity_t *p_ent = add_entity(&scene.scene.ent_manager, PLAYER_ENT_TAG); - - CBBox_t *p_bbox = add_component(&scene.scene.ent_manager, p_ent, CBBOX_COMP_T); - set_bbox(p_bbox, 30, 45); - add_component(&scene.scene.ent_manager, p_ent, CTRANSFORM_COMP_T); - CJump_t *p_cjump = add_component(&scene.scene.ent_manager, p_ent, CJUMP_COMP_T); - p_cjump->jump_speed = 680; - p_cjump->jumps = 1; - p_cjump->max_jumps = 1; - add_component(&scene.scene.ent_manager, p_ent, CPLAYERSTATE_T); - add_component(&scene.scene.ent_manager, p_ent, CTILECOORD_COMP_T); - add_component(&scene.scene.ent_manager, p_ent, CMOVEMENTSTATE_T); - update_entity_manager(&scene.scene.ent_manager); - //for (size_t step = 0; step < 6000; step++) while(true) { @@ -63,6 +49,7 @@ int main(void) } update_scene(&scene.scene); + update_entity_manager(&scene.scene.ent_manager); // This is needed to advance time delta BeginDrawing(); render_scene(&scene.scene);