cocos2d-x开发之动作游戏实战--5
先看一下这篇文章:
Cocos2d-x游戏开发之TecturePacker的plist解析
将一下碰撞检测的实现原理,应为图片基于plist的压缩,碰撞过程中npc以及hero是一个运动的动画,也就是说,一个动作有很多图片合成,比如***动画有五张图片,而npc的运动动画有三张,这种情况下的碰撞检测就比较难一点,简单的来说是矩形碰撞。
碰撞算法的具体是实现,初始化动画的过程中将,npc和hero的动作的图片生成一个pictureArray的集合,然后成plist中读取图片的大小与npc的位置生成碰撞矩行,判断5*3次。
生成picArray的实现:
boolAnimationManager::loadAnimation(AnimationFormation*af,intcount){//缓冲——这会加载对应的png,并裁切成SpriteFrame,而且还会完成索引memset(charBuffer,0,sizeof(charBuffer));//sprintf(charBuffer,"objectTexture/16bit/4444-%sYPding.plist",af[0].animateName);//CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(charBuffer);CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(totoYPdingPlist);//创建动画数据CCMutableArray<CCSpriteFrame*>*spriteFrames=newCCMutableArray<CCSpriteFrame*>();for(inti=0;i<count;i++){CCMutableArray<CCString*>*picArray=newCCMutableArray<CCString*>();for(intj=getDirection(af[i].direction);j<getDirection(af[i].direction)+af[i].frameNum;j++){memset(charBuffer,0,sizeof(charBuffer));sprintf(charBuffer,"%s_%d.png",af[i].animateName,/*getBehaviour(af[i].behaviour)*/j);CCString*picName=newCCString();picName->m_sString=charBuffer;picArray->addObject(picName);//printf("------AnimationPicture:%s\n",charBuffer);//CCLOG("------AnimationPicture:%s",charBuffer);//FrameCacheCCSpriteFrame*spriteFrame=CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(charBuffer);spriteFrames->addObject(spriteFrame);}//使用cache缓冲管理CCAnimation*animation=CCAnimation::animationWithFrames(spriteFrames,0.1f);memset(charBuffer,0,sizeof(charBuffer));sprintf(charBuffer,"%s_%s%s",af[i].animateName,getBehaviour(af[i].behaviour),getDirectionName(af[i].direction));//CCLOG("AnimationName:%s\n",charBuffer);//parseplistCCPlistParseCache::sharedPlistParseCache()->addPictureArrayWithAnimationName(charBuffer,picArray);CCAnimationCache::sharedAnimationCache()->addAnimation(animation,charBuffer);spriteFrames->removeAllObjects();}spriteFrames->release();returntrue;}
关键代码
CCPlistParseCache::sharedPlistParseCache()>addPictureArrayWithAnimation(charBuffer,picArray);
初始话后将CCPlistParseCache类的实现
classCCRectangle:publicCCObject{public:constchar*m_string;CCSizesize;CCRectangle();CCRectangle(constchar*name,intwidth,intheight);staticfloatrectangleGetWidth(constCCRectangle&rect);staticfloatrectangleGetHeight(constCCRectangle&rect);staticconstchar*rectangleGetName(CCRectangle*rect);voidsetRectangle(constchar*name,intwidth,intheight);floatgeRectangleWidth();CCRectangle*rect;//inlineboolinitRectangle(constchar*m_name,intm_width,intm_height);inlineintgetWidth(void){returnwidth;}inlineintgetHeight(void){returnheight;}inlineconstchar*getName(void){returnname;}inlineconstCCSize&getRect(void){returnm_obRect;}/**setsizeoftheframe*/voidsetRect(constCCSize&rect);protected:constchar*name;intwidth;intheight;CCSizem_obRect;};#defineCCRectangleMake(name,width,height)CCRectangle((name),(width),(height))classCCPlistParseCache:publicCCObject{public:boolinit(void);~CCPlistParseCache(void);public:/**ReturnsthesharedinstanceoftheSpriteFramecache*/staticCCPlistParseCache*sharedPlistParseCache(void);CCPlistParseCache(void):m_pSpriteName(NULL),m_pSpriteNameAliases(NULL),m_pAnimPic(NULL){}staticvoidpurgeSharedSpriteFrameCache(void);voidaddSpriteCollisionWithFile(constchar*pszPlist);voidaddWeaponCollisionWithFile(constchar*pszPlist);voidaddObjCollisionWithFile(constchar*pszPlist);voidaddMoonkCollisionWithFile(constchar*pszPlist);CCRectangle*spriteCollisionByName(constchar*pszName);voidaddPictureArrayWithAnimationName(constchar*pszName,CCMutableArray<CCString*>*pic);CCMutableArray<CCString*>*pictureArrayByAnimationName(constchar*pszName);private:CCDictionary<std::string,CCMutableArray<CCString*>*>*m_pAnimPic;constchar*picForKey(constchar*key,CCDictionary<std::string,CCMutableArray<CCString*>*>*picDict);CCDictionary<std::string,CCString*>*m_pSpriteNameAliases;CCDictionary<std::string,CCRectangle*>*m_pSpriteName;constchar*valueForKey(constchar*key,CCDictionary<std::string,CCRectangle*>*dict);};#endif//_CCPLISTPARSECACHE_H_
部分函数的实现
voidCCPlistParseCache::addSpriteCollisionWithFile(constchar*pszPlist){//LoadrootDictfromfile,andthenstepintothemetadatasubdict.DS_DictionaryrootDict;if(!rootDict.loadRootSubDictFromFile(pszPlist)){printf("noload\n");}if(!rootDict.stepIntoSubDictWithKey("texture")){printf("Notexture\n");}//GetanintvaluefromthesubdictintsomeInt=rootDict.getIntegerForKey("height");CCLOG("height%d",someInt);someInt=rootDict.getIntegerForKey("width");CCLOG("width%d",someInt);//StepoutofthesubdictandintoanotherrootDict.stepOutOfSubDict();if(!rootDict.stepIntoSubDictWithKey("frames")){printf("nodic\n");}for(inti=0;i<=59;){charpicture[20];sprintf(picture,"toto_%d.png",i);CCRectangle*rect=m_pSpriteName->objectForKey(picture);if(!rootDict.stepIntoSubDictWithKey(picture)){i++;//CCLOG("---noid--%d",i);rootDict.stepOutOfSubDict();continue;}//CCLOG("----totoid-------%d",i);intx=rootDict.getIntegerForKey("x");inty=rootDict.getIntegerForKey("y");intwidth=rootDict.getIntegerForKey("width");intheight=rootDict.getIntegerForKey("height");//CCCollisionRectMake(picture,width,height);//CCLOG("Picture:%sx:%dy:%dwidth:%dheight:%d\n",picture,x,y,width,height);CCRectanglerectangle=CCRectangleMake(picture,width-10,height-10);rect=newCCRectangle();rect->initRectangle(picture,width,height);std::stringname=picture;m_pSpriteName->setObject(rect,name);//m_pSpriteName->release();}for(inti=0;i<=11;){charpicture[20];sprintf(picture,"yDing_%d.png",i);CCRectangle*rect=m_pSpriteName->objectForKey(picture);if(!rootDict.stepIntoSubDictWithKey(picture)){i++;//printf("No%s\n",picture);rootDict.stepOutOfSubDict();continue;}intx=rootDict.getIntegerForKey("x");inty=rootDict.getIntegerForKey("y");intwidth=rootDict.getIntegerForKey("width");intheight=rootDict.getIntegerForKey("height");//CCCollisionRectMake(picture,width,height);//printf("Picture:%sx:%dy:%dwidth:%dheight:%d\n",picture,x,y,width,height);CCRectanglerectangle=CCRectangleMake(picture,width,height);rect=newCCRectangle();rect->initRectangle(picture,width,height);std::stringname=picture;m_pSpriteName->setObject(rect,name);//m_pSpriteName->release();}for(inti=0;i<=11;){charpicture[20];sprintf(picture,"pDing_%d.png",i);//printf("piccture-----%s",picture);CCRectangle*rect=m_pSpriteName->objectForKey(picture);if(!rootDict.stepIntoSubDictWithKey(picture)){i++;//printf("No%s\n",picture);rootDict.stepOutOfSubDict();continue;}intx=rootDict.getIntegerForKey("x");inty=rootDict.getIntegerForKey("y");intwidth=rootDict.getIntegerForKey("width");intheight=rootDict.getIntegerForKey("height");//CCCollisionRectMake(picture,width,height);//printf("Picture:%sx:%dy:%dwidth:%dheight:%d\n",picture,x,y,width,height);CCRectanglerectangle=CCRectangleMake(picture,width,height);rect=newCCRectangle();rect->initRectangle(picture,width,height);std::stringname=picture;m_pSpriteName->setObject(rect,name);//m_pSpriteName->release();}}
此类基于CCTextureCache类实现,可以参考实现其他的。
voidCCPlistParseCache::addPictureArrayWithAnimationName(constchar*pszName,CCMutableArray<CCString*>*pic){CCMutableArray<CCString*>*picture=m_pAnimPic->objectForKey(pszName);//CCLOG("addPic:-%s",pszName);picture=pic;std::stringpicName=pszName;m_pAnimPic->setObject(picture,picName);}CCMutableArray<CCString*>*CCPlistParseCache::pictureArrayByAnimationName(constchar*pszName){CCMutableArray<CCString*>*pictureArray=m_pAnimPic->objectForKey(std::string(pszName));if(!pictureArray){//printf("NoPictureArray!");//CCLOG("NoPictureArray!");}returnpictureArray;}
然后碰撞collision类的实现
classCCCollisionRect{public:constchar*m_string;CCSizesize;CCCollisionRect();CCCollisionRect(constchar*name,intwidth,intheight);public:staticCGFloatCCRectGetHeight(constCCCollisionRect&rect);staticCGFloatCCRectGetWidth(constCCCollisionRect&rect);staticconstchar*CCRectGetName(constCCCollisionRect&rect);};#defineCCCollisionRectMake(name,width,height)CCCollisionRect((name),(width),(height))classcollision:publicSingleton<collision>{public:collision(void);~collision(void);boolspriteCollision(CCNode*a,CCNode*b,constchar*animationA,constchar*animationB,Directiondir,Behaviourbe);voidspriteArray(constchar*plistName);voidplistParse();voidgetCollisionRect(constchar*animationName,Directiondir,Behaviourbe,CCNode*node);CCMutableArray<CCString*>*getAnimationPictureName(constchar*animationName,Directiondir,Behaviourbe);char*getDirectionName(Directiondirection);char*getBehaviour(Behaviourbehaviour);boolisCCNodeCollision(constchar*animNameA,constchar*animNameB,Boy*boy,Enemy*enemy);boolisMoonkCollision(constchar*animNameA,constchar*animNameB,Boy*boy,Boss*boss);boolisPlayerCollision(constchar*animNameA,constchar*animNameB,Player*p,Enemy*enemy);boolbulletsCCNodeCollision(inti,constchar*animNameA,constchar*animNameB,Bullet*bullet,Enemy*enemy);boolbulletsMoonkCollision(inti,constchar*animNameA,constchar*animNameB,Bullet*bullet,Boss*moonk);private:BoxCollisionboxCollision;boolisWingInit;boolisYdingInit;boolisPdingInit;boolisMoonkInit;};#definesCollisioncollision::getInstance()#endif//_COLLISION_H_
实现一个函数
boolcollision::isCCNodeCollision(constchar*animNameA,constchar*animNameB,Boy*boy,Enemy*enemy){//datanothadinitedCCMutableArray<CCString*>*collisionPicArrayA=getAnimationPictureName(animNameA,boy->getDirection(),boy->getBehaviour());CCMutableArray<CCString*>*collisionPicArrayB=getAnimationPictureName(animNameB,enemy->getDirection(),enemy->getBehaviour());for(inti=0;i<collisionPicArrayA->count();i++){for(intj=0;j<collisionPicArrayB->count();j++){CCString*strA=collisionPicArrayA->getObjectAtIndex(i);//returnrectanglewidthandheightCCRectangle*rectangleA=CCPlistParseCache::sharedPlistParseCache()->spriteCollisionByName(strA->m_sString.c_str());intwidthA=rectangleA->getWidth();intheightA=rectangleA->getHeight();//CCLOG("---------------Collision:%s",strA->m_sString.c_str());CCString*strB=collisionPicArrayB->getObjectAtIndex(j);CCRectangle*rectangleB=CCPlistParseCache::sharedPlistParseCache()->spriteCollisionByName(strB->m_sString.c_str());intwidthB=rectangleB->getWidth();intheightB=rectangleB->getHeight();charcharBuffer[128];memset(charBuffer,0,sizeof(charBuffer));//CCLOG("COLLISION:animName:%s----width:%dheight:%d\n",strA->m_sString.c_str(),widthA,heightA);//CCLOG("COLLISION:animName:%s----width:%dheight:%d\n",strB->m_sString.c_str(),widthB,heightB);//attackAnimationtoto_14.png~toto_19.png//ATTACKANIMATIONCOLLISION校正for(inti=14;i<14+5;i++){sprintf(charBuffer,"toto_%d.png",i);if(strcmp(charBuffer,strA->m_sString.c_str())==0){widthA=widthA-70;heightA=heightA-50;}memset(charBuffer,0,sizeof(charBuffer));}CCRecta;CCRectb;a=boy->getCollisionRect(widthA,heightA);b=enemy->getCollisionRect(widthB,heightB);if(CCRect::CCRectIntersectsRect(a,b)){//CCLOG("COLLISIONYES!");returntrue;}}}returnfalse;}
具体怎么用下一篇再讲,待续(两月后,期间没网)。。。。。。。。。。。。。。。。。。
long原创
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。