Implement Crates
Changelog: - Add new component: container - Add function to spawn a crate - Refactor player spawning into level scene init - Modify tile collision to work on bbox components - Add actions to switch entity to spawn - Update spawn system to spawn a cratescene_man
parent
af080dbdc8
commit
0b342bb9be
|
@ -7,5 +7,7 @@ typedef enum ActionType
|
|||
ACTION_LEFT,
|
||||
ACTION_RIGHT,
|
||||
ACTION_JUMP,
|
||||
ACTION_NEXT_SPAWN,
|
||||
ACTION_PREV_SPAWN,
|
||||
}ActionType_t;
|
||||
#endif // __ACTIONS_H
|
||||
|
|
28
components.h
28
components.h
|
@ -4,7 +4,7 @@
|
|||
#include <stdint.h>
|
||||
// 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)
|
||||
{
|
||||
|
|
3
entity.h
3
entity.h
|
@ -3,12 +3,13 @@
|
|||
#include <stdbool.h>
|
||||
#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
|
||||
|
|
|
@ -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}};
|
||||
|
||||
|
|
114
scene_impl.c
114
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; i<tilemap.n_tiles;++i)
|
||||
{
|
||||
char buffer[6] = {0};
|
||||
|
@ -202,14 +230,6 @@ static void level_scene_render_func(Scene_t* scene)
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
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; i<tilemap.width;++i)
|
||||
{
|
||||
|
@ -240,6 +260,8 @@ static void level_scene_render_func(Scene_t* scene)
|
|||
DrawText(buffer, tilemap.width * TILE_SIZE + 1, 90, 12, BLACK);
|
||||
sprintf(buffer, "Water: %s", p_mstate->water_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)
|
||||
|
|
15
scene_test.c
15
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);
|
||||
|
|
Loading…
Reference in New Issue