From f95cb8ec9b6f657be5fff5c1eabe9b215aacb92c Mon Sep 17 00:00:00 2001 From: doyle Date: Sun, 24 Sep 2023 16:24:51 +1000 Subject: [PATCH] tely: Wire up the sprite up/down/left/right anims --- feely_pona.cpp | 57 +++++++++++++++++++++++++++++++++++++---------- feely_pona_game.h | 10 ++++++++- 2 files changed, 54 insertions(+), 13 deletions(-) diff --git a/feely_pona.cpp b/feely_pona.cpp index feff855..193e94a 100644 --- a/feely_pona.cpp +++ b/feely_pona.cpp @@ -595,7 +595,7 @@ void TELY_DLL_Init(void *user_data) entity->flags |= FP_GameEntityFlag_MoveByMouse; entity->flags |= FP_GameEntityFlag_MoveByGamepad; entity->flags |= FP_GameEntityFlag_NonTraversable; - entity->facing_left = true; + entity->direction = FP_GameDirection_Left; game->clicked_entity = entity->handle; game->player = entity->handle; } @@ -731,7 +731,9 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_Renderer *renderer, if (entity->flags & (FP_GameEntityFlag_MoveByKeyboard || FP_GameEntityFlag_MoveByGamepad)) { acceleration = dir_vector * 10000000.f; if (dir_vector.x) - entity->facing_left = dir_vector.x < 0.f; + entity->direction = dir_vector.x > 0.f ? FP_GameDirection_Right : FP_GameDirection_Left; + else if (dir_vector.y) + entity->direction = dir_vector.y > 0.f ? FP_GameDirection_Down : FP_GameDirection_Up; } } @@ -795,19 +797,33 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_Renderer *renderer, #endif // NOTE: Core equations of motion ========================================================== + bool has_collision = false; { // f"(t) = a // f'(t) = at + v // f (t) = 0.5f*a(t^2) + vt + p Dqn_f32 t = DQN_CAST(Dqn_f32)DQN_SQUARED(input->delta_s); Dqn_f32 t_squared = DQN_SQUARED(t); - entity->velocity = (acceleration * t) + entity->velocity * 0.82f; + + Dqn_f32 velocity_falloff_coefficient = 0.25f; + if (entity->handle == game->clicked_entity) { + if (dir_vector.x || dir_vector.y) + velocity_falloff_coefficient = 0.82f; + } + + entity->velocity = (acceleration * t) + entity->velocity * velocity_falloff_coefficient; + + // NOTE: Zero out velocity with epsilon + if (DQN_ABS(entity->velocity.x) < 5.f) + entity->velocity.x = 0.f; + if (DQN_ABS(entity->velocity.y) < 5.f) + entity->velocity.y = 0.f; + 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_V2 entity_pos = Dqn_Rect_Center(entity_world_hit_box); Dqn_V2 entity_new_pos = entity_pos + delta_pos; - bool has_collision = false; for (FP_GameEntityIterator collider_it = {}; FP_Game_DFSPostOrderWalkEntityTree(game, &collider_it, game->root_entity); ) { FP_GameEntity *collider = collider_it.entity; @@ -975,11 +991,14 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_Renderer *renderer, } if (action->state == FP_GameEntityState_Run) { - action_to_anim_mapping = FP_Game_GetActionAnimMappingForType(game, entity->handle, FP_ActionType_WalkRight); + switch (entity->direction) { + case FP_GameDirection_Up: action_to_anim_mapping = FP_Game_GetActionAnimMappingForType(game, entity->handle, FP_ActionType_WalkUp); break; + case FP_GameDirection_Down: action_to_anim_mapping = FP_Game_GetActionAnimMappingForType(game, entity->handle, FP_ActionType_WalkDown); break; + case FP_GameDirection_Left: action_to_anim_mapping = FP_Game_GetActionAnimMappingForType(game, entity->handle, FP_ActionType_WalkLeft); break; + case FP_GameDirection_Right: action_to_anim_mapping = FP_Game_GetActionAnimMappingForType(game, entity->handle, FP_ActionType_WalkRight); break; + } - if (action->flags & FP_GameEntityActionFlag_StateTransition) { - FP_Game_EntityActionReset(action, FP_GAME_ENTITY_ACTION_INFINITE_TIMER, action_to_anim_mapping); - } else if (we_are_clicked_entity) { + if (we_are_clicked_entity) { if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_J) || TELY_Platform_InputGamepadButtonCodeIsPressed(input, 0, TELY_PlatformInputGamepadButtonCode_X)) { FP_Game_EntityActionSetState(action, FP_GameEntityState_AttackA); @@ -989,7 +1008,12 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_Renderer *renderer, } } - if ((action_has_finished && !entity_has_velocity) || (we_are_clicked_entity && dir_vector.x == 0.f && dir_vector.y == 0.f)) { + // NOTE: Also handles state transition + if (action->mapping.action_type != action_to_anim_mapping.action_type) { + FP_Game_EntityActionReset(action, FP_GAME_ENTITY_ACTION_INFINITE_TIMER, action_to_anim_mapping); + } + + if (!entity_has_velocity && !has_collision) { FP_Game_EntityActionSetState(action, FP_GameEntityState_Idle); } } @@ -1000,7 +1024,14 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_Renderer *renderer, if (action->flags & FP_GameEntityActionFlag_StateTransition) { FP_Game_EntityActionReset(action, action_to_anim_mapping.anim.count * action_to_anim_mapping.anim.seconds_per_frame, action_to_anim_mapping); - Dqn_V2 dash_dir = {entity->facing_left ? -1.f : 1.f, 0.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; + } + Dqn_V2 dash_acceleration = dash_dir * 400'000'000.f; Dqn_f32 t = DQN_CAST(Dqn_f32)DQN_SQUARED(input->delta_s); entity->velocity = (dash_acceleration * t) + entity->velocity * 2.0f; @@ -1026,7 +1057,7 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_Renderer *renderer, entity->attack_box_size = entity->local_hit_box_size; // NOTE: Position the attack box - if (entity->facing_left) { + if (entity->direction == FP_GameDirection_Left) { entity->attack_box_offset = Dqn_V2_InitNx2(entity->local_hit_box_offset.x - entity->attack_box_size.w, entity->local_hit_box_offset.y); } else { @@ -1173,8 +1204,10 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer) dest_rect.size = src_rect.size * entity->size_scale; dest_rect.pos = world_pos - (dest_rect.size * .5f); - if (entity->facing_left) + #if 0 + if (entity->direction == FP_GameDirection_Left) dest_rect.size.w *= -1.f; // NOTE: Flip the texture horizontally + #endif TELY_Render_TextureColourV4(renderer, sprite_sheet->tex_handle, src_rect, dest_rect, TELY_COLOUR_WHITE_V4); } diff --git a/feely_pona_game.h b/feely_pona_game.h index 28a23ec..c1b27f4 100644 --- a/feely_pona_game.h +++ b/feely_pona_game.h @@ -97,6 +97,14 @@ struct FP_GameEntityAction Dqn_f32 end_at_s; }; +enum FP_GameDirection +{ + FP_GameDirection_Up, + FP_GameDirection_Down, + FP_GameDirection_Left, + FP_GameDirection_Right, +}; + struct FP_GameEntity { FP_GameEntity *next; @@ -128,7 +136,7 @@ struct FP_GameEntity uint64_t spawn_cap; uint64_t flags; - bool facing_left; + FP_GameDirection direction; Dqn_V2 local_pos; Dqn_f64 alive_time_s; Dqn_FArray shapes;