You can use a zero length frame in order to send a key frame event without any visual indication in the animation itself. Essentially a sequence trigger.
As in the Animation Walkthrough, we'll use the chicken sprite sheet again:
Create a standard orx project.
Start with some basic config to set up the chicken, the animation and the frames:
[Scene] ChildList = Chicken [Chicken] Graphic = @ Texture = chicken-animation-sheet.png TextureOrigin = (0, 0, 0) TextureSize = (108, 115, 0) Pivot = top left AnimationSet = ChickenAnimationSet [ChickenAnimationSet] Texture = chicken-animation-sheet.png FrameSize = (108, 115, 0) StartAnim = SitDownAnim KeyDuration = 2 ; frame every two seconds SitDownAnim = 0 ; five frames are specified, so need to keep this total up to date. [SitDownAnim1] TextureOrigin = (0, 0, 0) [SitDownAnim2] TextureOrigin = (108, 0, 0) KeyEvent = SITTING_FRAME_2 # 100 [SitDownAnim3] KeyDuration = 0 KeyEvent = SITTING_FRAME_3 # 900 [SitDownAnim4] TextureOrigin = (216, 0, 0) KeyEvent = SITTING_FRAME_4 # 230 [SitDownAnim5] TextureOrigin = (324, 0, 0)
We'll need an animation event handler so that we can print out the Key Event names and values.
At the bottom to the init()
:
orxEvent_AddHandler(orxEVENT_TYPE_ANIM, AnimationEventHandler);
And the AnimationEventHandler
function itself:
orxSTATUS orxFASTCALL AnimationEventHandler(const orxEVENT *_pstEvent){ orxANIM_EVENT_PAYLOAD *pstPayload; pstPayload = (orxANIM_EVENT_PAYLOAD *)_pstEvent->pstPayload; switch(_pstEvent->eID){ case orxANIM_EVENT_CUSTOM_EVENT: { orxLOG("<%s> / <%s> event was fired. Value: %f ", pstPayload->zAnimName, pstPayload->stCustom.zName, pstPayload->stCustom.fValue ); break; } } return orxSTATUS_SUCCESS; }
Compile and run, and we should have a basic chicken on the screen.
The chicken will start to slowly sit down. Frames change every two seconds due to the default KeyDuration
, which helps you see what's going on. Each frame will be 2 seconds unless we say otherwise in a specific frame.
The log should be something like:
[22:36:41] [LOG] <SitDownAnim> / <SITTING_FRAME_2> event was fired. Value: 100.000000 [22:36:45] [LOG] <SitDownAnim> / <SITTING_FRAME_3> event was fired. Value: 900.000000 [22:36:45] [LOG] <SitDownAnim> / <SITTING_FRAME_4> event was fired. Value: 230.000000
And the above repeats forever. You'll note the following interesting things:
There is no SITTING_FRAME_1. This is because frame 1 is defined as just a graphic change, there is no KeyEvent and KeyValue:
[SitDownAnim1] TextureOrigin = (0, 0, 0)
However we go to next frame straight away, within the same 'tick', and, as such, this 'ghost' frame doesn't require a proper graphic to exist.
Frames 2 fires and then 3, being the next frame, fires within the same 'tick' (due to the KeyDuration of 0). And this is the real point of this tutorial. Frame 2 changes the graphic texture and fires the SITTING_FRAME_2 KeyEvent name and value of 100.
[SitDownAnim2] TextureOrigin = (108, 0, 0) KeyEvent = SITTING_FRAME_2 # 100 [SitDownAnim3] KeyDuration = 0 KeyEvent = SITTING_FRAME_3 # 900
Frame 4 then shows for 2 seconds, SITTING_FRAME_4 fires with a value of 230.
[SitDownAnim4] TextureOrigin = (216, 0, 0) KeyEvent = SITTING_FRAME_4 # 230
Frame 5 will change graphic texture, but there is no event fired:
[SitDownAnim5] TextureOrigin = (324, 0, 0)
That's pretty much it. This is handy for firing an event on a certain frame and being able to trigger some game activity. Examples could be: