这是关于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/