您好,登錄后才能下訂單哦!
先看一下這篇文章:
Cocos2d-x游戲開發之TecturePacker的plist解析
將一下碰撞檢測的實現原理,應為圖片基于plist的壓縮,碰撞過程中npc以及hero是一個運動的動畫,也就是說,一個動作有很多圖片合成,比如***動畫有五張圖片,而npc的運動動畫有三張,這種情況下的碰撞檢測就比較難一點,簡單的來說是矩形碰撞。
碰撞算法的具體是實現,初始化動畫的過程中將,npc和hero的動作的圖片生成一個pictureArray的集合,然后成plist中讀取圖片的大小與npc的位置生成碰撞矩行,判斷5*3次。
生成picArray的實現:
bool AnimationManager::loadAnimation(AnimationFormation *af,int count) { //緩沖——這會加載對應的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 = new CCMutableArray<CCSpriteFrame*>(); for (int i=0;i<count;i++) { CCMutableArray<CCString*> *picArray = new CCMutableArray<CCString*>(); for(int j=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=new CCString(); picName->m_sString=charBuffer; picArray->addObject(picName); //printf("------AnimationPicture: %s\n",charBuffer); //CCLOG("------AnimationPicture: %s",charBuffer); //FrameCache CCSpriteFrame *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); //parse plist CCPlistParseCache::sharedPlistParseCache()->addPictureArrayWithAnimationName(charBuffer,picArray); CCAnimationCache::sharedAnimationCache()->addAnimation(animation,charBuffer); spriteFrames->removeAllObjects(); } spriteFrames->release(); return true; }
關鍵代碼
CCPlistParseCache::sharedPlistParseCache()>addPictureArrayWithAnimation(charBuffer,picArray);
初始話后將CCPlistParseCache類的實現
class CCRectangle :public CCObject { public: const char* m_string; CCSize size; CCRectangle(); CCRectangle(const char* name,int width,int height); static float rectangleGetWidth(const CCRectangle& rect); static float rectangleGetHeight(const CCRectangle& rect); static const char* rectangleGetName(CCRectangle* rect); void setRectangle(const char* name,int width,int height); float geRectangleWidth(); CCRectangle* rect; //inline bool initRectangle(const char* m_name,int m_width,int m_height); inline int getWidth(void){return width;} inline int getHeight(void){return height;} inline const char* getName(void){return name;} inline const CCSize& getRect(void) { return m_obRect; } /** set size of the frame */ void setRect(const CCSize& rect); protected: const char* name; int width; int height; CCSize m_obRect; }; #define CCRectangleMake(name,width,height) CCRectangle((name),(width),(height)) class CCPlistParseCache : public CCObject { public: bool init(void); ~CCPlistParseCache(void); public: /** Returns the shared instance of the Sprite Frame cache */ static CCPlistParseCache* sharedPlistParseCache(void); CCPlistParseCache(void):m_pSpriteName(NULL),m_pSpriteNameAliases(NULL),m_pAnimPic(NULL){} static void purgeSharedSpriteFrameCache(void); void addSpriteCollisionWithFile(const char *pszPlist); void addWeaponCollisionWithFile(const char *pszPlist); void addObjCollisionWithFile(const char *pszPlist); void addMoonkCollisionWithFile(const char *pszPlist); CCRectangle* spriteCollisionByName(const char *pszName); void addPictureArrayWithAnimationName(const char *pszName,CCMutableArray<CCString*>*pic); CCMutableArray<CCString*>* pictureArrayByAnimationName(const char *pszName); private: CCDictionary<std::string, CCMutableArray<CCString*>*> *m_pAnimPic; const char * picForKey(const char *key, CCDictionary<std::string, CCMutableArray<CCString*>*> *picDict); CCDictionary<std::string, CCString*> *m_pSpriteNameAliases; CCDictionary<std::string, CCRectangle*> *m_pSpriteName; const char * valueForKey(const char *key, CCDictionary<std::string, CCRectangle*> *dict); }; #endif//_CCPLISTPARSECACHE_H_
部分函數的實現
void CCPlistParseCache::addSpriteCollisionWithFile(const char* pszPlist) { //Load rootDict from file, and then step into the metadata sub dict. DS_Dictionary rootDict; if(!rootDict.loadRootSubDictFromFile(pszPlist)) { printf("no load\n"); } if(!rootDict.stepIntoSubDictWithKey("texture")) { printf("No texture\n"); } //Get an int value from the subdict int someInt = rootDict.getIntegerForKey("height"); CCLOG("height %d",someInt); someInt = rootDict.getIntegerForKey("width"); CCLOG("width %d",someInt); //Step out of the sub dict and into another rootDict.stepOutOfSubDict(); if(!rootDict.stepIntoSubDictWithKey("frames")) { printf("no dic\n"); } for(int i=0;i<=59;) { char picture[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); int x=rootDict.getIntegerForKey("x"); int y=rootDict.getIntegerForKey("y"); int width=rootDict.getIntegerForKey("width"); int height=rootDict.getIntegerForKey("height"); //CCCollisionRectMake(picture,width,height); //CCLOG("Picture:%s x:%d y:%d width:%d height:%d\n",picture,x,y,width,height); CCRectangle rectangle=CCRectangleMake(picture,width-10,height-10); rect=new CCRectangle(); rect->initRectangle(picture,width,height); std::string name=picture; m_pSpriteName->setObject(rect, name); //m_pSpriteName->release(); } for(int i=0;i<=11;) { char picture[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; } int x=rootDict.getIntegerForKey("x"); int y=rootDict.getIntegerForKey("y"); int width=rootDict.getIntegerForKey("width"); int height=rootDict.getIntegerForKey("height"); //CCCollisionRectMake(picture,width,height); //printf("Picture:%s x:%d y:%d width:%d height:%d\n",picture,x,y,width,height); CCRectangle rectangle=CCRectangleMake(picture,width,height); rect=new CCRectangle(); rect->initRectangle(picture,width,height); std::string name=picture; m_pSpriteName->setObject(rect, name); //m_pSpriteName->release(); } for(int i=0;i<=11;) { char picture[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; } int x=rootDict.getIntegerForKey("x"); int y=rootDict.getIntegerForKey("y"); int width=rootDict.getIntegerForKey("width"); int height=rootDict.getIntegerForKey("height"); //CCCollisionRectMake(picture,width,height); //printf("Picture:%s x:%d y:%d width:%d height:%d\n",picture,x,y,width,height); CCRectangle rectangle=CCRectangleMake(picture,width,height); rect=new CCRectangle(); rect->initRectangle(picture,width,height); std::string name=picture; m_pSpriteName->setObject(rect, name); //m_pSpriteName->release(); } }
此類基于CCTextureCache類實現,可以參考實現其他的。
void CCPlistParseCache::addPictureArrayWithAnimationName(const char *pszName,CCMutableArray<CCString*>*pic) { CCMutableArray<CCString*> * picture=m_pAnimPic->objectForKey(pszName); //CCLOG("addPic: - %s",pszName); picture=pic; std::string picName=pszName; m_pAnimPic->setObject(picture,picName); } CCMutableArray<CCString*>* CCPlistParseCache::pictureArrayByAnimationName(const char *pszName) { CCMutableArray<CCString*> *pictureArray =m_pAnimPic->objectForKey(std::string(pszName)); if (!pictureArray) { //printf("No PictureArray!"); //CCLOG("No PictureArray!"); } return pictureArray; }
然后碰撞collision類的實現
class CCCollisionRect { public: const char* m_string; CCSize size; CCCollisionRect(); CCCollisionRect(const char* name,int width,int height); public: static CGFloat CCRectGetHeight(const CCCollisionRect& rect); static CGFloat CCRectGetWidth(const CCCollisionRect& rect); static const char* CCRectGetName(const CCCollisionRect& rect); }; #define CCCollisionRectMake(name,width, height) CCCollisionRect((name), (width), (height)) class collision:public Singleton<collision> { public: collision(void); ~collision(void); bool spriteCollision(CCNode* a,CCNode* b,const char* animationA,const char* animationB,Direction dir,Behaviour be); void spriteArray(const char* plistName); void plistParse(); void getCollisionRect(const char* animationName,Direction dir,Behaviour be,CCNode* node); CCMutableArray<CCString*>* getAnimationPictureName(const char* animationName,Direction dir,Behaviour be); char* getDirectionName(Direction direction); char* getBehaviour(Behaviour behaviour); bool isCCNodeCollision(const char* animNameA,const char* animNameB,Boy* boy,Enemy* enemy); bool isMoonkCollision(const char* animNameA,const char* animNameB,Boy* boy,Boss* boss); bool isPlayerCollision(const char* animNameA,const char* animNameB,Player* p,Enemy* enemy); bool bulletsCCNodeCollision(int i,const char* animNameA,const char* animNameB,Bullet* bullet,Enemy* enemy); bool bulletsMoonkCollision(int i,const char* animNameA,const char* animNameB,Bullet* bullet,Boss* moonk); private: BoxCollision boxCollision; bool isWingInit; bool isYdingInit; bool isPdingInit; bool isMoonkInit; }; #define sCollision collision::getInstance() #endif//_COLLISION_H_
實現一個函數
bool collision::isCCNodeCollision(const char* animNameA,const char* animNameB,Boy* boy,Enemy* enemy) { //data not had inited CCMutableArray<CCString*>*collisionPicArrayA=getAnimationPictureName(animNameA,boy->getDirection(),boy->getBehaviour()); CCMutableArray<CCString*>*collisionPicArrayB=getAnimationPictureName(animNameB,enemy->getDirection(),enemy->getBehaviour()); for(int i=0;i<collisionPicArrayA->count();i++) { for(int j=0;j<collisionPicArrayB->count();j++) { CCString* strA=collisionPicArrayA->getObjectAtIndex(i); //return rectangle width and height CCRectangle* rectangleA=CCPlistParseCache::sharedPlistParseCache()->spriteCollisionByName(strA->m_sString.c_str()); int widthA=rectangleA->getWidth(); int heightA=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()); int widthB=rectangleB->getWidth(); int heightB=rectangleB->getHeight(); char charBuffer[128]; memset(charBuffer,0,sizeof(charBuffer)); //CCLOG("COLLISION:animName:%s----width:%d height:%d\n",strA->m_sString.c_str(),widthA,heightA); //CCLOG("COLLISION:animName:%s----width:%d height:%d\n",strB->m_sString.c_str(),widthB,heightB); //attackAnimation toto_14.png~toto_19.png //ATTACK ANIMATION COLLISION校正 for(int i=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)); } CCRect a; CCRect b; a=boy->getCollisionRect(widthA,heightA); b=enemy->getCollisionRect(widthB,heightB); if(CCRect::CCRectIntersectsRect(a,b)) { //CCLOG("COLLISION YES!"); return true; } } } return false; }
具體怎么用下一篇再講,待續(兩月后,期間沒網)。。。。。。。。。。。。。。。。。。
long原創
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。