菜鸟也能学cocos2dx 3.0 伊始(一)

虽然只有1个半月的cocos基础,但是我感觉我浑身充满了力量and power~~

进入正题, 现在我来大致谈下cocos2dx这款引擎。
1.cocos2dx是采用树形的方式和引用计数管理成员对象的, 
 引用计数:引用计数其实很简单,就是0的时候被释放,>=1的时候对象存在,通过addchild可以将参数的对象   添加到layer上。简单看下引擎代码:
        
void Node::addChild(Node *child, int zOrder, int tag)
{ 
CCASSERT( child != nullptr, "Argument must be non-nil");//断言判断child是否不为空指针,nullptr也是c++特性

CCASSERT( child->_parent == nullptr, "child already added. It can't be added again");

//_children 是个存放了node指针的vector容器,getchildren其实就是获得这个容器.

if (_children.empty())//如果当前vector没有对象的话,执行childrenalloc,为vector预留4个元素大小的空间
{

this->childrenAlloc();

}

this->insertChild(child, zOrder);//然后添加child,并设置层级,即zorder,在引擎树形遍历 的时候会将zorder大的放在上层

#if CC_USE_PHYSICS//如果用了引擎就开始下面的处理

if (child->getPhysicsBody() != nullptr)//判断引擎对象
{
child->getPhysicsBody()->setPosition(this->convertToWorldSpace(child->getPosition()));//切换到世界坐标系
}

for (Node* node = this->getParent(); node != nullptr; node = node->getParent())
{
if (dynamic_cast<Scene*>(node) != nullptr)
{
(

dynamic_cast<Scene*>(node))->addChildToPhysicsWorld(child);//node强转为场景添加到引擎world中去。
break;
}
}
#endif

child->_tag = tag;//tag默认为-1

child->setParent(this);//child的父对象为this
child->setOrderOfArrival(s_globalOrderOfArrival++);

if( _running )
{
child->onEnter();
// prevent onEnterTransitionDidFinish to be called twice when a node is added in onEnter
if (_isTransitionFinished) {
child->onEnterTransitionDidFinish();
}
}

if (_cascadeColorEnabled)//颜色变化默认为false,action的时候用到
{
updateCascadeColor();
}

if (_cascadeOpacityEnabled)//透明度变化false,同上
{
updateCascadeOpacity();
}
}

   其实这些还不是重点,主要看  this->insertChild(child, zOrder)这,进行了引用计数  ,在创建对象成功的时候引用计数为1,添加到场景之后引用计数为2,就是这个原因了:
void Node::insertChild(Node* child, int z)
{
    _reorderChildDirty = true;
    _children.pushBack(child);
    child->_setLocalZOrder(z);
}
void pushBack(T object)
    {
        CCASSERT(object != nullptr, "The object should not be nullptr");
        _data.push_back( object );
        object->retain();//就是这里~
    }


所以说,引用计数为1的只是说明创建了这个对象,是存在的,但是不以为着这个对象一定会在场景中显示的存在的。
又比如你创建了容器,存放sprite,方便以后调用std;:vector<Sprite*> _vec,那么你就改更加注意容器里面对象的引用计数了。
顺便提一下vector,不得不说太好用了,在我看来,vetor就像是一个动态数组。
你可以用sort对vector里面的对象进行排序,你可以v.pushback("heihei");添加元素。不过最好时刻关注你的内存,以及vector的capacity,因为vector的动态增长,是通过一段预留空间(reserve)实现的,而引擎内的cache类基本也都是用vector和map的衍生,当你添加过多缓存的时候,会发生一些预想不到的问题。

2.说一下我之前遇到过的一些问题:
Q:我用了cocostudio的scorlliview,我知道scollview内部有实现触摸机制,那么我在外部添加 onebyone即单点触控的时候为什么会感应不到?
R:这个大哥,问得好!这就涉及到触摸优先级的问题了,我可以告诉你scollview的优先级为0!而你外部添加的触摸事件增会大于0.那么这个时候你就需要修改优先级了:
listener=EventListenerTouchOneByOne::create();
listener->onTouchbegan=[&](Touch* touch,Event event){
CCLOG("touch");
return true;
};//&引用传递,=值传递,this即将当前对象传进去,这里用的是lambda.
_eventDispatcher->addEventListenerWithFixedPriority(listener,-1);//添加,并设置优先级为-1;
当前你也可以这样:
Director::getInstance()->getEventDispatcher()->setPriority(listener,-1);//
简单粗暴OK!

其实吧,之前我用了3.0final的时候就发现一个问题关于onkeyrelease:
void myUI::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event)
{
if (keyCode==EventKeyboard::KeyCode::KEY_BACKSPACE)
{
             Director::getInstance()->end();
}

}


发现,诶?!怎么点击了后退没反应??当时没解决,就做了另外一个按钮去关闭它。现在一想,可能是触摸优先级的事情~欢迎各位大哥大姐去尝试下~ps:本人目前用的是3.0beta2,为什么?因为懒~因为beta2可爱的ui创建工程~
2.spine的问题,如果我要在spine骨骼的手掌上实现武器的换装,怎么搞?
众所周知,skeleton并没有继承node,那么我们就无法直接在slot or bone上添加sprite,那么怎么办?改!
借鉴这位大神的一篇文章,就能很好的解决这个问题:
http://blog.csdn.net/n5/article/details/21795265


  本人会陆续推出菜鸟也能学cocos一系列文章,每篇文章都会有俩个模块,1-讲下cocos引擎,2-提问和回答问题,有什么好的意见或者问题也可以在评论里面写出来。然后就是最重要的~,求收藏,求订阅,欢迎关注~
 ps:本人果断菜鸟!如果有什么不对的,希望各位大神指出,互相进步~大笑

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值