I'm having an issue I can't seem to solve on the DATLib side of things.
I'm wondering If anyone can help me sort it out?
To set the stage lets say you have two near identical running animations.
(Animations can be any number of frames...The important part is both animations have the exact same number of frames and are near identical)
Animation 1 (Standard Run)
Animation 2 (Shoot while Running)
In both cases the leg animations are identical but the upper body changes to fire a weapon if the users presses the shoot button.
I have coded a near seamless frame swap
1. Lets say you player is on run frame 4 and the user presses the fire button.
2. The animation changes to frame 4 of the shoot animation at that exact moment the player presses the shoot button.
This works pretty well. The functions being used to achieve this could be:
aSpriteSetAnimStep, or aSpriteSetAnimStep2
EX: aSpriteSetAnimStep (&playerE->gfx[0]->sprite, playerE->anim.A_RUN_RECOIL, playerE->gfx[0]->sprite.stepNum);
Side Note: I believe both functions work in this case.
The difference is the first function will ignore a request to call the animation that is currently running but in our case that doesn't matter as we are calling an entirely different animation.
Anyway here is the issue:
Assuming your frames have the standard 5 frame duration. EX: The frame is held for 5 frames then the next animation frame is displayed
If the Frame 4 was on it's 4th hold frame this means it is just about to transition to frame 5 but then the users presses the fire button at that moment and the timing gets messed up at that point.
The user see's a seamless transition to a near identical frame however the timing is reset. So instead of frame 4 being held for 5 frames it is held for like 9 frames.
4 (Old frame held for 4 frames at the time of user input) + 5 (New Frame is programmed to hold for 5 frames) = 9 frames user see's that frame for too long...
Another Example: Frame 4 is typically held for 5 frames....
1. Frame 4 is on it's 4th hold frame at the time of user intervention.
2. New near identical frame 4 is loaded however the 'duration' is reset to 0
Now we have the 4 initial frames we saw frame 4 for plus we have to wait 5 identical frames.
3. The fluidity of the animation is lost as the user realizes one of the run frame is held for slightly longer then it should be.
In this case a frame that should appear for 5 frames appears for 9.
The Animator tool in DATLib does allow the user to stipulate duration to get the perfect timing on your animations.
The only mention of the duration is found here:
typedef struct animStep {
sprFrame *frame; Pointer to frame info
short shiftX; Frame X displacement from origin
short shiftY; Frame Y displacement from origin
ushort duration; Number of frame to display
} animStep;
The struct breakdown is accompanied with this note in the documentation:
spriteInfo, animStep and sprFrame structures are generated by the buildchar and animator tools.
Holds infos about animated sprite frames and animations.
Which tells me the animations must be reading from this information when loading frames and animations.
I hope what I have written makes sense. I don't want the timing to reset when a new animation is called. I want the previous frame timing to be carried over to the new animation frame.
This function does not exist as I am just adding a new parameter here but this pretty much sums it up. Does anyone know if this is possible?
EX: aSpriteSetAnimStep (&Sprite, NewAnimationID, sprite.stepNum, sprite.doNotResetDuration);