温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

cocos2d-x开发之动作游戏实战--5

发布时间:2020-07-19 22:44:03 来源:网络 阅读:1148 作者:lonag 栏目:游戏开发

  先看一下这篇文章:

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原创




向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI