This is an old revision of the document!
One of the requirements I have for my project is for my character to plant his feet firmly on the ground as he walks. Many games, especially platformers, will have a main sprite with many frames of animation, and will be repositioned across the screen as the character animates.
An interesting thing to notice with many games is that when a character plants his foot on the ground, it glides across without any friction. For most games, this is fine. But where a little more realism is required, some tricks are needed.
Orx has a complete physics system for moving objects around but this tutorial will require using an old school method to move the object.
This tutorial aims to show you how to:
1) Move an object sprite manually.
2) Move the object with a realistic walk motion.
3) Using an EventHandler to update movement in sync with frame changes.
4) Creating custom events in the config, and having the EventHandler use them.
You are best to be familiar with the Anim Tutorial before this one.
With a simple movement, for each frame change, the object is usually moved x pixels along. With this solution, a list of varying distance values is used. For each frame change, an event value is taken, and the character is moved that many pixels along.
That is the concept in a nutshell.
I have provided a set of animation frames for this tutorial here.
The graphic is 506 x 100 and each frame varies in width. Save to the data/anim folder.
[DroidAnimationSet] AnimationList = DroidWalkAnim#DroidIdleAnim LinkList = DroidIdle2Walk#DroidWalk2Idle#DroidIdleLoop#DroidWalkLoop [DroidIdle2Walk] Source = DroidIdleAnim Destination = DroidWalkAnim Property = immediate [DroidWalk2Idle] Source = DroidWalkAnim Destination = DroidIdleAnim Property = immediate Priority = 10 [DroidIdleLoop] Source = DroidIdleAnim Destination = DroidIdleAnim [DroidWalkLoop] Source = DroidWalkAnim Destination = DroidWalkAnim [DroidIdleAnim] KeyData1 = droid1 KeyDuration1 = 0.2 Property = immediate [DroidWalkAnim] DefaultKeyDuration = 0.2; KeyData1 = droid2 KeyData2 = droid3 KeyData3 = droid4 KeyData4 = droid5 KeyData5 = droid6 KeyData6 = droid7 KeyData7 = droid1 KeyEventName1 = AR1 KeyEventValue1 = 13 KeyEventName2 = AR1 KeyEventValue2 = 6 KeyEventName3 = AR1 KeyEventValue3 = 18 KeyEventName4 = AR1 KeyEventValue4 = 10 KeyEventName5 = AR1 KeyEventValue5 = 19 KeyEventName6 = AR1 KeyEventValue6 = 14 KeyEventName7 = AR1 KeyEventValue7 = 21
The [DroidWalkAnim] section contains the custom events which are very important. Each EventName is set the same as this is not important for this tutorial. But the KeyEventTime and KeyEventValue values are very important, and are defined in order to be in sync with the EventHandler.
And each KeyEventValue contains a pixel distance value used to move our character each step. These vary as you can see above: 13, 6, 18, 10, 19, 14 & 21 pixels.
[DroidObject] Graphic = droid1; This will do as a default. AnimationSet = DroidAnimationSet Position = (5, 130, 0) [DroidGraphic] Texture = ../data/anim/droid-animation.png Pivot = top right [droid1@DroidGraphic] TextureCorner = (0, 0, 0) TextureSize = (63, 100, 0) [droid2@DroidGraphic] TextureCorner = (63, 0, 0) TextureSize = (72, 100, 0) [droid3@DroidGraphic] TextureCorner = (135, 0, 0) TextureSize = (78, 100, 0) [droid4@DroidGraphic] TextureCorner = (213, 0, 0) TextureSize = (78, 100, 0) [droid5@DroidGraphic] TextureCorner = (291, 0, 0) TextureSize = (65, 100, 0) [droid6@DroidGraphic] TextureCorner = (356, 0, 0) TextureSize = (80, 100, 0) [droid7@DroidGraphic] TextureCorner = (436, 0, 0) TextureSize = (70, 100, 0)
You'll notice there is only right hand movement defined, just to keep the tutorial simple.
A few things to set up, first our little droid object:
orxOBJECT *droid = orxObject_CreateFromConfig("DroidObject"); orxObject_SetCurrentAnim(droid, orxNULL );
Next is to set up an EventHandler for custom animation events
orxEvent_AddHandler(orxEVENT_TYPE_ANIM, EventHandler);
And the handler:
orxSTATUS orxFASTCALL EventHandler(const orxEVENT *_pstEvent){ orxANIM_EVENT_PAYLOAD *pstPayload; pstPayload = (orxANIM_EVENT_PAYLOAD *)_pstEvent->pstPayload; switch(_pstEvent->eID){ case orxANIM_EVENT_CUSTOM_EVENT: { orxLOG("<%s>@<%s> was fired PIXELS %f ", pstPayload->zAnimName, orxObject_GetName(orxOBJECT(_pstEvent->hRecipient)), pstPayload->stCustom.fValue ); orxVECTOR droidVector; orxObject_GetPosition(droid, &droidVector); droidVector.fX = droidVector.fX + pstPayload->stCustom.fValue; orxObject_SetPosition(droid, &droidVector); break; } } return orxSTATUS_SUCCESS; }
In the event handler, the orxANIM_EVENT_CUSTOM_EVENT is fired because the KeyEvents having been defined in the config. The current position is added to by retrieving the active KeyEventValue (pstPayload→stCustom.fValue) from the config file.
Setting the proper animation with key on and key off is done with:
if(orxInput_IsActive("Right")){ orxObject_SetTargetAnim(droid, "DroidWalkAnim"); } else{ orxObject_SetTargetAnim(droid, orxNULL); }
When you run the program, the droid's feet should plant nice and firmly on the ground as it walks along.
Possible pitfalls:
1) Be careful to make all your Config EventTime(s) different. Two EventTime(s) the same will crash.