cocos2dx : schedule 计时,调用崩溃

本文介绍了在使用cocos2dx时遇到的schedule计时调用导致程序崩溃的问题。问题源于在错误的对象上下文中调用了schedule函数。解决方案包括从包含成员的正确类中启动schedule,或者使用scheduler的scheduleSelector方法手动设置this指针。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个问题还不知道怎么用标题来说明


问题如下:

有一个Scene如下:

class FirstScene : public cocos2d::CCLayer
{
public:
    virtual bool init();  
    static cocos2d::CCScene* scene();
    CREATE_FUNC(FirstScene);

    void start(float f);
    CCNode *anim;
};
里面有一个start函数,是一个定时器回调。有一个节点,比如是一个动画什么的。start函数如下:

void start(float f)
{
    anim->doSomething();
}

现在我要做的事情,是要让这个节点anim过段时间之后,执行start函数。有时候惯性思维(以前用wiengine),就直接这么写了

anim->schedule(SEL_SCHEDULE(start));
然后一运行,就崩了,崩的还很诡异,说anim是空指针


原因如下:

schedule函数,在ccnode里面的定义

void CCNode::schedule(SEL_SCHEDULE selector)
{
    this->schedule(selector, 0.0f, kCCRepeatForever, 0.0f);
}
然后会调用到

void CCNode::schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay)
{
    CCAssert( selector, "Argument must be non-nil");
    CCAssert( interval >=0, "Argument must be positive");

    m_pScheduler->scheduleSelector(selector, this, interval , repeat, delay, !m_bRunning);
}
发现问题没有,请注意第一个参数和第二个参数。第一个参数就是执行的函数指针。第二个参数,他直接把自己(this)作为m_pScheduler的参数丢进去了。最后在触发回调之后,他的调用就会成为

(m_pTarget->*m_pfnSelector)(m_fElapsed);
这里的m_pTarget就成了this,由于我们之前是用anim启动schedule,所以这个this就成了anim。那么在anim对象里面去找一个叫anim的变量,就找不到了。

解决办法:
1、从包含你要操作的成员的类启动schedule。

  2、如果这个类没有schedule函数,或者说她不是node的子类,用scheduler的scheduleSelector启动,因为这个可以手动设置this指针,把this设置成第一点说的。

检查VScocos2dx4.0代码问题,并修改错误 #include "Thorn.h" #include "HelloWorldScene.h" // StaticThorn StaticThorn* StaticThorn::create(const cocos2d::Size& size, const cocos2d::Vec2& position) { StaticThorn* thorn = new (std::nothrow) StaticThorn(); if (thorn && thorn->initWithFile("Thorn.png")) { thorn->autorelease(); thorn->setPosition(position); thorn->setContentSize(size); thorn->setupPhysics(); return thorn; } CC_SAFE_DELETE(thorn); return nullptr; } void StaticThorn::setupPhysics() { damageBody = cocos2d::PhysicsBody::createBox(this->getContentSize(), cocos2d::PhysicsMaterial(0.0f, 0.0f, 1.0f)); damageBody->setDynamic(false); damageBody->setCategoryBitmask(0x08); damageBody->setCollisionBitmask(0x01); damageBody->setContactTestBitmask(0x01); damageBody->setTag(THORN_DAMAGE_TAG); this->setPhysicsBody(damageBody); triggerBody = cocos2d::PhysicsBody::createBox(this->getContentSize(), cocos2d::PhysicsMaterial(0.0f, 0.0f, 1.0f)); triggerBody->setDynamic(false); triggerBody->setCategoryBitmask(0x10); triggerBody->setCollisionBitmask(0x01); triggerBody->setContactTestBitmask(0x01); triggerBody->setTag(THORN_TRIGGER_TAG); this->addChild(cocos2d::Node::create()); this->getChildByTag(0)->setPhysicsBody(triggerBody); } void StaticThorn::onTrigger() { // Do nothing for static thorn } // MovingThorn MovingThorn* MovingThorn::create(const cocos2d::Size& size, const cocos2d::Vec2& position) { MovingThorn* thorn = new (std::nothrow) MovingThorn(); if (thorn && thorn->initWithFile("Thorn.png")) { thorn->autorelease(); thorn->setPosition(position); thorn->setContentSize(size); thorn->setupPhysics(); return thorn; } CC_SAFE_DELETE(thorn); return nullptr; } void MovingThorn::setupPhysics() { Thorn::setupPhysics(); } void MovingThorn::onTrigger() { auto moveAction = cocos2d::MoveBy::create(1.0f, cocos2d::Vec2(0, 100)); auto removeAction = cocos2d::RemoveSelf::create(); auto sequence = cocos2d::Sequence::create(moveAction, removeAction, nullptr); this->runAction(sequence); } // InvisibleThorn InvisibleThorn* InvisibleThorn::create(const cocos2d::Size& size, const cocos2d::Vec2& position) { InvisibleThorn* thorn = new (std::nothrow) InvisibleThorn(); if (thorn && thorn->initWithFile("Thorn.png")) { thorn->autorelease(); thorn->setPosition(position); thorn->setContentSize(size); thorn->setOpacity(0); thorn->setupPhysics(); return thorn; } CC_SAFE_DELETE(thorn); return nullptr; } void InvisibleThorn::setupPhysics() { Thorn::setupPhysics(); } void InvisibleThorn::onTrigger() { auto fadeIn = cocos2d::FadeIn::create(0.5f); auto moveAction = cocos2d::MoveBy::create(1.0f, cocos2d::Vec2(0, 100)); auto removeAction = cocos2d::RemoveSelf::create(); auto sequence = cocos2d::Sequence::create(fadeIn, moveAction, removeAction, nullptr); this->runAction(sequence); } // StretchingThorn StretchingThorn* StretchingThorn::create(const cocos2d::Size& size, const cocos2d::Vec2& position, float stretchLength) { StretchingThorn* thorn = new (std::nothrow) StretchingThorn(); if (thorn && thorn->initWithFile("Thorn.png")) { thorn->autorelease(); thorn->setPosition(position); thorn->setContentSize(size); thorn->stretchLength = stretchLength; thorn->setupPhysics(); return thorn; } CC_SAFE_DELETE(thorn); return nullptr; } void StretchingThorn::setupPhysics() { Thorn::setupPhysics(); } void StretchingThorn::onTrigger() { auto stretchAction = cocos2d::ScaleBy::create(1.0f, 1.0f, stretchLength / this->getContentSize().height); auto removeAction = cocos2d::RemoveSelf::create(); auto sequence = cocos2d::Sequence::create(stretchAction, removeAction, nullptr); this->runAction(sequence); } #ifndef THORN_H #define THORN_H #include "cocos2d.h" class Thorn : public cocos2d::Sprite { public: static const int THORN_DAMAGE_TAG = 400; static const int THORN_TRIGGER_TAG = 500; virtual void setupPhysics() = 0; // 纯虚函数 virtual void onTrigger() = 0; // 纯虚函数 protected: cocos2d::PhysicsBody* damageBody; cocos2d::PhysicsBody* triggerBody; }; class StaticThorn : public Thorn { public: static StaticThorn* create(const cocos2d::Size& size, const cocos2d::Vec2& position); virtual void setupPhysics() override; virtual void onTrigger() override; }; class MovingThorn : public Thorn { public: static MovingThorn* create(const cocos2d::Size& size, const cocos2d::Vec2& position); virtual void setupPhysics() override; virtual void onTrigger() override; }; class InvisibleThorn : public Thorn { public: static InvisibleThorn* create(const cocos2d::Size& size, const cocos2d::Vec2& position); virtual void setupPhysics() override; virtual void onTrigger() override; }; class StretchingThorn : public Thorn { public: static StretchingThorn* create(const cocos2d::Size& size, const cocos2d::Vec2& position, float stretchLength); virtual void setupPhysics() override; virtual void onTrigger() override; private: float stretchLength; }; #endif // THORN_H
最新发布
06-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值