fp: Add hitboxes to buildings, fix collision detection skipping detections

This commit is contained in:
doyle 2023-10-01 22:16:49 +11:00
parent c5a76e6b97
commit be88c34439
2 changed files with 71 additions and 62 deletions

View File

@ -117,10 +117,13 @@ static void FP_Game_MoveEntity(FP_Game *game, FP_GameEntityHandle entity_handle,
Dqn_V2 delta_pos = (acceleration * 0.5f * t_squared) + (entity->velocity * t); Dqn_V2 delta_pos = (acceleration * 0.5f * t_squared) + (entity->velocity * t);
Dqn_Rect entity_world_hit_box = FP_Game_CalcEntityWorldHitBox(game, entity->handle); Dqn_Rect entity_world_hit_box = FP_Game_CalcEntityWorldHitBox(game, entity->handle);
Dqn_V2 entity_pos = Dqn_Rect_Center(entity_world_hit_box); Dqn_V2 entity_pos = FP_Game_CalcEntityWorldPos(game, entity->handle);
Dqn_V2 entity_new_pos = entity_pos + delta_pos; Dqn_V2 entity_new_pos = entity_pos + delta_pos;
bool has_collision = false; Dqn_f32 const SENTINEL_T = 999.f;
Dqn_f32 global_earliest_t = SENTINEL_T;
Dqn_V2 global_earliest_pos_just_before_collide = {};
for (FP_GameEntityIterator collider_it = {}; FP_Game_DFSPostOrderWalkEntityTree(game, &collider_it, game->root_entity); ) { for (FP_GameEntityIterator collider_it = {}; FP_Game_DFSPostOrderWalkEntityTree(game, &collider_it, game->root_entity); ) {
FP_GameEntity *collider = collider_it.entity; FP_GameEntity *collider = collider_it.entity;
if (collider->handle == entity->handle) if (collider->handle == entity->handle)
@ -181,7 +184,6 @@ static void FP_Game_MoveEntity(FP_Game *game, FP_GameEntityHandle entity_handle,
// td = x - O // td = x - O
// t = (x - O) / d // t = (x - O) / d
Dqn_f32 const SENTINEL_T = 999.f;
Dqn_f32 earliest_t = SENTINEL_T; Dqn_f32 earliest_t = SENTINEL_T;
if (d.x != 0.f) { if (d.x != 0.f) {
Dqn_f32 left_t = (collider_left_wall_x - o.x) / d.x; Dqn_f32 left_t = (collider_left_wall_x - o.x) / d.x;
@ -201,16 +203,17 @@ static void FP_Game_MoveEntity(FP_Game *game, FP_GameEntityHandle entity_handle,
earliest_t = DQN_MIN(earliest_t, bottom_t); earliest_t = DQN_MIN(earliest_t, bottom_t);
} }
if (earliest_t != SENTINEL_T) { if (earliest_t < global_earliest_t) {
Dqn_V2 pos_just_before_collide = entity_pos + (d * earliest_t); global_earliest_t = earliest_t;
Dqn_V2 new_delta_p = pos_just_before_collide - entity_pos; global_earliest_pos_just_before_collide = entity_pos + (d * earliest_t);
entity->local_pos += new_delta_p;
has_collision = true;
} }
} }
if (!has_collision) { if (global_earliest_t == SENTINEL_T) {
entity->local_pos += delta_pos; entity->local_pos += delta_pos;
} else {
Dqn_V2 new_delta_pos = global_earliest_pos_just_before_collide - entity_pos;
entity->local_pos += new_delta_pos;
} }
} }
@ -357,8 +360,9 @@ void TELY_DLL_Init(void *user_data)
// NOTE: Mid lane mob spawner ================================================================== // NOTE: Mid lane mob spawner ==================================================================
Dqn_V2 base_mid_p = Dqn_V2_InitNx2(1580, 0.f); Dqn_V2 base_mid_p = Dqn_V2_InitNx2(1580, 0.f);
Dqn_V2 mid_lane_mob_spawner_pos = Dqn_V2_InitNx2(game->map->local_hit_box_size.w * -0.5f, 0.f); Dqn_V2 mid_lane_mob_spawner_pos = Dqn_V2_InitNx2(game->map->local_hit_box_size.w * -0.5f, 0.f);
Dqn_usize spawn_cap = 128;
{ {
FP_GameEntityHandle mob_spawner = FP_Entity_CreateMobSpawner(game, mid_lane_mob_spawner_pos, 128 /*spawn_cap*/, "Mob spawner"); FP_GameEntityHandle mob_spawner = FP_Entity_CreateMobSpawner(game, mid_lane_mob_spawner_pos, spawn_cap, "Mob spawner");
FP_Game_PushParentEntity(game, mob_spawner); FP_Game_PushParentEntity(game, mob_spawner);
FP_Entity_CreateWaypointF(game, Dqn_V2_InitNx2(-mid_lane_mob_spawner_pos.x + base_mid_p.x, base_mid_p.y), "Waypoint"); FP_Entity_CreateWaypointF(game, Dqn_V2_InitNx2(-mid_lane_mob_spawner_pos.x + base_mid_p.x, base_mid_p.y), "Waypoint");
FP_Game_PopParentEntity(game); FP_Game_PopParentEntity(game);
@ -368,7 +372,7 @@ void TELY_DLL_Init(void *user_data)
// NOTE: Bottom lane spawner =================================================================== // NOTE: Bottom lane spawner ===================================================================
Dqn_V2 bottom_lane_mob_spawner_pos = Dqn_V2_InitNx2(mid_lane_mob_spawner_pos.x, mid_lane_mob_spawner_pos.y + 932.f); Dqn_V2 bottom_lane_mob_spawner_pos = Dqn_V2_InitNx2(mid_lane_mob_spawner_pos.x, mid_lane_mob_spawner_pos.y + 932.f);
{ {
FP_GameEntityHandle mob_spawner = FP_Entity_CreateMobSpawner(game, bottom_lane_mob_spawner_pos, 128 /*spawn_cap*/, "Mob spawner"); FP_GameEntityHandle mob_spawner = FP_Entity_CreateMobSpawner(game, bottom_lane_mob_spawner_pos, spawn_cap, "Mob spawner");
FP_Game_PushParentEntity(game, mob_spawner); FP_Game_PushParentEntity(game, mob_spawner);
FP_Entity_CreateWaypointF(game, Dqn_V2_InitNx2(-bottom_lane_mob_spawner_pos.x + base_mid_p.x, 0.f), "Waypoint"); FP_Entity_CreateWaypointF(game, Dqn_V2_InitNx2(-bottom_lane_mob_spawner_pos.x + base_mid_p.x, 0.f), "Waypoint");
FP_Entity_CreateWaypointF(game, Dqn_V2_InitNx2(-bottom_lane_mob_spawner_pos.x + base_mid_p.x, -932.f), "Waypoint"); FP_Entity_CreateWaypointF(game, Dqn_V2_InitNx2(-bottom_lane_mob_spawner_pos.x + base_mid_p.x, -932.f), "Waypoint");
@ -378,7 +382,7 @@ void TELY_DLL_Init(void *user_data)
// NOTE: Top lane spawner =================================================================== // NOTE: Top lane spawner ===================================================================
Dqn_V2 top_lane_mob_spawner_pos = Dqn_V2_InitNx2(mid_lane_mob_spawner_pos.x, mid_lane_mob_spawner_pos.y - 915.f); Dqn_V2 top_lane_mob_spawner_pos = Dqn_V2_InitNx2(mid_lane_mob_spawner_pos.x, mid_lane_mob_spawner_pos.y - 915.f);
{ {
FP_GameEntityHandle mob_spawner = FP_Entity_CreateMobSpawner(game, top_lane_mob_spawner_pos, 128 /*spawn_cap*/, "Mob spawner"); FP_GameEntityHandle mob_spawner = FP_Entity_CreateMobSpawner(game, top_lane_mob_spawner_pos, spawn_cap, "Mob spawner");
FP_Game_PushParentEntity(game, mob_spawner); FP_Game_PushParentEntity(game, mob_spawner);
FP_Entity_CreateWaypointF(game, Dqn_V2_InitNx2(-top_lane_mob_spawner_pos.x + base_mid_p.x, 0.f), "Waypoint"); FP_Entity_CreateWaypointF(game, Dqn_V2_InitNx2(-top_lane_mob_spawner_pos.x + base_mid_p.x, 0.f), "Waypoint");
FP_Entity_CreateWaypointF(game, Dqn_V2_InitNx2(-top_lane_mob_spawner_pos.x + base_mid_p.x, +915.f), "Waypoint"); FP_Entity_CreateWaypointF(game, Dqn_V2_InitNx2(-top_lane_mob_spawner_pos.x + base_mid_p.x, +915.f), "Waypoint");
@ -397,7 +401,7 @@ void TELY_DLL_Init(void *user_data)
game->audio[FP_GameAudio_Smooch] = platform->func_load_audio(assets, DQN_STRING8("Smooch"), DQN_STRING8("Data/Audio/smooch.mp3")); game->audio[FP_GameAudio_Smooch] = platform->func_load_audio(assets, DQN_STRING8("Smooch"), DQN_STRING8("Data/Audio/smooch.mp3"));
} }
void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_PlatformInput *input, FP_GameEntity *entity, Dqn_V2 dir_vector) void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_PlatformInput *input, FP_GameEntity *entity, Dqn_V2 *acceleration_meters_per_s)
{ {
TELY_AssetSpriteSheet *sheet = &game->atlas_sprite_sheet; TELY_AssetSpriteSheet *sheet = &game->atlas_sprite_sheet;
FP_GameEntityAction *action = &entity->action; FP_GameEntityAction *action = &entity->action;
@ -427,7 +431,8 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
if (we_are_clicked_entity) { if (we_are_clicked_entity) {
if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_J) || if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_J) ||
TELY_Platform_InputGamepadButtonCodeIsPressed(input, 0, TELY_PlatformInputGamepadButtonCode_X)) { TELY_Platform_InputGamepadButtonCodeIsPressed(input, 0, TELY_PlatformInputGamepadButtonCode_X)) {
} else if (dir_vector.x || dir_vector.y) { FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Attack);
} else if (acceleration_meters_per_s->x || acceleration_meters_per_s->y) {
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Run); FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Run);
} }
} }
@ -487,34 +492,14 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
} break; } break;
case FP_EntityTerryState_Dash: { case FP_EntityTerryState_Dash: {
if (entering_new_state) { if (entering_new_state) {
TELY_AssetAnimatedSprite sprite = TELY_Asset_MakeAnimatedSprite(sheet, g_anim_names.terry_walk_right, TELY_AssetFlip_No); uint64_t duration_ms = 250;
uint64_t duration_ms = sprite.anim->count * sprite.anim->ms_per_frame; FP_Game_EntityActionReset(game, entity->handle, duration_ms, entity->action.sprite);
FP_Game_EntityActionReset(game, entity->handle, duration_ms, sprite); *acceleration_meters_per_s *= 35.f;
Dqn_V2 dash_dir = {};
switch (entity->direction) {
case FP_GameDirection_Up: dash_dir.y = -1.f; break;
case FP_GameDirection_Down: dash_dir.y = +1.f; break;
case FP_GameDirection_Left: dash_dir.x = -1.f; break;
case FP_GameDirection_Right: dash_dir.x = +1.f; break;
case FP_GameDirection_Count: DQN_INVALID_CODE_PATH; break;
} }
Dqn_V2 dash_acceleration = dash_dir * 400'000'000.f; if (action_has_finished)
Dqn_f32 t = DQN_CAST(Dqn_f32)DQN_SQUARED(PHYSICS_STEP);
entity->velocity = (dash_acceleration * t) + entity->velocity * 2.0f;
}
if (action_has_finished) {
if (entity_has_velocity) {
// TODO(doyle): Not sure if this branch triggers properly.
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Run); FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Run);
} else {
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Idle);
}
}
} break; } break;
} }
@ -583,7 +568,7 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_J) || if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_J) ||
TELY_Platform_InputGamepadButtonCodeIsPressed(input, 0, TELY_PlatformInputGamepadButtonCode_X)) { TELY_Platform_InputGamepadButtonCodeIsPressed(input, 0, TELY_PlatformInputGamepadButtonCode_X)) {
FP_Game_EntityTransitionState(game, entity, FP_EntitySmoochieState_Attack); FP_Game_EntityTransitionState(game, entity, FP_EntitySmoochieState_Attack);
} else if (dir_vector.x || dir_vector.y) { } else if (acceleration_meters_per_s->x || acceleration_meters_per_s->y) {
FP_Game_EntityTransitionState(game, entity, FP_EntitySmoochieState_Run); FP_Game_EntityTransitionState(game, entity, FP_EntitySmoochieState_Run);
} }
} }
@ -666,9 +651,8 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
FP_Game_EntityActionReset(game, entity->handle, duration_ms, sprite); FP_Game_EntityActionReset(game, entity->handle, duration_ms, sprite);
} }
if (action_has_finished) { if (action_has_finished)
FP_Game_DeleteEntity(game, entity->handle); FP_Game_DeleteEntity(game, entity->handle);
}
} break; } break;
@ -754,7 +738,7 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_J) || if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_J) ||
TELY_Platform_InputGamepadButtonCodeIsPressed(input, 0, TELY_PlatformInputGamepadButtonCode_X)) { TELY_Platform_InputGamepadButtonCodeIsPressed(input, 0, TELY_PlatformInputGamepadButtonCode_X)) {
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Attack); FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Attack);
} else if (dir_vector.x || dir_vector.y) { } else if (acceleration_meters_per_s->x || acceleration_meters_per_s->y) {
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Run); FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Run);
} }
} }
@ -793,9 +777,8 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
FP_Game_EntityActionReset(game, entity->handle, duration_ms, sprite); FP_Game_EntityActionReset(game, entity->handle, duration_ms, sprite);
} }
if (action_has_finished) { if (action_has_finished)
FP_Game_DeleteEntity(game, entity->handle); FP_Game_DeleteEntity(game, entity->handle);
}
} break; } break;
@ -1365,12 +1348,6 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
entity->local_pos += input->mouse_p_delta; entity->local_pos += input->mouse_p_delta;
} }
// NOTE: Core equations of motion ==========================================================
FP_Game_MoveEntity(game, entity->handle, acceleration_meters_per_s);
// NOTE: Tick the state machine
FP_EntityActionStateMachine(game, &platform->audio, input, entity, dir_vector);
if (game->clicked_entity == entity->handle) { if (game->clicked_entity == entity->handle) {
if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_F1)) { if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_F1)) {
entity->sprite_height.meters += 1; entity->sprite_height.meters += 1;
@ -1384,6 +1361,14 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
if (entity->flags & FP_GameEntityFlag_CameraTracking) if (entity->flags & FP_GameEntityFlag_CameraTracking)
game->camera.world_pos = FP_Game_CalcEntityWorldPos(game, entity->handle) - Dqn_V2_InitV2I(platform->core.window_size) * .5f; game->camera.world_pos = FP_Game_CalcEntityWorldPos(game, entity->handle) - Dqn_V2_InitV2I(platform->core.window_size) * .5f;
} }
// NOTE: Tick the state machine
// NOTE: This can delete the entity! Take caution
FP_GameEntityHandle entity_handle = entity->handle;
FP_EntityActionStateMachine(game, &platform->audio, input, entity, &acceleration_meters_per_s);
// NOTE: Core equations of motion ==========================================================
FP_Game_MoveEntity(game, entity_handle, acceleration_meters_per_s);
} }
// NOTE: Update entity ========================================================================= // NOTE: Update entity =========================================================================

View File

@ -159,11 +159,17 @@ static FP_GameEntityHandle FP_Entity_CreateMerchantTerry(FP_Game *game, Dqn_V2 p
entity->type = FP_EntityType_MerchantTerry; entity->type = FP_EntityType_MerchantTerry;
entity->local_pos = pos; entity->local_pos = pos;
entity->local_hit_box_size = Dqn_V2_InitNx2(50, 50);
entity->sprite_height.meters = 3.66f; entity->sprite_height.meters = 3.66f;
FP_Entity_AddDebugEditorFlags(game, result); FP_Entity_AddDebugEditorFlags(game, result);
entity->flags |= FP_GameEntityFlag_NonTraversable; entity->flags |= FP_GameEntityFlag_NonTraversable;
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, g_anim_names.merchant_graveyard);
Dqn_Rect sprite_rect = game->atlas_sprite_sheet.rects.data[sprite_anim->index];
Dqn_f32 size_scale = FP_Entity_CalcSpriteScaleForDesiredHeight(game, entity->sprite_height, sprite_rect);
Dqn_V2 sprite_rect_scaled = sprite_rect.size * size_scale;
entity->local_hit_box_offset = Dqn_V2_InitNx2(0, sprite_rect_scaled.h * .15f);
entity->local_hit_box_size = Dqn_V2_InitNx2(sprite_rect_scaled.w, sprite_rect_scaled.h - (sprite_rect_scaled.h * .4f));
return result; return result;
} }
@ -177,11 +183,18 @@ static FP_GameEntityHandle FP_Entity_CreateMerchantGraveyard(FP_Game *game, Dqn_
entity->type = FP_EntityType_MerchantGraveyard; entity->type = FP_EntityType_MerchantGraveyard;
entity->local_pos = pos; entity->local_pos = pos;
entity->local_hit_box_size = Dqn_V2_InitNx2(50, 50);
entity->sprite_height.meters = 3.66f; entity->sprite_height.meters = 3.66f;
FP_Entity_AddDebugEditorFlags(game, result); FP_Entity_AddDebugEditorFlags(game, result);
entity->flags |= FP_GameEntityFlag_NonTraversable; entity->flags |= FP_GameEntityFlag_NonTraversable;
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, g_anim_names.merchant_graveyard);
Dqn_Rect sprite_rect = game->atlas_sprite_sheet.rects.data[sprite_anim->index];
Dqn_f32 size_scale = FP_Entity_CalcSpriteScaleForDesiredHeight(game, entity->sprite_height, sprite_rect);
Dqn_V2 sprite_rect_scaled = sprite_rect.size * size_scale;
entity->local_hit_box_offset = Dqn_V2_InitNx2(0, sprite_rect_scaled.h * .1f);
entity->local_hit_box_size = Dqn_V2_InitNx2(sprite_rect_scaled.w - (sprite_rect_scaled.w * .3f), sprite_rect_scaled.h - (sprite_rect_scaled.h * .5f));
return result; return result;
} }
@ -195,11 +208,17 @@ static FP_GameEntityHandle FP_Entity_CreateMerchantGym(FP_Game *game, Dqn_V2 pos
entity->type = FP_EntityType_MerchantGym; entity->type = FP_EntityType_MerchantGym;
entity->local_pos = pos; entity->local_pos = pos;
entity->local_hit_box_size = Dqn_V2_InitNx2(50, 50);
entity->sprite_height.meters = 3.66f; entity->sprite_height.meters = 3.66f;
FP_Entity_AddDebugEditorFlags(game, result); FP_Entity_AddDebugEditorFlags(game, result);
entity->flags |= FP_GameEntityFlag_NonTraversable; entity->flags |= FP_GameEntityFlag_NonTraversable;
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, g_anim_names.merchant_gym);
Dqn_Rect sprite_rect = game->atlas_sprite_sheet.rects.data[sprite_anim->index];
Dqn_f32 size_scale = FP_Entity_CalcSpriteScaleForDesiredHeight(game, entity->sprite_height, sprite_rect);
Dqn_V2 sprite_rect_scaled = sprite_rect.size * size_scale;
entity->local_hit_box_offset = Dqn_V2_InitNx2(0, sprite_rect_scaled.h * .3f);
entity->local_hit_box_size = Dqn_V2_InitNx2(sprite_rect_scaled.w - (sprite_rect_scaled.w * .3f), sprite_rect_scaled.h - (sprite_rect_scaled.h * .6f));
return result; return result;
} }
@ -213,11 +232,17 @@ static FP_GameEntityHandle FP_Entity_CreateMerchantPhoneCompany(FP_Game *game, D
entity->type = FP_EntityType_MerchantPhoneCompany; entity->type = FP_EntityType_MerchantPhoneCompany;
entity->local_pos = pos; entity->local_pos = pos;
entity->local_hit_box_size = Dqn_V2_InitNx2(50, 50);
entity->sprite_height.meters = 3.66f; entity->sprite_height.meters = 3.66f;
FP_Entity_AddDebugEditorFlags(game, result); FP_Entity_AddDebugEditorFlags(game, result);
entity->flags |= FP_GameEntityFlag_NonTraversable; entity->flags |= FP_GameEntityFlag_NonTraversable;
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, g_anim_names.merchant_phone_company);
Dqn_Rect sprite_rect = game->atlas_sprite_sheet.rects.data[sprite_anim->index];
Dqn_f32 size_scale = FP_Entity_CalcSpriteScaleForDesiredHeight(game, entity->sprite_height, sprite_rect);
Dqn_V2 sprite_rect_scaled = sprite_rect.size * size_scale;
entity->local_hit_box_offset = Dqn_V2_InitNx2(0, sprite_rect_scaled.h * .15f);
entity->local_hit_box_size = Dqn_V2_InitNx2(sprite_rect_scaled.w - (sprite_rect_scaled.w * .3f), sprite_rect_scaled.h - (sprite_rect_scaled.h * .4f));
return result; return result;
} }
@ -232,16 +257,16 @@ static FP_GameEntityHandle FP_Entity_CreateClubTerry(FP_Game *game, Dqn_V2 pos,
entity->type = FP_EntityType_ClubTerry; entity->type = FP_EntityType_ClubTerry;
entity->local_pos = pos; entity->local_pos = pos;
entity->sprite_height.meters = 4.f; entity->sprite_height.meters = 4.f;
FP_Entity_AddDebugEditorFlags(game, result);
entity->flags |= FP_GameEntityFlag_NonTraversable;
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, g_anim_names.club_terry_alive); TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, g_anim_names.club_terry_alive);
Dqn_Rect sprite_rect = game->atlas_sprite_sheet.rects.data[sprite_anim->index]; Dqn_Rect sprite_rect = game->atlas_sprite_sheet.rects.data[sprite_anim->index];
Dqn_f32 size_scale = FP_Entity_CalcSpriteScaleForDesiredHeight(game, entity->sprite_height, sprite_rect); Dqn_f32 size_scale = FP_Entity_CalcSpriteScaleForDesiredHeight(game, entity->sprite_height, sprite_rect);
Dqn_V2 sprite_rect_scaled = sprite_rect.size * size_scale; Dqn_V2 sprite_rect_scaled = sprite_rect.size * size_scale;
entity->local_hit_box_offset = Dqn_V2_InitNx2(0, sprite_rect_scaled.h * .1f);
entity->local_hit_box_size = Dqn_V2_InitNx2(sprite_rect_scaled.w, sprite_rect_scaled.h - (sprite_rect_scaled.h * .4f)); entity->local_hit_box_size = Dqn_V2_InitNx2(sprite_rect_scaled.w, sprite_rect_scaled.h - (sprite_rect_scaled.h * .4f));
FP_Entity_AddDebugEditorFlags(game, result);
entity->flags |= FP_GameEntityFlag_NonTraversable;
return result; return result;
} }
@ -256,6 +281,8 @@ static FP_GameEntityHandle FP_Entity_CreateHeart(FP_Game *game, Dqn_V2 pos, DQN_
entity->type = FP_EntityType_Heart; entity->type = FP_EntityType_Heart;
entity->local_pos = pos; entity->local_pos = pos;
entity->sprite_height.meters = 4.f; entity->sprite_height.meters = 4.f;
FP_Entity_AddDebugEditorFlags(game, result);
entity->flags |= FP_GameEntityFlag_NonTraversable;
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, g_anim_names.heart); TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, g_anim_names.heart);
Dqn_Rect sprite_rect = game->atlas_sprite_sheet.rects.data[sprite_anim->index]; Dqn_Rect sprite_rect = game->atlas_sprite_sheet.rects.data[sprite_anim->index];
@ -264,8 +291,5 @@ static FP_GameEntityHandle FP_Entity_CreateHeart(FP_Game *game, Dqn_V2 pos, DQN_
entity->local_hit_box_offset = Dqn_V2_InitNx2(0, sprite_rect_scaled.h * .15f); entity->local_hit_box_offset = Dqn_V2_InitNx2(0, sprite_rect_scaled.h * .15f);
entity->local_hit_box_size = Dqn_V2_InitNx2(sprite_rect_scaled.w - (sprite_rect_scaled.w * .3f), sprite_rect_scaled.h - (sprite_rect_scaled.h * .4f)); entity->local_hit_box_size = Dqn_V2_InitNx2(sprite_rect_scaled.w - (sprite_rect_scaled.w * .3f), sprite_rect_scaled.h - (sprite_rect_scaled.h * .4f));
FP_Entity_AddDebugEditorFlags(game, result);
entity->flags |= FP_GameEntityFlag_NonTraversable;
return result; return result;
} }