这是关于Difference between CCNode::init() and CCNode::onEnter()的主题。但是我遵循他们给出的advice

void MyLayer::onEnter() {
    CCLayer::onEnter();
    //your code goes here
}


我收到了Assertion failed!错误!
MyLayer代码:

class MyLayer : public CCLayerColor


我应该在我的CCLayerColor::onEnter()代码中添加MyLayer::onEnter()吗? CCLayer::init()CCLayer::onEnter()有什么区别。我应将哪一部分代码放入init()中,并将哪一部分放入onEnter()中?

最佳答案

Cocos2d-x具有它的内存分配模型,该过程分为两步,例如Objective-c。每个对象都有分配的内存(通常使用“创建”方法),然后初始化其状态(通常使用称为“ init”的方法)。因此,在create / init方法中,您可以分配内存并进行运行所需的任何对象初始化。

当对象开始放到显示器上或添加到另一个容器时,将调用其“ onEnter”方法。当框架本身显示CCScene / CCLayer(两者都可能包含您的CCNode派生对象)时,将调用此方法。

至少有2种模式用于内存分配和对象创建,我倾向于遵循这样的模式:让一个类包含一个静态工厂方法和一个私有构造函数,这样一来,您必须通过工厂创建对象而不能创建一个对象,这一点很明确。你自己

例如,我目前正在研究这个“按钮”类:

class ActionButton;

class ActionButtonTarget
{
public:
   virtual void ActionButtonActivated(ActionButton* button) = 0;
};

class ActionButton : public CCNode, public CCTargetedTouchDelegate
{
private:
   ActionButton();

   CCNode* _node; // Weak Reference
   CCRect _testRect;
   ActionButtonTarget* _target;

   bool init(ActionButtonTarget* target, CCNode* node, CCRect rect);
   bool IsTouchInside(CCTouch* touch);

   void NotifyTarget();

protected:
   virtual CCAction* CreateAction();

public:

   virtual ~ActionButton();

   // The class registers/unregisters on entry
   // or exit of the layer.  This
   virtual void onEnterTransitionDidFinish();
   virtual void onExitTransitionDidStart();

   virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
   virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
   virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
   virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);

   static ActionButton* create(ActionButtonTarget* target, CCNode* node, CCRect rect);
};


请注意,“创建”方法是创建它的唯一方法。在这种情况下,它将参数用作按钮的参数。其他从CCNode派生的对象(例如CCScene)通常不会。

内部:

ActionButton::ActionButton()
{
}

ActionButton::~ActionButton()
{

}

// The class registers/unregisters on entry
// or exit of the layer.  This
void ActionButton::onEnterTransitionDidFinish()
{
   CCNode::onEnterTransitionDidFinish();
   CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
}

void ActionButton::onExitTransitionDidStart()
{
   CCNode::onExitTransitionDidStart();
   CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
}

bool ActionButton::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
   if(IsTouchInside(pTouch))
   {
      return true;
   }
   return false;
}

void ActionButton::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)
{
   // Nothing to do here.
}

void ActionButton::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
{
   NotifyTarget();
}

bool ActionButton::IsTouchInside(CCTouch* touch)
{
   CCPoint point = touch->getLocationInView();
   point = CCDirector::sharedDirector()->convertToGL(point);
   return _testRect.containsPoint(point);
}


void ActionButton::ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent)
{
   _target->ActionButtonActivated(this);
}

ActionButton* ActionButton::create(ActionButtonTarget* target, CCNode* node, CCRect rect)
{
   ActionButton *pRet = new ActionButton();
   if (pRet && pRet->init(target,node,rect))
   {
      pRet->autorelease();
      return pRet;
   }
   else
   {
      CC_SAFE_DELETE(pRet);
      return NULL;
   }
}

CCAction* ActionButton::CreateAction()
{
   return NULL;
}

void ActionButton::NotifyTarget()
{
   CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect(Constants::SOUND_EFFECT_BUTTON_CLICK());
   _target->ActionButtonActivated(this);
}



bool ActionButton::init(ActionButtonTarget* target, CCNode* node, CCRect rect)
{
   assert(target != NULL);
   assert(node != NULL);
   assert(dynamic_cast<ActionButtonTarget*>(target) != NULL);

   _target = target;
   _node  = node;
   _testRect = rect;

   addChild(_node);

   return true;
}


注意,OnEnterXXX和onExitXXX方法调用父类方法。您必须执行此操作,否则它将无法正常工作。

此类是一个按钮,它将在节点上运行一个动作(也许使其增大/缩小以指示已被按下)。它需要来自用户的触摸。在进入场景之前,我无法将其添加到触摸管理器中。因此,我使用onEnterTransitionDidFinish方法添加它,也使用onExitTransitionDidStart删除它,这样在删除场景后它将不会继续接收触摸。我不知道该容器是否会被破坏,因此当按钮退出显示屏时,我必须将其删除。

这个有帮助吗?

关于cocos2d-x - CCLayer::init()和CCLayer::onEnter()之间的区别?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20769747/

10-11 22:49