rework animation logic, don't loop increasingly as time goes on
This commit is contained in:
parent
76c609f8d5
commit
452e922e23
21
src/entity.c
21
src/entity.c
@ -1,24 +1,3 @@
|
|||||||
#include "entity.h"
|
#include "entity.h"
|
||||||
|
|
||||||
READONLY struct entity _g_entity_nil = { 0 };
|
READONLY struct entity _g_entity_nil = { 0 };
|
||||||
|
|
||||||
void entity_enable_prop(struct entity *entity, enum entity_prop prop)
|
|
||||||
{
|
|
||||||
u64 index = prop / 64;
|
|
||||||
u64 bit = prop % 64;
|
|
||||||
entity->props[index] |= ((u64)1 << bit);
|
|
||||||
}
|
|
||||||
|
|
||||||
void entity_disable_prop(struct entity *entity, enum entity_prop prop)
|
|
||||||
{
|
|
||||||
u64 index = prop / 64;
|
|
||||||
u64 bit = prop % 64;
|
|
||||||
entity->props[index] &= ~((u64)1 << bit);
|
|
||||||
}
|
|
||||||
|
|
||||||
b32 entity_has_prop(struct entity *entity, enum entity_prop prop)
|
|
||||||
{
|
|
||||||
u64 index = prop / 64;
|
|
||||||
u64 bit = prop % 64;
|
|
||||||
return !!(entity->props[index] & ((u64)1 << bit));
|
|
||||||
}
|
|
||||||
|
|||||||
30
src/entity.h
30
src/entity.h
@ -41,9 +41,8 @@ struct entity {
|
|||||||
struct entity_handle last;
|
struct entity_handle last;
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Translation, rotation, scale in relation to parent entity */
|
|
||||||
|
|
||||||
struct xform rel_xform;
|
struct xform rel_xform; /* Transform in relation to parent entity (or the world if entity has no parent) */
|
||||||
struct xform world_xform; /* Calculated post-physics */
|
struct xform world_xform; /* Calculated post-physics */
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
@ -68,8 +67,8 @@ struct entity {
|
|||||||
/* Animation */
|
/* Animation */
|
||||||
|
|
||||||
/* ENTITY_PROP_ANIMATING */
|
/* ENTITY_PROP_ANIMATING */
|
||||||
b32 animation_looping;
|
f64 animation_time_in_frame;
|
||||||
f64 animation_start_time; /* Calculated */
|
u64 animation_frame;
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Testing */
|
/* Testing */
|
||||||
@ -95,8 +94,25 @@ struct entity {
|
|||||||
extern READONLY struct entity _g_entity_nil;
|
extern READONLY struct entity _g_entity_nil;
|
||||||
INLINE READONLY struct entity *entity_nil(void) { return &_g_entity_nil; }
|
INLINE READONLY struct entity *entity_nil(void) { return &_g_entity_nil; }
|
||||||
|
|
||||||
void entity_enable_prop(struct entity *entity, enum entity_prop prop);
|
INLINE void entity_enable_prop(struct entity *entity, enum entity_prop prop)
|
||||||
void entity_disable_prop(struct entity *entity, enum entity_prop prop);
|
{
|
||||||
b32 entity_has_prop(struct entity *entity, enum entity_prop prop);
|
u64 index = prop / 64;
|
||||||
|
u64 bit = prop % 64;
|
||||||
|
entity->props[index] |= ((u64)1 << bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE void entity_disable_prop(struct entity *entity, enum entity_prop prop)
|
||||||
|
{
|
||||||
|
u64 index = prop / 64;
|
||||||
|
u64 bit = prop % 64;
|
||||||
|
entity->props[index] &= ~((u64)1 << bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE b32 entity_has_prop(struct entity *entity, enum entity_prop prop)
|
||||||
|
{
|
||||||
|
u64 index = prop / 64;
|
||||||
|
u64 bit = prop % 64;
|
||||||
|
return !!(entity->props[index] & ((u64)1 << bit));
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
44
src/game.c
44
src/game.c
@ -135,7 +135,6 @@ INTERNAL void game_update(void)
|
|||||||
e->player_acceleration = 15.0f;
|
e->player_acceleration = 15.0f;
|
||||||
|
|
||||||
entity_enable_prop(e, ENTITY_PROP_ANIMATING);
|
entity_enable_prop(e, ENTITY_PROP_ANIMATING);
|
||||||
e->animation_looping = true;
|
|
||||||
|
|
||||||
player_ent = e;
|
player_ent = e;
|
||||||
|
|
||||||
@ -144,8 +143,9 @@ INTERNAL void game_update(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Child ent */
|
/* Child ent */
|
||||||
{
|
for (u64 i = 0; i < 100; ++i) {
|
||||||
struct v2 pos = V2(0, 0.25);
|
//struct v2 pos = V2(0, 0.001);
|
||||||
|
struct v2 pos = V2(0, 0.25 * (i + 1));
|
||||||
struct v2 size = V2(1, 1);
|
struct v2 size = V2(1, 1);
|
||||||
f32 r = 0;
|
f32 r = 0;
|
||||||
|
|
||||||
@ -185,7 +185,6 @@ INTERNAL void game_update(void)
|
|||||||
//e->player_acceleration = 15.0f;
|
//e->player_acceleration = 15.0f;
|
||||||
|
|
||||||
entity_enable_prop(e, ENTITY_PROP_ANIMATING);
|
entity_enable_prop(e, ENTITY_PROP_ANIMATING);
|
||||||
e->animation_looping = true;
|
|
||||||
|
|
||||||
//entity_enable_prop(e, ENTITY_PROP_TEST);
|
//entity_enable_prop(e, ENTITY_PROP_TEST);
|
||||||
//entity_enable_prop(e, ENTITY_PROP_TEST_FOLLOW_MOUSE);
|
//entity_enable_prop(e, ENTITY_PROP_TEST_FOLLOW_MOUSE);
|
||||||
@ -271,41 +270,34 @@ INTERNAL void game_update(void)
|
|||||||
ent->test_start_sprite_xform = ent->sprite_xform;
|
ent->test_start_sprite_xform = ent->sprite_xform;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ENTITY_PROP_ANIMATING */
|
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_ANIMATING) && ent->animation_start_time == 0) {
|
|
||||||
ent->animation_start_time = L.world.time;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Update animation
|
* Update animation
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
if (ent->animation_start_time > 0) {
|
if (entity_has_prop(ent, ENTITY_PROP_ANIMATING)) {
|
||||||
/* Stop animation if past duration and not looping */
|
f64 time_in_frame = ent->animation_time_in_frame + L.world.dt;
|
||||||
if (!ent->animation_looping) {
|
u64 tag_frame_offset = ent->animation_frame;
|
||||||
f64 time_in_anim = L.world.time - ent->animation_start_time;
|
|
||||||
|
|
||||||
struct sheet *sheet = sheet_load(ent->sprite_name);
|
struct sheet *sheet = sheet_load(ent->sprite_name);
|
||||||
if (sheet) {
|
if (sheet) {
|
||||||
struct sheet_tag tag = sheet_get_tag(sheet, ent->sprite_tag_name);
|
struct sheet_tag tag = sheet_get_tag(sheet, ent->sprite_tag_name);
|
||||||
|
u64 frame_index = tag.start + tag_frame_offset;
|
||||||
|
|
||||||
struct sheet_frame frame = { 0 };
|
struct sheet_frame frame = sheet_get_frame(sheet, frame_index);
|
||||||
u64 frame_index = tag.start;
|
while (time_in_frame > frame.duration) {
|
||||||
while (time_in_anim > 0) {
|
time_in_frame -= frame.duration;
|
||||||
frame = sheet_get_frame(sheet, frame_index);
|
|
||||||
if (frame_index > tag.end) {
|
|
||||||
entity_disable_prop(ent, ENTITY_PROP_ANIMATING);
|
|
||||||
ent->animation_start_time = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
time_in_anim -= frame.duration;
|
|
||||||
++frame_index;
|
++frame_index;
|
||||||
|
if (frame_index > tag.end) {
|
||||||
|
/* Loop animation */
|
||||||
|
frame_index = tag.start;
|
||||||
}
|
}
|
||||||
} else {
|
frame = sheet_get_frame(sheet, frame_index);
|
||||||
entity_disable_prop(ent, ENTITY_PROP_ANIMATING);
|
|
||||||
ent->animation_start_time = 0;
|
|
||||||
}
|
}
|
||||||
|
tag_frame_offset = frame_index - tag.start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ent->animation_time_in_frame = time_in_frame;
|
||||||
|
ent->animation_frame = tag_frame_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
|
|||||||
19
src/user.c
19
src/user.c
@ -528,6 +528,7 @@ INTERNAL void user_update(void)
|
|||||||
e->player_acceleration = math_lerp_f32(e0->player_acceleration, e1->player_acceleration, tick_blend);
|
e->player_acceleration = math_lerp_f32(e0->player_acceleration, e1->player_acceleration, tick_blend);
|
||||||
|
|
||||||
e->sprite_xform = xform_lerp(e0->sprite_xform, e1->sprite_xform, tick_blend);
|
e->sprite_xform = xform_lerp(e0->sprite_xform, e1->sprite_xform, tick_blend);
|
||||||
|
e->animation_time_in_frame = math_lerp_f64(e0->animation_time_in_frame, e1->animation_time_in_frame, (f64)tick_blend);
|
||||||
|
|
||||||
e->camera_zoom = math_lerp_f32(e0->camera_zoom, e1->camera_zoom, tick_blend);
|
e->camera_zoom = math_lerp_f32(e0->camera_zoom, e1->camera_zoom, tick_blend);
|
||||||
}
|
}
|
||||||
@ -629,22 +630,18 @@ INTERNAL void user_update(void)
|
|||||||
if (sheet) {
|
if (sheet) {
|
||||||
struct sheet_tag tag = sheet_get_tag(sheet, ent->sprite_tag_name);
|
struct sheet_tag tag = sheet_get_tag(sheet, ent->sprite_tag_name);
|
||||||
|
|
||||||
struct sheet_frame frame = sheet_get_frame(sheet, tag.start);
|
u64 frame_index = tag.start + ent->animation_frame;
|
||||||
|
struct sheet_frame frame = sheet_get_frame(sheet, frame_index);
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_ANIMATING)) {
|
if (entity_has_prop(ent, ENTITY_PROP_ANIMATING)) {
|
||||||
b32 looping = ent->animation_looping;
|
f64 time_in_frame = ent->animation_time_in_frame;
|
||||||
f64 time_in_anim = L.world.time - ent->animation_start_time;
|
while (time_in_frame > frame.duration) {
|
||||||
|
time_in_frame -= frame.duration;
|
||||||
u64 frame_index = tag.start;
|
|
||||||
while (time_in_anim > 0) {
|
|
||||||
frame = sheet_get_frame(sheet, frame_index);
|
|
||||||
time_in_anim -= frame.duration;
|
|
||||||
++frame_index;
|
++frame_index;
|
||||||
if (frame_index > tag.end) {
|
if (frame_index > tag.end) {
|
||||||
|
/* Loop animation */
|
||||||
frame_index = tag.start;
|
frame_index = tag.start;
|
||||||
if (!looping) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
frame = sheet_get_frame(sheet, frame_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,13 +16,11 @@ struct world {
|
|||||||
u64 entities_count; /* Includes 'released' & inactive entities */
|
u64 entities_count; /* Includes 'released' & inactive entities */
|
||||||
struct entity_handle first_free_entity;
|
struct entity_handle first_free_entity;
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Everything after this field is not automatically coppied
|
/* Everything after this field is not dumb-MEMCPY'd by world_copy_replace */
|
||||||
* in world_copy_replace */
|
|
||||||
u8 _copy_barrier;
|
u8 _copy_barrier;
|
||||||
|
|
||||||
/* Arenas */
|
/* Entities array */
|
||||||
struct arena entities_arena;
|
struct arena entities_arena;
|
||||||
struct entity *entities;
|
struct entity *entities;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user