类似愤怒的小鸟层滑动的视差效果(CCParallaxNode)和粒子效果内存泄露问题本文为firedragonpzy原创,转载务必在明显处注明:转载自【SoftewareMyZone】原文链接:欢迎热爱编程的朋友们参与到cocos2d-x编程中,为了给大家提供良好的交流环境,网站以开启QQ群SoftwareMyZone:66202765(群号,欢迎加入,若满,请加1群)SoftwareMyZone1群(2dx):286504621【加群请写:SoftwareMyZone或者是firedragonpzy】群论坛正在筹建中,欢迎大家多提些建设性意见……哎,赶快抽休息时间和大家分享点东西,今天和大家分享的是愤怒的小鸟层滑动的视差效果和有关使用粒子效果的时候产生的内存泄露。首先,谈论下一愤怒的小鸟滑动的视差效果,所谓的视差效果就是不同的精灵,移动的速度不同,造成的视觉效果。就拿愤怒的小鸟来说,你玩游戏的时候,滑动屏,会发现场景中的精灵有的滑动快,有的慢,这就是今天要讲的视差效果。这个效果,我们可以使用:CCParallaxNode这个类来实现。CCParallaxNode的声明是这样子的:123456789101112classCC_DLLCCParallaxNode:publicCCNode{/**arraythatholdstheoffset/ratioofthechildren*/CC_SYNTHESIZE(struct_ccArray*,m_pParallaxArray,ParallaxArray)public:/**Addsachildtothecontainerwithaz-order,aparallaxratioandapositionoffsetItreturnsself,soyoucanchainseveraladdChilds.@sincev0.8*/CCParallaxNode();virtual~CCParallaxNode();1314151617181920212223242526//@deprecated:Thisinterfacewillbedeprecatedsoonerorlater.CC_DEPRECATED_ATTRIBUTEstaticCCParallaxNode*node();staticCCParallaxNode*create();virtualvoidaddChild(CCNode*child,unsignedintz,constCCPoint¶llaxRatio,constCCPoint&positionOffset);//supermethodsvirtualvoidaddChild(CCNode*child,unsignedintzOrder,inttag);virtualvoidremoveChild(CCNode*child,boolcleanup);virtualvoidremoveAllChildrenWithCleanup(boolcleanup);virtualvoidvisit(void);private:CCPointabsolutePosition();protected:CCPointm_tLastPosition;};使用中最重要的就是带有四个参数的addChild()方法:1234voidCCParallaxNode::addChild(CCNode*child,unsignedintz,constCCPoint&ratio,constCCPoint&offset){CCAssert(child!=NULL,Argumentmustbenon-nil);CCPointObject*obj=CCPointObject::pointWithCCPoint(ratio,offset);567891011121314obj-setChild(child);ccArrayAppendObjectWithResize(m_pParallaxArray,(CCObject*)obj);CCPointpos=m_tPosition;pos.x=pos.x*ratio.x+offset.x;//注意这个【1】pos.y=pos.y*ratio.y+offset.y;child-setPosition(pos);CCNode::addChild(child,z,child-getTag());}在代码中标识的【1】是很重要的,这与你添加的精灵的位置息息相关,我的精灵是这么创建的12345678CCSpriteFrameCache*cache=CCSpriteFrameCache::sharedSpriteFrameCache();cache-addSpriteFramesWithFile(monkey.plist,monkey.png);CCSprite*sprite1=CCSprite::spriteWithSpriteFrameName(1.png);CCSprite*sprite2=CCSprite::spriteWithSpriteFrameName(2.png);CCSprite*sprite3=CCSprite::spriteWithSpriteFrameName(3.png);在使用了CCParallaxNode之后,设置精灵的位置是没有作用的,也不能说没有,应该说是总是不能达到你想要的效果。为什么呢,原因就在于addChild的参数,第一个参数不用废话了,第二个参数就是正常的zOrder,第三个参数是比例,例如你设置为(0.1,0.9),若你的层或者说是CCParallaxNode的实例x轴移动1,y轴移动1,则你添加的这个精灵x轴移动0.1(1*0.1),y轴移动0.9(1*0.9),这是移动对精灵的处理,但是在位置设置的时候也是有影响的。子节点的位置是这么设置的:1pos.x=pos.x*ratio.x+offset.x;所以导致你设置的位置总是达不到理想的效果,这个CCParallaxNode实例子节点的位置的设置是由实例的第三、四个参数决定的。如果你想要把精灵设置的和不用CCParallaxNode设置的位置一样,你需要这么处理(多给你贴出几个容易观察、理解):1234parallax-addChild(sprite1,1,ccp(0.4,0.4),ccp(parallax-getPositionX()*(1-0.4),parallax-getPositionY()*(1-0.4)));parallax-addChild(sprite2,2,ccp(1,1),ccp(0,0));parallax-addChild(sprite3,3,ccp(0.1,0.1),ccp(parallax-getPositionX()*(1-0.1),parallax-getPositionY()*(1-0.1)));parallax-addChild(m_emitter,4,ccp(0.3,0.3),ccp(parallax-getPositionX()*(1-0.3),parallax-getPositionY()*(1-0.3)));这里来个大家分析一下:看:pos.x=pos.x*ratio.x+offset.x;这是自己节点位置的设置,他是pos的x*ratio,然后加上offset的x。到这里咱还不知道pos是什么,看源码:1CCPointpos=m_tPosition;哦,原来是m_tPosition,在本类中,查找,没有此属性的定义,那肯定是继承来的(CCNode),那就是CCParallaxNode实例的位置。其实一算,他们合起来还是1,呵呵,说到这,大家应该明白了吧。但是这种通常不好理解,还有别的方法,那就是:1parallax-setPosition(CCPointZero);//parallax是CCParallaxNode的实例,其实默认是(0,0)位置的设置:12parallax-addChild(sprite1,1,ccp(0.4,0.4),ccp(winSize.width/2,winSize.height/2));parallax-addChild(sprite2,2,ccp(0.2,0.2),ccp(winSize.width/2,34winSize.height/2));parallax-addChild(sprite3,3,ccp(0.1,0.1),ccp(winSize.width/2,winSize.height/2));parallax-addChild(m_emitter,4,ccp(0.3,0.3),ccp(winSize.width/2,winSize.height/2));第四个参数想设置要什么位置就设置什么位置,原理在我绕了一个大弯路讲解之后大家应该明白了吧!刚刚开始研究CCParallaxNode习惯性设置位置,所以导致自己郁闷了好久,先与大家分析一下,讲解一下原理,望大家不要再走我的弯路……至于为什么我添加四个节点都是屏幕中间位置,那是我为了让大家更好的明白这个位置问题,之后我贴出的代码有注释了的,注释了的为设置了CCParallaxNode的实例的位置,大家开启比较一下,会更加明白的。对了,还有一点就是关于这个移动,你移动CCParallaxNode的实例也行,移动层也行,看需求。好了,关于CCParallaxNode就讲到这里吧。。。现贴出源码:1234567891011CCParticleSystem*m_emitter=CCParticleSystemQuad::particleWithFile(fire2.plist);m_emitter-setAutoRemoveOnFinish(true);//this-addChild(m_emitter);CCSpriteFrameCache*cache=CCSpriteFrameCache::sharedSpriteFrameCache();cache-addSpriteFramesWithFile(monkey.plist,monkey.png);CCSprite*sprite1=CCSprite::spriteWithSpriteFrameName(1.png);CCSprite*sprite2=CCSprite::spriteWithSpriteFrameName(2.png);12131415161718192021222324252627282930CCSprite*sprite3=CCSprite::spriteWithSpriteFrameName(3.png);CCSizewinSize=CCDirector::sharedDirector()-getWinSize(); CCTexture2D*texture=CCTextureCache::sharedTextureCache()-textureForKey(monkey.png);CCSpriteBatchNode*batchNode=CCSpriteBatchNode::createWithTexture(texture);batchNode-setPosition(ccp(0,0));this-addChild(batchNode,1);//batchNode-addChild(sprite1);//batchNode-addChild(sprite2);//batchNode-addChild(sprite3);//parallax=CCParallaxNode::create();//parallax-setPosition(ccp(winSize.width/2,winSize.