How to update(dt) from classes other than Scene?

Hello,
I have a standard update method in main Scene;
this->scheduleUpdate();
void update(float dt);
and etc.

But I want to make a new one update(float dt) method, in some Sprite classes.
Until now I can’t do it.
For example

Car *Car::createCar( GameScene *scene)
{
Car *sprite;
sprite = new Car();

if ( sprite ) {
    sprite->retain();
    sprite->setScene( scene );
    sprite->init();
    
    return sprite;
}

CC_SAFE_DELETE( sprite );
return sprite = nullptr;

}

bool Car::init()
{

 this->scheduleUpdate();

}

void Car::update( float dt )
{
do something;
}

Can any guidelines? Thanks!

What is the issue you have there? As long as Car inherits from Node it should work from a brief look at the code you provided.

Make sure you call super init. Maybe that is what is missing.
ie: in your init()… call a Sprite::init()… I would have set that up a little differently but make sure super inits are done.

Hi. You need to inherit your car class from Node (or Sprite) and override update method in Car.h.

Here is a quick, generic, working example I threw together for a Sprite subclass with a scheduled update:

.hpp :

class SomeSpriteSubclass : public cocos2d::Sprite {
public:
    SomeSpriteSubclass();
    ~SomeSpriteSubclass();
    
    static SomeSpriteSubclass* create(const std::string& filename);
    void setup();
    
    void update(float dt);
};

.cpp :

SomeSpriteSubclass::SomeSpriteSubclass() {}
SomeSpriteSubclass::~SomeSpriteSubclass() {}

SomeSpriteSubclass* SomeSpriteSubclass::create(const std::string& filename) {
    SomeSpriteSubclass* sprite = new SomeSpriteSubclass();
    if (sprite->initWithFile(filename)) {
        sprite->autorelease();
        sprite->setup();
        sprite->scheduleUpdate();
        return sprite;
    }
    CC_SAFE_DELETE(sprite);
    return NULL;
}

void SomeSpriteSubclass::setup() {
    ///any additional setup for the class
}

void SomeSpriteSubclass::update(float dt) {
    //voila
}
1 Like

Also… as an added tip… If your timing doesn’t HAVE to be 100% frame rate, it is recommended to run it at the maximum acceptable time.

Ex:
this->schedule(schedule_selector(SomeSpriteSubclass::update), 0.1f);
This will run the update at 10 times per second.

Sometimes skipping a few frames is unnoticeable depending on your required update logic and can make a difference in overall optimization of the application.

In this way, your custom node can even break up update logic at different intervals…
Ex:

void update(float dt);
void updatePerSecond(float dt);
this->scheduleUpdate();
this->schedule(schedule_selector(SomeSpriteSubclass::updatePerSecond), 1.0f);

An example would be a custom label that displays the current elapsed time in seconds. It does not have to update at 60fps, it could update on a different scheduled time. Doing that in scheduleUpdate() would make 60x unnecessary executions at 60fps.

2 Likes

He did not work with me.
Car.h
public:
void update(float dt) override;

You mean that, do not you?

Hello,
I’ve tried a lot of things, the only thing that works is:
Director::getInstance()->getScheduler()->schedule(schedule_selector(Car::update), this, 1.0f, false);

I have no idea why this:
this->schedule( schedule_selector( Car::update ), 1.0f );
is not work.

What is diff between them??

Are you sure your Car class is correctly inheriting from a cocos Node and being initialized via cocos initializations. Try and Copy/Paste the example class I provided above, you can rename it Car

Don’t use that method of scheduling the update.

If you want your cocos2d::Node subclass to call update, then you simply need to call scheduleUpdate() at some point, like from init().

Also, if you want to create scheduler callbacks, don’t use the deprecated methods, so for example:

this->schedule( schedule_selector( Car::FunctionName), 1.0f );

should have been

this->schedule(std::bind(&Car::FunctionName, this, std::placeholders::_1), 1.0f, "UniqueIDForThis");

2 Likes

@MadJi both @tdebock and @R101 have good advice here. Plus cpp-tests uses this all over.

1 Like

I have successfully solved the problem.
The problem with me was that I missed adding the main subject to the scene, for example
scene-> addChild (sprite);
But from your answers, I definitely learned new things about update methods.
Thank you all.

1 Like

awesome, yea, dont forget all cocos node inherit from Ref class with auto release management. If you do not add it to a parent node, it will be cleaned up immediately (unless you retain it, but not recommended unless you want to manage memory on top)

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.