fp: Use meters for calculations
This commit is contained in:
parent
dcf47a106a
commit
7a2bebf3c3
@ -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,13 +734,10 @@ 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;
|
||||
}
|
||||
|
||||
entity->velocity = (acceleration * t) + entity->velocity * velocity_falloff_coefficient;
|
||||
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
|
||||
if (DQN_ABS(entity->velocity.x) < 5.f)
|
||||
@ -748,8 +745,7 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
|
||||
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_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)
|
||||
|
11
feely_pona.h
11
feely_pona.h
@ -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;
|
||||
};
|
||||
|
||||
|
@ -43,10 +43,10 @@ static FP_GameEntityHandle FP_Entity_CreateSmoochie(FP_Game *game, Dqn_V2 pos, D
|
||||
FP_GameEntityHandle result = entity->handle;
|
||||
va_end(args);
|
||||
|
||||
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->type = FP_EntityType_Smoochie;
|
||||
entity->local_pos = pos;
|
||||
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;
|
||||
@ -105,10 +105,10 @@ static FP_GameEntityHandle FP_Entity_CreateTerry(FP_Game *game, Dqn_V2 pos, DQN_
|
||||
FP_GameEntityHandle result = entity->handle;
|
||||
va_end(args);
|
||||
|
||||
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->type = FP_EntityType_Terry;
|
||||
entity->local_pos = pos;
|
||||
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;
|
||||
@ -122,10 +122,10 @@ static FP_GameEntityHandle FP_Entity_CreateMerchant(FP_Game *game, Dqn_V2 pos, D
|
||||
FP_GameEntityHandle result = entity->handle;
|
||||
va_end(args);
|
||||
|
||||
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->type = FP_EntityType_Merchant;
|
||||
entity->local_pos = pos;
|
||||
entity->local_hit_box_size = Dqn_V2_InitNx2(50, 50);
|
||||
entity->sprite_height.meters = 3.66f;
|
||||
FP_Entity_AddDebugEditorFlags(game, result);
|
||||
entity->flags |= FP_GameEntityFlag_NonTraversable;
|
||||
|
||||
|
@ -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,9 +233,9 @@ 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->parent = FP_Game_ActiveParentEntityPointer(game);
|
||||
result->name = TELY_ChunkPool_AllocFmtFV(game->chunk_pool, fmt, args);
|
||||
result->sprite_height.meters = 1;
|
||||
result->parent = FP_Game_ActiveParentEntityPointer(game);
|
||||
result->name = TELY_ChunkPool_AllocFmtFV(game->chunk_pool, fmt, args);
|
||||
|
||||
// NOTE: Attach entity as a child to the parent
|
||||
FP_GameEntity *parent = result->parent;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user