cocos2d - x 개발 의 액 션 게임 실전 - 5
14783 단어 cocos2d - x 액 션 게임cocos2d-x
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;
}
구체 적 으로 어떻게 다음 편 으로 다시 이야기 하 는 지, 계속 (두 달 후, 기간 에 인터넷 이 없 음)....................................................
롱 오리지널
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Cocos2d-x에서 파티클을 처리하는 방법1. 소개 2. 파티클 만들기 3. 실제로 그려 보자! 4. 조심하세요! Cocos2d-x 버전은 3.10으로 진행됩니다. 우선 소재인 파티클이 필요하기 때문에 에 액세스합시다 영어만! ! 야다! 라고 생각합니다만,...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.