这是关于CCNode :: init()和CCNode :: onEnter()之间差异的主题.但是我遵循他们给出的建议.
void MyLayer::onEnter() {
CCLayer::onEnter();
//your code goes here
}
Run Code Online (Sandbox Code Playgroud)
我收到了Assertion failed!错误!
MyLayer代码:
class MyLayer : public CCLayerColor
Run Code Online (Sandbox Code Playgroud)
我应该添加CCLayerColor::onEnter()我的MyLayer::onEnter()代码吗?和之间有什么区别CCLayer::init()和CCLayer::onEnter().我init()应该将哪部分代码放入哪部分应该放入哪部分onEnter()?
Cocos2d-x的内存分配模型分为两步,就像objective-c一样.每个对象都分配了内存(通常使用"create"方法),然后初始化其状态(通常使用名为"init"的方法).因此,在create/init方法中,您可以分配内存并执行运行所需的任何对象初始化.
当对象开始放在显示器上,或者当它被添加到另一个容器时,它的"onEnter"方法被调用.当框架本身显示CCScene/CCLayer(其中任何一个可能包含您的CCNode派生对象)时,将调用此方法.
内存分配和对象创建至少有两种模式,我倾向于遵循一个类包含一个静态工厂方法和一个私有构造函数的模式,这样你就必须通过工厂创建对象而不能创建一个你自己.
例如,我目前正在处理这个"按钮"类:
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);
};
Run Code Online (Sandbox Code Playgroud)
请注意,"create"方法是创建它的唯一方法.在这种情况下,它接受按钮参数的参数.其他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;
}
Run Code Online (Sandbox Code Playgroud)
请注意,OnEnterXXX和onExitXXX方法调用父类方法. 您必须这样做,否则它将无法按预期工作.
这个类是一个按钮,它将在节点上运行一个动作(可能使它增长/缩小以指示它被按下).它需要用户的触摸.我无法在进入场景之前将其添加到触摸管理器.所以我使用onEnterTransitionDidFinish方法添加它,并使用onExitTransitionDidStart删除它,以便在删除场景后不会继续接收触摸.我不知道容器是否会被销毁,所以我必须在按钮退出显示器时将其移除.
这个有帮助吗?
| 归档时间: |
|
| 查看次数: |
5223 次 |
| 最近记录: |