How to execute stored animation with EventKeyboard

I am fairly new to Cocos2d-x v3 and Recently I was attempting to use the listener key press functionality in order to get my Sprite to move with the animations I have created for it. All the code Compiles with no error, but when the game runs if I press the specified Key in the switch case the window is suspend and it brings me to the action.h header file and highlights the “void setTarget” method of the class where it states error “this was a nullptr” perhaps I forgot to initialize a variable somewhere?

My header looks like so:

  #ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"
using namespace cocos2d;

class HelloWorld : public cocos2d::Layer
{
private:
Sprite* sarah;
Animate* walking;
Action* action;

public:

 static cocos2d::Scene* createScene();


 virtual bool init();
 void menuCloseCallback(cocos2d::Ref* pSender);

 CREATE_FUNC(HelloWorld);

  void onKeyPressed(EventKeyboard::KeyCode keyCode, Event *eventer);
 void onKeyReleased(EventKeyboard::KeyCode keyCode, Event *eventer);
   Sprite* GetSprite();
     Animate* GetAnimation();
}

   #endif // __HELLOWORLD_SCENE_H__

and the part in my cpp that is causing me problems looks like so:

  void HelloWorld::onKeyPressed(EventKeyboard::KeyCode keyCode, Event * event){

   auto action1 = event->getCurrentTarget()->getActionByTag(1);
  auto node = event->getCurrentTarget();
  switch (keyCode){


  case EventKeyboard::KeyCode::KEY_LEFT_ARROW:
 action1->setTarget(node);
 node->runAction(action1);

default:
break;
}
  }

 void HelloWorld::onKeyReleased(EventKeyboard::KeyCode keyCode,Event *event) {
  auto action1 = event->getCurrentTarget()->getActionByTag(1);
  auto node = event->getCurrentTarget();
 Vec2 loc = event->getCurrentTarget()->getPosition();

 switch (keyCode){
case EventKeyboard::KeyCode::KEY_UP_ARROW:
action1->getTarget()->stopActionByTag(1);
node->setPosition(--loc.x, --loc.y);
default:
   break;
 }
}

sarah = Sprite::create("standing.png");
sarah->setAnchorPoint(Vec2(0, 0));
sarah->setPosition(100, 100);



 Vector<SpriteFrame*> walkingframeskleft;
 walkingframeskleft.reserve(3);
 walkingframeskleft.pushBack(SpriteFrame::create("walk2.png", Rect(0, 0, 65, 81)));
 walkingframeskleft.pushBack(SpriteFrame::create("walk3.png", Rect(0, 0, 65, 81)));
 walkingframeskleft.pushBack(SpriteFrame::create("walk4.png", Rect(0, 0, 65, 81)));

Animation* walkinganimation = Animation::createWithSpriteFrames(walkingframeskleft, .1f);
 walking = Animate::create(walkinganimation);
action = RepeatForever::create(walking);
action->setTag(1);
this->addChild(sarah);


auto listener = EventListenerKeyboard::create();
listener->onKeyPressed = CC_CALLBACK_2(HelloWorld::onKeyPressed,this);
listener->onKeyReleased = CC_CALLBACK_2(HelloWorld::onKeyReleased,this);
this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, sarah);


 return true;
}

in my switch cases i only have the left arrow set up since i just wanted to test if a key would work to begin with. I also had a plist for my animations but I removed it because I thought that might have been causing my issues but i suppose it was not

I haven’t analyzed your code in details, but you need to know few things.

  1. If you want to create an animation and use it later you have to retain it, because otherwise it’d be reelased from memory. You also have to remember to release it manually after you no longer need it (for example leaving a scene).

  2. If you want to use the same animation for multiple nodes, you have to remember to always call clone, otherwise it won’t work.

  3. You can also create a helper function, which creates your animation in place, so you won’t worry about 1) and 2).

  4. Another technique is to embeed your animation in speed action (with tag or hold reference in .h file) and then change speed (0 to pause and 1 to resume). Then you should run this animation for all nodes.

1 Like