Acces to class object inside CallFunc

Hello guys, I have some problems animating a sprite using CallFunc. I will try to reduce my code to focus the problem:

I have a class that contains the sprite nebula I want to animate:

class BackgroundManager{
 public:
  BackgroundManager(Scene* scene);
 ~BackgroundManager();

  Sprite* nebula;
  Scene* scene;

};

In the Constructor, the sprite is created and added to the scene, and then do some animations:

BackgroundManager::BackgroundManager(Scene* scene) {

	scene_=scene;

	nebula =Sprite::createWithSpriteFrameName("nebula.png");

	nebula->setPositionX(SCREEN_SIZE.width);
	nebula->setPositionY( SCREEN_SIZE.height/2);

	scene_->addChild(nebula,E_LAYER_BACKGROUND);

	CallFunc* resetPosition= CallFunc::create([this](){
		this->nebula->setPositionX(SCREEN_SIZE.width);
		this->nebula->setPositionY( SCREEN_SIZE.height/2);
	});
	Sequence* seq = Sequence::create(
		MoveBy::create(0.5,Vec2(-SCREEN_SIZE.width,0)),
		resetPosition,
		DelayTime::create(0.5),
		nullptr);

	nebula->runAction(RepeatForever::create(seq));


}

The CallFunc function resetPosition can’t acces to the nebula sprite, (not event log the position) and the app crash when the sequence reach this function.

Conversely, if the sprite isn’t a member of the class BackgroundManager, and is created inside the Constructor:

Sprite* nebula = Sprite::createWithSpriteFrameName(“nebula.png”);

modifying the Callback properly to include this guy:

CallFunc* resetPosition= CallFunc::create([this, nebula](){
	nebula->setPositionX(SCREEN_SIZE.width);
	nebula->setPositionY( SCREEN_SIZE.height/2);
});

all goes alright.

The problem is that if I want to do some other stuff with the sprite, I need to include it as an object in the class, so the last solution is not what I’m looking for.

Can you help me finding a way to pass the sprite inside the callFunc, being the sprite a class object? Am I doing wrong the pass of [this] in the CallBack to refer an instance of the class itself?

Thanks!

I dont see you using retain() or anything.

1 Like

thanks for reply :grinning:
retaining the Sprite and/or the CallFunc continues crashing the app when the sequence reach the CallFunc.
By the way, isn’t
scene_->addChild(nebula,E_LAYER_BACKGROUND);
increase the retain count of the Sprite and avoid PoolManager deleting it?

Ok, I don’t retain the class itself, in the sense that I was calling it (in some scene) by :
BackgroundManager(this);
And so, there was no memory allocated in the heap to save anything inside the class. Doing:
BackgroundManager* bm= new BackgroundManager(this);
Solve the problem.

Thanks for you help :slight_smile: !

FYI: you could also use CallFuncN. It passes in the Node* where the action is running.

Your solution works just fine, and is basically a close equivalent slightly less expressive version.

CallFuncN::create([](Node* nebula) {
    // cast to (Sprite*) or other if you need to call derived members.
    nebula->setPositionX(SCREEN_SIZE.width);
    nebula->setPositionY(SCREEN_SIZE.height/2);
});
2 Likes