How to call update function from a subclass sprite

I trying to make a subclass of a sprite like this:
Ember.h

#ifndef __EMBER_H__
#define __EMBER_H__

#include "cocos2d.h"

class Ember : public cocos2d::Layer
{

    
public:
     Ember();
     cocos2d::Vec2 position;
     cocos2d::Vec2 velocity;
     cocos2d::Sprite* ember;
     cocos2d::Sprite*  make();
    
    //Update para la el motor fisico!
     virtual void update(float dt);
     
    // implement the "static create()" method manually
    CREATE_FUNC(Ember);
};

#endif // __EMBER_H__

Ember.cpp

#include "Ember.h"

USING_NS_CC;

Ember::Ember() {

    velocity = ccp(0.0f, 0.0f);
    ember = Sprite::create("player2.png");
    ember->setPosition(200.0f, 200.0f);
}
cocos2d::Sprite*  Ember::make() {

    return ember;
}

void Ember::update(float dt) {

    Vec2 gravity = Vec2(0.0f, -300.0f);
    Vec2 GravityStep = ccpMult(gravity,dt);
    
    velocity =  ccpAdd(velocity, GravityStep);
    Vec2 StepVelocity = ccpMult(velocity, dt);

    position =  ccpAdd(position, StepVelocity);
    ember->setPosition(position);
    CCLOG("Entro: %f",position.y);
    
    
    
}

Then im trying to call that Update function in may main scene, but i dont know how to do it… this is what i got so far (almost nothing):

#include "HelloWorldScene.h"
#include "cocostudio/CocoStudio.h"
#include "ui/CocosGUI.h"
#include "Ember.h"
USING_NS_CC;

using namespace cocostudio::timeline;

Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::create();
    
    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    
    
    //////////////////////////////
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }
    
    Ember ember;
    addChild(ember.make());

    
    scheduleUpdate();
    return true;
}

void HelloWorld::update(float dt) {
        
    
    
}

im using cocos2dx 3.10

In HelloWorld::update, add this

ember.update(dt); // you should pass the dt from update method

But why you don’t use the create method

Like

auto e = Ember::create();

Plus make sure update method is public in ember class

Happy coding

1 Like

This is an interesting style of doing it.

Take a look at our Programmers Guide samples: GitHub - chukong/programmers-guide-samples: Programmers Guide Samples

Let me check that and thanks for the help :smiley:

How i can call that function in the hellowworl update function… do i need to declare ember globally?

Of course bro you need it globally

Please don’t make it global :smiley:

  • Your ember class creates a Sprite in it’s constructor but does not retain it. This means that if you didn’t addChild it would destruct and Ember::Sprite would become invalid.
  • make() does not make anything… this is a very misleading function.

Instead consider deriving your ember class from cocos2d::Sprite, and use scheduleUpdate() in it’s onEnter() override and unscheduleUpdate() in it’s onExit() override.

I quickly wrote this up as an example, haven’t tested if it’ll run, but it demonstrates the principals.

Ember.h

#pragma once
#include "cocos2d.h"

class Ember : public cocos2d::Sprite
{
public:
    //declare destructor as virtual so we can derive from Ember safely
    virtual ~Ember();
    
    //A static create method that builds an auto released instance of Ember
    //Auto released objects will destruct at the end of the current frame
    static Ember create(const std::string& _fileName);

    //synthesize variable using cocos2d-x macro
    //this creates the variable and get/set functions for us
    CC_SYNTHESIZE(cocos2d::Vec2, m_velocity, Velocity);

    virtual void onEnter() override;
    virtual void onExit() override;
    virtual void update(float dt) override;
    
protected:
    //make constructor protected to stop it being constructed directly
    Ember();

    //initialisation function that allows construction to fail via create()
    bool init(const std::string& _fileName);
};

Ember.cpp

#include "Ember.h"

USING_NS_CC;

Ember::Ember() 
: velocity(0,0)
{
}

Ember::~Ember()
{
    //nothing to cleanup
}

Ember* Ember::create(const std::string& _fileName)
{
    auto instance = new Ember();
    if(instance && instance->init(_fileName))
    {
        instance->autorelease();
        return instance;
    }
    CC_SAFE_DELETE(instance);
    return nullptr;
}

bool Ember::init(const std::string& _fileName)
{
    //call sprite's initialisation method
    if(Sprite::initWithFile(_fileName) == false)
    {
        return false;
    }
    return true;
}

void Ember::onEnter()
{
    Sprite::onEnter(); //call base class onEnter()
    scheduleUpdate();
}

void Ember::onExit()
{
    Sprite::onExit(); //call base class onExit()
    unscheduleUpdate();
}

void Ember::update(float dt) {

    Vec2 gravity = Vec2(0.0f, -300.0f);
    Vec2 GravityStep = ccpMult(gravity,dt);

    m_velocity =  ccpAdd(m_velocity, GravityStep);
    Vec2 StepVelocity = ccpMult(m_velocity, dt);

    this->setPosition(ccpAdd(position, StepVelocity));
    CCLOG("Entro: %f",this->getPosition().y);
}

HelloWorld.cpp

#include "HelloWorldScene.h"
#include "Ember.h"

USING_NS_CC;

Scene* HelloWorld::createScene()
{
    auto scene = Scene::create();
    auto layer = HelloWorld::create();
    scene->addChild(layer);
    return scene;
}

bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }

    Ember* ember = Ember::create("player2.png");
    ember->setPosition(200.0f, 200.0f);
    addChild(ember);
    return true;
}
1 Like

I used that code, just fix a couple of errors but it worked perfect, i dont know how to thank you…
i will learn more about that code and more about C++, once again thanks for the help!

My pleasure :slight_smile: and good luck!