User Tools

Site Tools


tutorials:community:sausage:realistic_walk_movement

Realistic Walk Movement

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.

Prerequisite

You are best to be familiar with the Anim Tutorial before this one.

Simple Movement vs a Distance Array

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.

Define your Config File

[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]
TextureOrigin = (0, 0, 0)
TextureSize = (63, 100, 0)
 
[droid2@DroidGraphic]
TextureOrigin = (63, 0, 0)
TextureSize = (72, 100, 0)
 
[droid3@DroidGraphic]
TextureOrigin = (135, 0, 0)
TextureSize = (78, 100, 0)
 
[droid4@DroidGraphic]
TextureOrigin = (213, 0, 0)
TextureSize = (78, 100, 0)
 
[droid5@DroidGraphic]
TextureOrigin = (291, 0, 0)
TextureSize = (65, 100, 0)
 
[droid6@DroidGraphic]
TextureOrigin = (356, 0, 0)
TextureSize = (80, 100, 0)
 
[droid7@DroidGraphic]
TextureOrigin = (436, 0, 0)
TextureSize = (70, 100, 0)

You'll notice there is only right hand movement defined, just to keep the tutorial simple.

Setting Up

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.

tutorials/community/sausage/realistic_walk_movement.txt · Last modified: 2016/12/31 02:34 (3 months ago) by sausage