cocos2d - x 개발 의 액 션 게임 실전 - 5

먼저 이 글 을 보 세 요.
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 *spriteFrames = new CCMutableArray();
    for (int i=0;i *picArray = new CCMutableArray();
        for(int j=getDirection(af[i].direction);jm_sString=charBuffer;
            picArray->addObject(picName);
            //printf("------AnimationPicture:    %s
",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
",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*pic);
    CCMutableArray* pictureArrayByAnimationName(const char *pszName);
private:
    CCDictionary<:string>*> *m_pAnimPic;
    const char * picForKey(const char *key, CCDictionary<:string>*> *picDict);
    CCDictionary<:string> *m_pSpriteNameAliases;
    CCDictionary<:string> *m_pSpriteName;
    const char * valueForKey(const char *key, CCDictionary<:string> *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
");     }     if(!rootDict.stepIntoSubDictWithKey("texture"))     {            printf("No texture
");     }     //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
");     }     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
",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
",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
",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
",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
",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*pic)
{
    CCMutableArray * picture=m_pAnimPic->objectForKey(pszName);
    //CCLOG("addPic:      -   %s",pszName);
    picture=pic;
    std::string picName=pszName;
    m_pAnimPic->setObject(picture,picName);
}
CCMutableArray* CCPlistParseCache::pictureArrayByAnimationName(const char *pszName)
{
    CCMutableArray *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
{
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* 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*collisionPicArrayA=getAnimationPictureName(animNameA,boy->getDirection(),boy->getBehaviour());
    CCMutableArray*collisionPicArrayB=getAnimationPictureName(animNameB,enemy->getDirection(),enemy->getBehaviour());
                  
    for(int i=0;icount();i++)
    {
        for(int j=0;jcount();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
",strA->m_sString.c_str(),widthA,heightA);             //CCLOG("COLLISION:animName:%s----width:%d    height:%d
",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; }

구체 적 으로 어떻게 다음 편 으로 다시 이야기 하 는 지, 계속 (두 달 후, 기간 에 인터넷 이 없 음)....................................................
롱 오리지널

좋은 웹페이지 즐겨찾기