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"
|
||||
|
||||
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;
|
||||
|
||||
/* ====================================================================== */
|
||||
/* 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 */
|
||||
|
||||
/* ====================================================================== */
|
||||
@ -68,8 +67,8 @@ struct entity {
|
||||
/* Animation */
|
||||
|
||||
/* ENTITY_PROP_ANIMATING */
|
||||
b32 animation_looping;
|
||||
f64 animation_start_time; /* Calculated */
|
||||
f64 animation_time_in_frame;
|
||||
u64 animation_frame;
|
||||
|
||||
/* ====================================================================== */
|
||||
/* Testing */
|
||||
@ -95,8 +94,25 @@ struct entity {
|
||||
extern READONLY struct entity _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);
|
||||
void entity_disable_prop(struct entity *entity, enum entity_prop prop);
|
||||
b32 entity_has_prop(struct entity *entity, enum entity_prop prop);
|
||||
INLINE 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);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
52
src/game.c
52
src/game.c
@ -135,7 +135,6 @@ INTERNAL void game_update(void)
|
||||
e->player_acceleration = 15.0f;
|
||||
|
||||
entity_enable_prop(e, ENTITY_PROP_ANIMATING);
|
||||
e->animation_looping = true;
|
||||
|
||||
player_ent = e;
|
||||
|
||||
@ -144,8 +143,9 @@ INTERNAL void game_update(void)
|
||||
}
|
||||
|
||||
/* Child ent */
|
||||
{
|
||||
struct v2 pos = V2(0, 0.25);
|
||||
for (u64 i = 0; i < 100; ++i) {
|
||||
//struct v2 pos = V2(0, 0.001);
|
||||
struct v2 pos = V2(0, 0.25 * (i + 1));
|
||||
struct v2 size = V2(1, 1);
|
||||
f32 r = 0;
|
||||
|
||||
@ -185,7 +185,6 @@ INTERNAL void game_update(void)
|
||||
//e->player_acceleration = 15.0f;
|
||||
|
||||
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_FOLLOW_MOUSE);
|
||||
@ -271,41 +270,34 @@ INTERNAL void game_update(void)
|
||||
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
|
||||
* ========================== */
|
||||
|
||||
if (ent->animation_start_time > 0) {
|
||||
/* Stop animation if past duration and not looping */
|
||||
if (!ent->animation_looping) {
|
||||
f64 time_in_anim = L.world.time - ent->animation_start_time;
|
||||
if (entity_has_prop(ent, ENTITY_PROP_ANIMATING)) {
|
||||
f64 time_in_frame = ent->animation_time_in_frame + L.world.dt;
|
||||
u64 tag_frame_offset = ent->animation_frame;
|
||||
|
||||
struct sheet *sheet = sheet_load(ent->sprite_name);
|
||||
if (sheet) {
|
||||
struct sheet_tag tag = sheet_get_tag(sheet, ent->sprite_tag_name);
|
||||
struct sheet *sheet = sheet_load(ent->sprite_name);
|
||||
if (sheet) {
|
||||
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 };
|
||||
u64 frame_index = tag.start;
|
||||
while (time_in_anim > 0) {
|
||||
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;
|
||||
struct sheet_frame frame = sheet_get_frame(sheet, frame_index);
|
||||
while (time_in_frame > frame.duration) {
|
||||
time_in_frame -= frame.duration;
|
||||
++frame_index;
|
||||
if (frame_index > tag.end) {
|
||||
/* Loop animation */
|
||||
frame_index = tag.start;
|
||||
}
|
||||
} else {
|
||||
entity_disable_prop(ent, ENTITY_PROP_ANIMATING);
|
||||
ent->animation_start_time = 0;
|
||||
frame = sheet_get_frame(sheet, frame_index);
|
||||
}
|
||||
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->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);
|
||||
}
|
||||
@ -629,22 +630,18 @@ INTERNAL void user_update(void)
|
||||
if (sheet) {
|
||||
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)) {
|
||||
b32 looping = ent->animation_looping;
|
||||
f64 time_in_anim = L.world.time - ent->animation_start_time;
|
||||
|
||||
u64 frame_index = tag.start;
|
||||
while (time_in_anim > 0) {
|
||||
frame = sheet_get_frame(sheet, frame_index);
|
||||
time_in_anim -= frame.duration;
|
||||
f64 time_in_frame = ent->animation_time_in_frame;
|
||||
while (time_in_frame > frame.duration) {
|
||||
time_in_frame -= frame.duration;
|
||||
++frame_index;
|
||||
if (frame_index > tag.end) {
|
||||
/* Loop animation */
|
||||
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 */
|
||||
struct entity_handle first_free_entity;
|
||||
|
||||
|
||||
/* ====================================================================== */
|
||||
/* Everything after this field is not automatically coppied
|
||||
* in world_copy_replace */
|
||||
/* Everything after this field is not dumb-MEMCPY'd by world_copy_replace */
|
||||
u8 _copy_barrier;
|
||||
|
||||
/* Arenas */
|
||||
/* Entities array */
|
||||
struct arena entities_arena;
|
||||
struct entity *entities;
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user