Implement Chest Entity

Internal Changelog:
- chest entity: Basically crates, but high def, and fragile
- Add new spawn type for chest
- Add atk modifier for player->chest
- Make crate non-fragile
- Ignore chest for collision check and move with player
scene_man
En Yi 2023-09-21 21:48:32 +08:00
parent 57f6a154b0
commit e1a0c6e4e0
5 changed files with 72 additions and 7 deletions

View File

@ -17,6 +17,7 @@ enum EntitySpawnSelection {
TOGGLE_SPIKE, TOGGLE_SPIKE,
TOGGLE_WATER, TOGGLE_WATER,
TOGGLE_AIR_POCKET, TOGGLE_AIR_POCKET,
SPAWN_CHEST,
SPAWN_CRATE, SPAWN_CRATE,
SPAWN_CRATE_ARROW_L, SPAWN_CRATE_ARROW_L,
SPAWN_CRATE_ARROW_R, SPAWN_CRATE_ARROW_R,
@ -27,7 +28,7 @@ enum EntitySpawnSelection {
SPAWN_WATER_RUNNER, SPAWN_WATER_RUNNER,
}; };
#define MAX_SPAWN_TYPE 14 #define MAX_SPAWN_TYPE 15
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;
@ -48,6 +49,7 @@ static char* get_spawn_selection_string(enum EntitySpawnSelection sel)
case TOGGLE_SPIKE: return "spike"; case TOGGLE_SPIKE: return "spike";
case TOGGLE_WATER: return "water"; case TOGGLE_WATER: return "water";
case TOGGLE_AIR_POCKET: return "air pocket"; case TOGGLE_AIR_POCKET: return "air pocket";
case SPAWN_CHEST: return "chest";
case SPAWN_CRATE: return (metal_toggle) ? "metal crate" : "wooden crate"; case SPAWN_CRATE: return (metal_toggle) ? "metal crate" : "wooden crate";
case SPAWN_CRATE_ARROW_D: return (metal_toggle) ? "metal down arrow crate" : "wooden down arrow crate"; case SPAWN_CRATE_ARROW_D: return (metal_toggle) ? "metal down arrow crate" : "wooden down arrow crate";
case SPAWN_CRATE_ARROW_U: return (metal_toggle) ? "metal up arrow crate" : "wooden up arrow crate"; case SPAWN_CRATE_ARROW_U: return (metal_toggle) ? "metal up arrow crate" : "wooden up arrow crate";
@ -216,6 +218,9 @@ static void level_scene_render_func(Scene_t* scene)
case BOULDER_ENT_TAG: case BOULDER_ENT_TAG:
colour = GRAY; colour = GRAY;
break; break;
case CHEST_ENT_TAG:
colour = YELLOW;
break;
default: default:
colour = BLACK; colour = BLACK;
break; break;
@ -449,6 +454,18 @@ static void level_scene_render_func(Scene_t* scene)
EndDrawing(); EndDrawing();
} }
static void spawn_chest(Scene_t* scene, unsigned int tile_idx)
{
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
Entity_t* p_crate = create_chest(&scene->ent_manager, &scene->engine->assets);
if (p_crate == NULL) return;
CTransform_t* p_ctransform = get_component(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;
p_ctransform->active = true;
}
static void spawn_crate(Scene_t* scene, unsigned int tile_idx, bool metal, ContainerItem_t item, bool active) static void spawn_crate(Scene_t* scene, unsigned int tile_idx, bool metal, ContainerItem_t item, bool active)
{ {
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data); LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
@ -573,6 +590,9 @@ static void toggle_block_system(Scene_t* scene)
} }
} }
break; break;
case SPAWN_CHEST:
spawn_chest(scene, tile_idx);
break;
} }
change_a_tile(&tilemap, tile_idx, new_type); change_a_tile(&tilemap, tile_idx, new_type);
last_tile_idx = tile_idx; last_tile_idx = tile_idx;
@ -819,8 +839,9 @@ void init_sandbox_scene(LevelScene_t* scene)
Vector2 draw_pos = {0, 0}; Vector2 draw_pos = {0, 0};
const Color crate_colour = metal_toggle ? GRAY : BROWN; const Color crate_colour = metal_toggle ? GRAY : BROWN;
const Color draw_colour[MAX_SPAWN_TYPE] = { const Color draw_colour[MAX_SPAWN_TYPE] = {
BLACK, MAROON, ORANGE, ColorAlpha(RAYWHITE, 0.5), ColorAlpha(BLUE, 0.5), ColorAlpha(RAYWHITE, 0.5), BLACK, MAROON, ORANGE, ColorAlpha(RAYWHITE, 0.5), ColorAlpha(BLUE, 0.5),
crate_colour, crate_colour, crate_colour, crate_colour, crate_colour, crate_colour, ColorAlpha(RAYWHITE, 0.5), YELLOW, 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)
}; };
for (uint8_t i = 0; i < MAX_SPAWN_TYPE; ++i) for (uint8_t i = 0; i < MAX_SPAWN_TYPE; ++i)

View File

@ -7,6 +7,7 @@ typedef enum EntityTag {
PLAYER_ENT_TAG, PLAYER_ENT_TAG,
ENEMY_ENT_TAG, ENEMY_ENT_TAG,
CRATES_ENT_TAG, CRATES_ENT_TAG,
CHEST_ENT_TAG,
BOULDER_ENT_TAG, BOULDER_ENT_TAG,
DESTRUCTABLE_ENT_TAG, DESTRUCTABLE_ENT_TAG,
DYNMEM_ENT_TAG, DYNMEM_ENT_TAG,
@ -25,5 +26,6 @@ Entity_t* create_boulder(EntityManager_t* ent_manager, Assets_t* assets);
Entity_t* create_arrow(EntityManager_t* ent_manager, Assets_t* assets, uint8_t dir); Entity_t* create_arrow(EntityManager_t* ent_manager, Assets_t* assets, uint8_t dir);
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);
#endif // __ENT_IMPL_H #endif // __ENT_IMPL_H

View File

@ -668,10 +668,16 @@ void tile_collision_system(Scene_t* scene)
if (p_other_bbox == NULL) continue; if (p_other_bbox == NULL) continue;
CTransform_t *p_other_ct = get_component(p_other_ent, CTRANSFORM_COMP_T); CTransform_t *p_other_ct = get_component(p_other_ent, CTRANSFORM_COMP_T);
SolidType_t solid = p_other_bbox->solid? SOLID : NOT_SOLID;
if (p_ent->m_tag == PLAYER_ENT_TAG && p_other_ent->m_tag == CHEST_ENT_TAG)
{
solid = NOT_SOLID;
}
check_collision_and_move( check_collision_and_move(
&tilemap, p_ent, &tilemap, p_ent,
&p_other_ct->position, p_other_bbox->size, &p_other_ct->position, p_other_bbox->size,
p_other_bbox->solid? SOLID : NOT_SOLID solid
); );
} }
} }
@ -681,7 +687,7 @@ void tile_collision_system(Scene_t* scene)
// Post movement edge check to zero out velocity // Post movement edge check to zero out velocity
uint8_t edges = check_bbox_edges( uint8_t edges = check_bbox_edges(
&data->tilemap, p_ent, &data->tilemap, p_ent,
p_ctransform->position, p_ctransform->prev_position, p_bbox->size, false p_ctransform->position, p_ctransform->prev_position, p_bbox->size, true
); );
if (edges & (1<<3)) if (edges & (1<<3))
{ {
@ -1447,7 +1453,13 @@ void hitbox_update_system(Scene_t* scene)
) )
{ {
hit = true; hit = true;
if (p_hitbox->atk > p_other_hurtbox->def)
uint8_t full_atk = p_hitbox->atk;
if (p_ent->m_tag == PLAYER_ENT_TAG && p_other_ent->m_tag == CHEST_ENT_TAG)
{
full_atk = p_other_hurtbox->def + 1;
}
if (full_atk > p_other_hurtbox->def)
{ {
p_other_hurtbox->damage_src = ent_idx; p_other_hurtbox->damage_src = ent_idx;
if (p_other_ent->m_tag == CRATES_ENT_TAG) if (p_other_ent->m_tag == CRATES_ENT_TAG)

View File

@ -39,7 +39,7 @@ Entity_t* create_crate(EntityManager_t* ent_manager, Assets_t* assets, bool meta
CBBox_t* p_bbox = add_component(p_crate, CBBOX_COMP_T); CBBox_t* p_bbox = add_component(p_crate, CBBOX_COMP_T);
set_bbox(p_bbox, TILE_SIZE, TILE_SIZE); set_bbox(p_bbox, TILE_SIZE, TILE_SIZE);
p_bbox->solid = true; p_bbox->solid = true;
p_bbox->fragile = !metal; p_bbox->fragile = false;
CTransform_t* p_ctransform = add_component(p_crate, CTRANSFORM_COMP_T); CTransform_t* p_ctransform = add_component(p_crate, CTRANSFORM_COMP_T);
p_ctransform->grav_delay = 7; p_ctransform->grav_delay = 7;
@ -202,3 +202,26 @@ Entity_t* create_explosion(EntityManager_t* ent_manager, Assets_t* assets)
p_clifetimer->life_time = 3; p_clifetimer->life_time = 3;
return p_explosion; return p_explosion;
} }
Entity_t* create_chest(EntityManager_t* ent_manager, Assets_t* assets)
{
Entity_t* p_chest = add_entity(ent_manager, CHEST_ENT_TAG);
if (p_chest == NULL) return NULL;
CBBox_t* p_bbox = add_component(p_chest, CBBOX_COMP_T);
set_bbox(p_bbox, TILE_SIZE, TILE_SIZE);
p_bbox->solid = true;
p_bbox->fragile = true;
CTransform_t* p_ctransform = add_component(p_chest, CTRANSFORM_COMP_T);
p_ctransform->grav_delay = 7;
p_ctransform->shape_factor = (Vector2){0.7,0.7};
add_component(p_chest, CMOVEMENTSTATE_T);
add_component(p_chest, CTILECOORD_COMP_T);
CHurtbox_t* p_hurtbox = add_component(p_chest, CHURTBOX_T);
p_hurtbox->size = p_bbox->size;
p_hurtbox->def = 4;
p_hurtbox->damage_src = -1;
return p_chest;
}

View File

@ -21,6 +21,12 @@ typedef enum TileType {
#define MAX_TILE_SPRITES 32 #define MAX_TILE_SPRITES 32
typedef struct CoinCounter
{
uint16_t current;
uint16_t total;
}CoinCounter_t;
typedef struct LevelSceneData { typedef struct LevelSceneData {
TileGrid_t tilemap; TileGrid_t tilemap;
RenderTexture2D game_viewport; RenderTexture2D game_viewport;
@ -29,6 +35,7 @@ typedef struct LevelSceneData {
Sprite_t* tile_sprites[MAX_TILE_SPRITES]; Sprite_t* tile_sprites[MAX_TILE_SPRITES];
LevelPack_t* level_pack; LevelPack_t* level_pack;
unsigned int current_level; unsigned int current_level;
CoinCounter_t coins;
}LevelSceneData_t; }LevelSceneData_t;
typedef struct LevelScene { typedef struct LevelScene {