fix animation transition issue for hit enemies
Transitioning to the `next` animation frame preserved the priority, which was a problem for enemies with a next: Hit=Idle or similar transition, as that would give an infinite Idle loop with high priority. This change forces a clear of the animation priority when such a transition occurs. This relies on the flawed linked list system, which means that it will not happen if the new animation is just after the current one in the source file. This is a fundamental issue due to mixing all frames as single pointers in the anim_t structure. This will be fixed in engine code eventually.
This commit is contained in:
parent
d6221db818
commit
e2ba1f51c2
|
@ -16,10 +16,10 @@ bat_right.aseprite:
|
|||
|
||||
gunslinger_left.aseprite:
|
||||
center: 15, 22
|
||||
next: Idle=Idle, Walking=Walking, Hit=Idle, Fire=Reloading
|
||||
next: Idle=Idle, Walking=Walking, Hit=Idle
|
||||
gunslinger_right.aseprite:
|
||||
center: 8, 22
|
||||
next: Idle=Idle, Walking=Walking, Hit=Idle, Fire=Reloading
|
||||
next: Idle=Idle, Walking=Walking, Hit=Idle
|
||||
|
||||
*.txt:
|
||||
custom-type: aseprite-anim-variation
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,15 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.8" tiledversion="1.8.4" orientation="orthogonal" renderorder="right-down" width="24" height="11" tilewidth="16" tileheight="16" infinite="0" nextlayerid="3" nextobjectid="1">
|
||||
<map version="1.9" tiledversion="1.9.2" orientation="orthogonal" renderorder="right-down" width="24" height="11" tilewidth="16" tileheight="16" infinite="0" nextlayerid="3" nextobjectid="1">
|
||||
<tileset firstgid="1" source="../tilesets/cavern.tsx"/>
|
||||
<layer id="1" name="Ground" width="24" height="11">
|
||||
<data encoding="csv">
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
2,2,2,2,2,7,15,8,7,8,7,16,8,7,15,7,7,16,8,2,2,2,2,2,
|
||||
2,2,2,2,2,4,4,14,14,6,3,3,3,3,6,4,4,14,4,2,2,2,2,2,
|
||||
2,2,2,2,2,14,14,5,3,3,3,5,5,3,3,3,5,4,4,2,2,2,2,2,
|
||||
2,2,2,2,2,3,5,3,3,3,4,5,5,4,3,3,3,5,3,2,2,2,2,2,
|
||||
2,2,2,2,2,5,3,3,6,5,5,6,6,5,5,6,3,3,5,2,2,2,2,2,
|
||||
2,2,2,2,2,3,5,3,3,3,4,5,5,4,3,3,3,5,3,2,2,2,2,2,
|
||||
2,2,2,2,2,14,14,5,3,3,3,2,2,3,3,3,5,4,4,2,2,2,2,2,
|
||||
2,2,2,2,2,3,5,3,3,3,2,2,2,2,3,3,3,5,3,2,2,2,2,2,
|
||||
2,2,2,2,2,5,3,3,6,5,7,2,2,7,5,6,3,3,5,2,2,2,2,2,
|
||||
2,2,2,2,2,3,5,3,3,3,4,7,23,4,3,3,3,5,3,2,2,2,2,2,
|
||||
2,2,2,2,2,14,4,5,3,3,3,5,5,3,3,3,5,4,14,2,2,2,2,2,
|
||||
2,2,2,2,2,4,14,4,4,6,3,3,3,3,6,14,14,4,4,2,2,2,2,2,
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
|
|
11
src/anim.c
11
src/anim.c
|
@ -138,14 +138,19 @@ void anim_frame_subrender(int x, int y, anim_frame_t const *frame, int left,
|
|||
frame->x + left, frame->y + top, width, height, DIMAGE_NONE);
|
||||
}
|
||||
|
||||
void anim_state_update(anim_state_t *state, fixed_t dt)
|
||||
bool anim_state_update(anim_state_t *state, fixed_t dt)
|
||||
{
|
||||
if(!state->frame) return;
|
||||
if(!state->frame) return false;
|
||||
|
||||
state->elapsed += fround(dt * 1000);
|
||||
if(state->elapsed < state->frame->duration) return;
|
||||
if(state->elapsed < state->frame->duration) return false;
|
||||
|
||||
// TODO: FIXME: This is incorrect if the next animation is just behind
|
||||
bool transitioning = (state->frame->next != state->frame + 1);
|
||||
|
||||
/* Switch to next frame */
|
||||
state->elapsed -= state->frame->duration;
|
||||
state->frame = state->frame->next;
|
||||
|
||||
return transitioning;
|
||||
}
|
||||
|
|
11
src/anim.h
11
src/anim.h
|
@ -61,8 +61,9 @@ void anim_frame_render(int x, int y, anim_frame_t const *frame);
|
|||
void anim_frame_subrender(int x, int y, anim_frame_t const *frame, int left,
|
||||
int top, int width, int height);
|
||||
|
||||
/* Update an animation to next frame. */
|
||||
void anim_state_update(anim_state_t *state, fixed_t dt);
|
||||
/* Update an animation to next frame. Returns true if the update transitioned
|
||||
to another animation. */
|
||||
bool anim_state_update(anim_state_t *state, fixed_t dt);
|
||||
|
||||
/* List of animations. */
|
||||
|
||||
|
@ -87,9 +88,9 @@ extern anim_t anims_skill_bullet;
|
|||
ANIM_E1(MACRO, bat, Idle, Hit, Death) \
|
||||
ANIM_E1(MACRO, albinos_bat, Idle, Hit, Death) \
|
||||
ANIM_E1(MACRO, crimson_bat, Idle, Hit, Death) \
|
||||
ANIM_E1(MACRO, gunslinger, Idle, Walking, Reloading, Fire, Hit, Death) \
|
||||
ANIM_E1(MACRO, gb_gunslinger, Idle, Walking, Reloading, Fire, Hit, Death) \
|
||||
ANIM_E1(MACRO, master_gunslinger, Idle, Walking,Reloading,Fire,Hit,Death) \
|
||||
ANIM_E1(MACRO, gunslinger, Idle, Walking, Fire, Hit, Death) \
|
||||
ANIM_E1(MACRO, gb_gunslinger, Idle, Walking, Fire, Hit, Death) \
|
||||
ANIM_E1(MACRO, master_gunslinger, Idle, Walking, Fire,Hit,Death) \
|
||||
ANIM_E1(MACRO, tifucile, Idle, Walking, Hit, Death) \
|
||||
ANIM_E1(MACRO, washing_machine, Idle, Walking, Attack, Hit, Death)
|
||||
|
||||
|
|
|
@ -38,7 +38,8 @@ void visible_update(entity_t *e, fixed_t dt)
|
|||
if(v->anim.frame == NULL)
|
||||
return;
|
||||
|
||||
anim_state_update(&v->anim, dt);
|
||||
if(anim_state_update(&v->anim, dt))
|
||||
v->anim_priority = 0;
|
||||
|
||||
if(v->anim.frame == NULL)
|
||||
v->anim_priority = 0;
|
||||
|
|
|
@ -504,7 +504,7 @@ void render_arcade(int x, int y, int halign, int value, int color_style)
|
|||
|
||||
/* Auto style based on the number of digits */
|
||||
if(color_style < 0)
|
||||
color_style = (value >= 10) + (value >= 100);
|
||||
color_style = (value >= 10) + (value >= 30);
|
||||
|
||||
char str[16];
|
||||
sprintf(str, "%d", value);
|
||||
|
|
Loading…
Reference in New Issue