fp: Use meters for calculations

This commit is contained in:
doyle 2023-09-26 00:07:39 +10:00
parent dcf47a106a
commit 7a2bebf3c3
6 changed files with 75 additions and 44 deletions

View File

@ -131,6 +131,8 @@ void TELY_DLL_Init(void *user_data)
TELY_Assets *assets = &platform->assets;
FP_Game *game = Dqn_Arena_New(&platform->arena, FP_Game, Dqn_ZeroMem_Yes);
game->chunk_pool = &platform->chunk_pool;
game->meters_to_pixels = 65.416f;
platform->user_data = game;
{
TELY_AssetSpriteSheet *sheet = &game->hero_sprite_sheet;
@ -235,13 +237,11 @@ void TELY_DLL_Init(void *user_data)
// NOTE: Mob spawner ===========================================================================
{
FP_GameEntityHandle mob_spawner = FP_Entity_CreateMobSpawner(game,
Dqn_V2_InitNx2(50.f, platform->core.window_size.y * .5f),
16 /*spawn_cap*/,
"Mob spawner");
Dqn_V2 mob_spawner_pos = FP_Game_MetersToPixelsNx2(game, 2.f, 5.f);
FP_GameEntityHandle mob_spawner = FP_Entity_CreateMobSpawner(game, mob_spawner_pos, 16 /*spawn_cap*/, "Mob spawner");
FP_Game_PushParentEntity(game, mob_spawner);
FP_Entity_CreateWaypointF(game, Dqn_V2_InitNx2(800.f, -200.f), "Waypoint");
FP_Entity_CreateWaypointF(game, Dqn_V2_InitNx2(932.f, 200.f), "Waypoint");
FP_Entity_CreateWaypointF(game, FP_Game_MetersToPixelsNx2(game, 2.f, 4.f), "Waypoint A");
FP_Entity_CreateWaypointF(game, FP_Game_MetersToPixelsNx2(game, 14.f, 8.f), "Waypoint B");
FP_Game_PopParentEntity(game);
}
@ -638,7 +638,7 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
entity->alive_time_s += PHYSICS_STEP;
// NOTE: Move entity by keyboard and gamepad ===============================================
Dqn_V2 acceleration = {};
Dqn_V2 acceleration_meters_per_s = {};
if (game->clicked_entity == entity->handle) {
if (entity->flags & (FP_GameEntityFlag_MoveByKeyboard | FP_GameEntityFlag_MoveByGamepad)) {
bool move_entity = false;
@ -658,7 +658,7 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
}
if (move_entity) {
acceleration = dir_vector * 10000000.f;
acceleration_meters_per_s = dir_vector * 8;
if (dir_vector.x)
entity->direction = dir_vector.x > 0.f ? FP_GameDirection_Right : FP_GameDirection_Left;
else if (dir_vector.y)
@ -668,7 +668,7 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
}
// NOTE: Determine AI movement =============================================================
if (acceleration.x == 0 && acceleration.y == 0) {
if (acceleration_meters_per_s.x == 0 && acceleration_meters_per_s.y == 0) {
Dqn_V2 entity_pos = FP_Game_CalcEntityWorldPos(game, entity->handle);
if (entity->flags & FP_GameEntityFlag_AggrosWhenNearTerry) {
@ -689,7 +689,7 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
}
}
if (closest_terry_dist < DQN_SQUARED(200.f)) {
if (closest_terry_dist < DQN_SQUARED(FP_Game_MetersToPixelsNx1(game, 5.f))) {
FP_SentinelListLink<FP_GameEntityHandle> *first_waypoint = FP_SentinelList_Front(&entity->waypoints);
if (first_waypoint->data != closest_terry->handle) {
FP_SentinelListLink<FP_GameEntityHandle> *link = FP_SentinelList_MakeBefore(&entity->waypoints, first_waypoint, game->chunk_pool);
@ -720,7 +720,7 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
// NOTE: We haven't arrived yet, calculate an acceleration vector to the waypoint
Dqn_V2 entity_to_waypoint_norm = Dqn_V2_Normalise(entity_to_waypoint);
acceleration = entity_to_waypoint_norm * 1'000'000.f;
acceleration_meters_per_s = entity_to_waypoint_norm * 4.f;
break;
}
}
@ -734,12 +734,9 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
Dqn_f32 t = DQN_CAST(Dqn_f32)DQN_SQUARED(PHYSICS_STEP);
Dqn_f32 t_squared = DQN_SQUARED(t);
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;
}
Dqn_f32 velocity_falloff_coefficient = 0.82f;
Dqn_f32 acceleration_feel_good_factor = 15'000.f;
Dqn_V2 acceleration = FP_Game_MetersToPixelsV2(game, acceleration_meters_per_s) * acceleration_feel_good_factor;
entity->velocity = (acceleration * t) + entity->velocity * velocity_falloff_coefficient;
// NOTE: Zero out velocity with epsilon
@ -749,7 +746,6 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
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;
@ -1006,8 +1002,11 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer)
} break;
}
Dqn_f32 sprite_in_meters = src_rect.size.y * FP_Game_PixelsToMeters(game);
Dqn_f32 size_scale = entity->sprite_height.meters / sprite_in_meters;
Dqn_Rect dest_rect = {};
dest_rect.size = src_rect.size * entity->size_scale;
dest_rect.size = src_rect.size * size_scale;
dest_rect.pos = world_pos - (dest_rect.size * .5f);
if (sprite.flip & TELY_AssetFlip_X)

View File

@ -3,12 +3,6 @@
#include "feely_pona_unity.h"
#endif
#define FP_SentinelDoublyLinkedList_Insert(list, item) \
item->next = list; \
item->prev = list->prev; \
item->next->prev = item; \
item->prev->next = item;
enum FP_ProfileZone
{
FP_ProfileZone_FPUpdate = TELY_ProfileZone_Count,
@ -22,3 +16,8 @@ enum FP_ProfileZone
FP_ProfileZone_FPRender,
};
struct FP_Meters
{
Dqn_f32 meters;
};

View File

@ -45,8 +45,8 @@ static FP_GameEntityHandle FP_Entity_CreateSmoochie(FP_Game *game, Dqn_V2 pos, D
entity->type = FP_EntityType_Smoochie;
entity->local_pos = pos;
entity->size_scale = Dqn_V2_InitNx1(.25f);
entity->local_hit_box_size = Dqn_V2_InitNx2(428, 471) * entity->size_scale;
entity->sprite_height.meters = 1.6f;
entity->local_hit_box_size = Dqn_V2_InitNx2(0.4f, 1.6f) * FP_Game_MetersToPixels(game);
FP_Entity_AddDebugEditorFlags(game, entity->handle);
entity->flags |= FP_GameEntityFlag_NonTraversable;
return result;
@ -107,8 +107,8 @@ static FP_GameEntityHandle FP_Entity_CreateTerry(FP_Game *game, Dqn_V2 pos, DQN_
entity->type = FP_EntityType_Terry;
entity->local_pos = pos;
entity->size_scale = Dqn_V2_InitNx1(0.25f);
entity->local_hit_box_size = Dqn_V2_InitNx2(428, 471) * entity->size_scale;
entity->sprite_height.meters = 1.8f;
entity->local_hit_box_size = Dqn_V2_InitNx2(0.5f, entity->sprite_height.meters) * FP_Game_MetersToPixels(game);
FP_Entity_AddDebugEditorFlags(game, result);
entity->flags |= FP_GameEntityFlag_NonTraversable;
return result;
@ -125,7 +125,7 @@ static FP_GameEntityHandle FP_Entity_CreateMerchant(FP_Game *game, Dqn_V2 pos, D
entity->type = FP_EntityType_Merchant;
entity->local_pos = pos;
entity->local_hit_box_size = Dqn_V2_InitNx2(50, 50);
entity->size_scale = Dqn_V2_InitNx1(0.25f);
entity->sprite_height.meters = 3.66f;
FP_Entity_AddDebugEditorFlags(game, result);
entity->flags |= FP_GameEntityFlag_NonTraversable;

View File

@ -3,6 +3,36 @@
#include "feely_pona_unity.h"
#endif
static Dqn_f32 FP_Game_PixelsToMeters(FP_Game const *game)
{
Dqn_f32 result = game ? (1.f / game->meters_to_pixels) : 10.f;
return result;
}
static Dqn_f32 FP_Game_MetersToPixels(FP_Game const *game)
{
Dqn_f32 result = game ? game->meters_to_pixels : 1 / 10.f;
return result;
}
static Dqn_V2 FP_Game_MetersToPixelsV2(FP_Game const *game, Dqn_V2 pos)
{
Dqn_V2 result = pos * FP_Game_MetersToPixels(game);
return result;
}
static Dqn_f32 FP_Game_MetersToPixelsNx1(FP_Game const *game, Dqn_f32 val)
{
Dqn_f32 result = val * FP_Game_MetersToPixels(game);
return result;
}
static Dqn_V2 FP_Game_MetersToPixelsNx2(FP_Game const *game, Dqn_f32 x, Dqn_f32 y)
{
Dqn_V2 result = Dqn_V2_InitNx2(x, y) * FP_Game_MetersToPixels(game);
return result;
}
static bool operator==(FP_GameEntityHandle const &lhs, FP_GameEntityHandle const &rhs)
{
bool result = lhs.id == rhs.id;
@ -203,7 +233,7 @@ static FP_GameEntity *FP_Game_MakeEntityPointerFV(FP_Game *game, DQN_FMT_STRING_
result->handle.id = (game->entities.size - 1) & FP_GAME_ENTITY_HANDLE_INDEX_MASK;
}
result->size_scale = Dqn_V2_InitNx1(1);
result->sprite_height.meters = 1;
result->parent = FP_Game_ActiveParentEntityPointer(game);
result->name = TELY_ChunkPool_AllocFmtFV(game->chunk_pool, fmt, args);

View File

@ -97,7 +97,9 @@ struct FP_GameEntity
Dqn_String8 name;
FP_GameEntityHandle handle;
Dqn_V2 size_scale;
// The target size to render the sprite in meters. The width of the sprite
// is scaled uniformly with respect to the height.
FP_Meters sprite_height;
FP_GameEntityAction action;
Dqn_V2 velocity;
@ -175,6 +177,7 @@ struct FP_Game
FP_GameCamera camera;
TELY_RFui rfui;
Dqn_f32 meters_to_pixels;
uint64_t clock_ms;
};

View File

@ -61,10 +61,10 @@ DQN_MSVC_WARNING_DISABLE(4505) // warning C4505: unreferenced function with inte
#include "External/tely/tely_rfui.cpp"
// NOTE: feely_pona ================================================================================
#include "feely_pona.h"
#include "feely_pona_stdlib.h"
#include "feely_pona_entity.h"
#include "feely_pona_game.h"
#include "feely_pona.h"
#include "feely_pona_game.cpp"
#include "feely_pona_entity.cpp"