And, as always, we will use the previous code as a starting point:
FrameListener
for controlling the movement speed and saving our rotation:float _WalkingSpeed; float _rotation;
_WalkingSpeed = 50.0f; _rotation = 0.0f;
_aniState = _ent->getAnimationState("RunBase"); _aniState->setLoop(false); _aniStateTop = _ent->getAnimationState("RunTop"); _aniStateTop->setLoop(false);
frameStarted()
method, we need two new local variables, one to indicate if we have moved our model for this frame and a second one to store the direction in which we have moved our model.bool walked = false; Ogre::Vector3 SinbadTranslate(0,0,0);
frameStarted()
method, we add some new code to control the movement of our model. We will use the arrow keys for movement. When a key is pressed, we need to change the translation variable to save the direction in which we want to move the model and we need to set the rotation variable to rotate the model in such a way that it looks in the direction it moves:if(_key->isKeyDown(OIS::KC_UP)) { SinbadTranslate += Ogre::Vector3(0,0,-1); _rotation = 3.14f; walked = true; }
if(_key->isKeyDown(OIS::KC_DOWN)) { SinbadTranslate += Ogre::Vector3(0,0,1); _rotation = 0.0f; walked = true; } if(_key->isKeyDown(OIS::KC_LEFT)) { SinbadTranslate += Ogre::Vector3(-1,0,0); _rotation = -1.57f; walked = true; } if(_key->isKeyDown(OIS::KC_RIGHT)) { SinbadTranslate += Ogre::Vector3(1,0,0); _rotation = 1.57f; walked = true; }
if(walked) { _aniState->setEnabled(true); _aniStateTop->setEnabled(true); if(_aniState->hasEnded()) { _aniState->setTimePosition(0.0f); } if(_aniStateTop->hasEnded()) { _aniStateTop->setTimePosition(0.0f); } }
else { _aniState->setTimePosition(0.0f); _aniState->setEnabled(false); _aniStateTop->setTimePosition(0.0f); _aniStateTop->setEnabled(false); }
_node->translate(SinbadTranslate * evt.timeSinceLastFrame * _WalkingSpeed); _node->resetOrientation(); _node->yaw(Ogre::Radian(_rotation));
We created our first application with user input and animations combined. This could be called the first real interactive application we created up until now. In steps 1 and 2, we created and inited some variables we needed later. In step 3, we changed how we handle our animations; previously, we always enabled an animation directly and let it loop. Now we don't want to enable it directly because we want the animation only to be played when our model moves, everything else just looks stupid. For the same reason, we disabled looping of animations. We only want to react to user input so that there is no need for animation looping. If needed, we will start the animation ourselves.
Most of the changes we did were inside the frameStarted()
method. In step 4, we created a couple of local variables we needed later, namely, a Boolean value that was used as an indicator if the model moves this frame and the other was a vector representing the movement direction. Steps 5 and 6 queried the key state of the arrow keys. When a key is down, we change the direction vector and the rotation accordingly and set the flag for movement to true
. We used this flag in step 7, if the flag is true
, meaning our model moves this frame, we enabled the animation and checked if the animations had reached their end. If the animations have reached their end, we reset them to their starting position so that they can be played again. Because we don't want animations to be played when the model isn't moving, we set them to their starting position and disable them in step 8. In step 9, we applied the translation. Then we reset the orientation, and after this, applied the new rotation. This is necessary because yaw
adds the rotation to the already done rotations, which in our case would be wrong because we have absolute rotation, and we need absolute and not relative rotations. Therefore, we reset the orientation first and then apply our rotation to the now zeroed rotation.
3.135.206.254