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

     这个实例基于cocos2d-x-12版本开发,有点久了,不过没关系。

     设计模式采用单例模式,开发环境为vs2010,后期会写怎么移植到android中去,好可以开始了。

     单例模式的代码写拷贝过来。

#ifndef __SINGLETON_H__//40
#define __SINGLETON_H__
/*
单例模式
*/
template <typename T>
class Singleton
{
public:
    inline static T* getInstance();
    inline static void release();
private:
    static T* t;
};
template <typename T>
inline T* Singleton<T>::getInstance()
{
    if (!t)
    {
        t = new T;
    }
    return t;
}
template<typename T>
inline void Singleton<T>::release()
{
    if (t)
    {
        delete t;
        t = 0;
    }
}
template <typename T>
T* Singleton<T>::t = 0;
#endif // __SINGLE_H__

添加到HelloWorld项目中,新建Global.h文件和Animation.h文件部分代码如下;

#ifndef _GLOBAL_H_//143
#define _GLOBAL_H_
#include"cocos2d.h"
#include"core/Singleton.h"
#include"DBgame.h"
#include"core/boy.h"
#include"core\boss.h"
#include"Core\typedefine.h"
#define MaxBuffer 100
using namespace cocos2d;
class Global:public Singleton<Global>
{
public:
    Global(void);
    ~Global(void);
    bool init();
};
#define sGlobal Global::getInstance()
#endif//_GLOBAL_

Animation.h

#ifndef _ANIMATION_H_//41
#define _ANIMATION_H_
#include"core/boy.h"
#include "cocos2d.h"
#include "core/Singleton.h"
struct  AnimationFormation
{
    char *animateName;//动画名:对应文件开头
    int frameNum;//帧数
    Behaviour behaviour;//行为
    Direction direction;//朝向
};
extern AnimationFormation heroAnimation[12];
extern AnimationFormation bombAnimation[2];
extern AnimationFormation monsterAnimation[3];
extern AnimationFormation monster[3];
extern AnimationFormation pDing[3];
extern AnimationFormation wing[4];
extern AnimationFormation box[4];
extern AnimationFormation portal[2];
extern AnimationFormation cube[2];
extern AnimationFormation moonk[8];
extern AnimationFormation toto_weapon[11];
class AnimationManager:public Singleton<AnimationManager>
{
public:
    bool loadAnimation(AnimationFormation *af,int count);
    bool loadObjAnimation(AnimationFormation *af,int count);
    bool loadWeaponAnimation(AnimationFormation *af,int count);
    bool loadMoonkAnimation(AnimationFormation *af,int count);
    cocos2d::CCAnimate* getAnimate(char *name,Behaviour behaviour,Direction direction);
    cocos2d::CCAnimation* getAnimation(char *name,Behaviour behaviour,Direction direction);
    int getDirection(Direction direction);
    char* getDirectionName(Direction direction);
    char* getBehaviour(Behaviour behaviour);
private:
    char *getAnimationName(char *name,Behaviour behaviour,Direction direction);
};
#define sAnimation AnimationManager::getInstance()
#endif//

现在打开HelloWorld.cpp文件,添加以下代码;

主要为控制部分

CCMenuItemImage *pBtn_Left = CCMenuItemImage::itemFromNormalImage(
            btn_left_d,
            btn_left_u
            );
        CCMenuItemImage *pBtn_Right = CCMenuItemImage::itemFromNormalImage(
            btn_right_d,
            btn_right_u
            );
                                                                                                                              
        CCMenuItemImage *pBtn_Jump = CCMenuItemImage::itemFromNormalImage(
            jump_btn_d,
            jump_btn_u
            );
        CCMenuItemImage *pBtn_Attack = CCMenuItemImage::itemFromNormalImage(
            attack_btn_d,
            attack_btn_u
            );
        CCMenu* pControlBtn = CCMenu::menuWithItems(pBtn_Left,pBtn_Right,pBtn_Attack, NULL);
        pBtn_Left->setPosition(ccp(50*(size.width/480),35*(size.height/320)));
        pBtn_Left->setScaleX(size.width/480);
        pBtn_Left->setScaleY(size.height/320);
        pBtn_Right->setPosition(ccp(150*(size.width/480),35*(size.height/320)));//50 150 435 325
        pBtn_Right->setScaleX(size.width/480);
        pBtn_Right->setScaleY(size.height/320);
        pBtn_Jump->setPosition(ccp(435*(size.width/480),40*(size.height/320)));//1174.5
        pBtn_Jump->setScaleX(size.width/480);
        pBtn_Jump->setScaleY(size.height/320);
        pBtn_Attack->setPosition(ccp(325*(size.width/480),40*(size.height/320)));//877.5
        pBtn_Attack->setScaleX(size.width/480);
        pBtn_Attack->setScaleY(size.height/320);
        CCMenu* jumpBtn = CCMenu::menuWithItems(pBtn_Jump,NULL);
        jumpBtn->setPosition(CCPointZero);
        pControlBtn->setPosition(CCPointZero);
        this->addChild(jumpBtn,1);
        this->addChild(pControlBtn,1);


注意一点,pBtn_Jump单独加载的,这样可以与其他按键同时被按下。setScale()函数放大CCNode的包括(CCSprite,等)。

然后开始加载地图

int lvl = CCUserDefault::sharedUserDefault()->getIntegerForKey("lvl");
        if(lvl == 0)
        {
            lvl = 1;
            CCUserDefault::sharedUserDefault()->setIntegerForKey("lvl",1);
        }
                                                                                              
//---------------------------------2013.3.4---------------------------------
        //int lvl=1;
        char mapPath[20];
        char lvlinform[30];
        //map_tmx_lvl1
        sprintf(mapPath,"mapTmx/map%d.tmx",lvl);
        sprintf(lvlinform,"Lvl %d",lvl);
        CCTMXTiledMap *map = CCTMXTiledMap::tiledMapWithTMXFile(mapPath);
        //addChild(map,0,mapList);
        if(!map)
        {
            CCLOG("map not init!");
        }
        map->setAnchorPoint(CCPointZero);
        map->setPosition(ccp(0,50*(size.height/320)));//112.5
        map->setScaleX(size.width/480);
        map->setScaleY(size.height/320);
        this->addChild(map,-2,mapList);

Animation.cpp的部分代码


#include "core/Animation.h"//386
#include"DBgame.h"
using namespace cocos2d;
static char charBuffer[128];
AnimationFormation heroAnimation[12]=
{
    {"toto",1,STAND,LEFT},
    {"toto",1,STAND,RIGHT},
    {"toto",1,STAND,OVERLOOK},
    {"toto",2,MOVE,LEFT},
    {"toto",2,MOVE,RIGHT},
    {"toto",3,MOVE,JUMP},/*      3       */
    {"toto",5,MOVE,ATTACK},
    {"toto",4,MOVE,JUMPATTACK},
    {"toto",6,DEAD,OVERLOOK},
    {"toto",2,MOVE,ATTACKED},
    {"toto",4,MOVE,FIRESTAND},
    {"toto",4,MOVE,ICESTAND},
};
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;
}
//根据方向与行为对animation的frame(51帧)进行截取1-5 6-12 13-15等
cocos2d::CCAnimate* AnimationManager::getAnimate(char *name,Behaviour behaviour,Direction direction )
{
    CCAnimation* animation=CCAnimationCache::sharedAnimationCache()->animationByName(getAnimationName(name,behaviour,direction));
    if(animation)
    {
        return cocos2d::CCAnimate::actionWithAnimation(animation);
    }
    return NULL;
}
CCAnimation* AnimationManager::getAnimation(char *name,Behaviour behaviour,Direction direction)
{
    CCAnimation* animation=CCAnimationCache::sharedAnimationCache()->animationByName(getAnimationName(name,behaviour,direction));
    if(animation)
    {
        return animation;
    }
    return NULL;
}
char* AnimationManager::getAnimationName(char *name,Behaviour behaviour,Direction direction )
{
    memset(charBuffer,0,sizeof(charBuffer));
    sprintf(charBuffer,"%s_%s%s",name,getBehaviour(behaviour),getDirectionName(direction));
    return charBuffer;
}
char* AnimationManager::getBehaviour( Behaviour behaviour )
{
    switch(behaviour)
    {
    case STAND:
        return "stand";
    case MOVE:
        return "move";
    case DEAD:
        return "dead";
    }
}
char* AnimationManager::getDirectionName(Direction direction)
{
    switch(direction)
    {
        case JUMP:
            return "jump";
        case ATTACK:
            return "attack";
        case JUMPATTACK:
            return "jumpattack";
        case LEFT:
            return "left";
        case RIGHT:
            return "right";
        case MOVERLOOK:
            return "moverlook";
        case MATTACK:
            return "mattack";
        case OVERLOOK:
            return "overlook";
        case ATTACKED:
            return "attacked";
        case BOVERLOOK:
            return "boverlook";
        case BONE:
            return "bone";
        case BTWO:
            return "btwo";
        case BTHREE:
            return "bthree";
        case REMOVE:
            return "remove";
        case PORTALONE:
            return "portalone";
        case PORTALTWO:
            return "portaltwo";
        case CUBEONE:
            return "cubeone";
        case CUBETWO:
            return "cubetwo";
        case FIRESTAND:
            return "firestand";
        case FIRELEFT:
            return "fireleft";
        case FIRERIGHT:
            return "fireright";
        case ICERIGHT:
            return "iceright";
        case ICELEFT:
            return "iceleft";
        case ICESTAND:
            return "icestand";
        case FIREEXPODE:
            return "fireexpode";
        case SWORDRIGHT:
            return "swordright";
        case SWORDLEFT:
            return "swordleft";
        case SWORDSTAND:
            return "swordstand";
        case SWORDATTACK:
            return "swordattack";
        case WRIGHT:
            return "wright";
        case WLEFT:
            return "wleft";
        case WATTACK:
            return "wattack";
        case WREMOVE:
            return "wremove";
        case BOSSRIGHT:
            return "bossright";
        case BOSSLEFT:
            return "bossleft";
        case BOSSATTACK:
            return "bossattack";
        case BOSSATTACKONE:
            return "bossattackone";
        case BOSSATTACKTWO:
            return "bossattacktwo";
        case BOSSATTACKTHREE:
            return "bossattackthree";
        case BOSSREMOVE:
            return "bossremove";
        case BOSSSTAND:
            return "bossstand";
    }
}
int AnimationManager::getDirection( Direction direction )
{
    switch(direction)
    {
        case JUMP:
            return 36;/*35*/
        case ATTACK:
            return 14;
        case JUMPATTACK:
            return 24;
        case LEFT:
            return 2;
        case RIGHT:
            return 2;
        case MOVERLOOK:
            return 2;
        case MATTACK:
            return 6;
        case OVERLOOK:
            return 1;
        case ATTACKED:
            return 39;
        case BOVERLOOK:
            return 5;
        case BONE:
            return 4;
        case BTWO:
            return 2;
        case BTHREE:
            return 1;
        case REMOVE:
            return 11;
        case PORTALONE:
            return 0;
        case PORTALTWO:
            return 3;
        case CUBEONE:
            return 0;
        case CUBETWO:
            return 3;
        case FIRESTAND:
            return 52;
        case ICESTAND:
            return 56;
        case FIRELEFT:
            return 0;
        case FIRERIGHT:
            return 0;
        case ICERIGHT:
            return 0;
        case ICELEFT:
            return 0;
        case FIREEXPODE:
            return 4;
        case SWORDSTAND:
            return 0;
        case SWORDRIGHT:
            return 0;
        case SWORDLEFT:
            return 0;
        case SWORDATTACK:
            return 4;
        case WRIGHT:
            return 0;
        case WLEFT:
            return 0;
        case WATTACK:
            return 2;
        case WREMOVE:
            return 11;
        case BOSSRIGHT:
            return 4;
        case BOSSLEFT:
            return 4;
        case BOSSATTACK:
            return 8;
        case BOSSATTACKONE:
            return 10;
        case BOSSATTACKTWO:
            return 25;
        case BOSSATTACKTHREE:
            return 27;//27 13
        case BOSSREMOVE:
            return 52;
        case BOSSSTAND:
            return 0;
        //0-8 8-16 16-24 24-32
        //default:
            //return 0;
    }
}


然后在HelloWorld.cpp文件intit()函数中添加

AnimationManager::getInstance()->loadAnimation(heroAnimation,12);

接下来是HERO的实现

boy.h
#ifndef _BOY_H_
#define _BOY_H_
#include"Common\BoundingBox.h"
#include"cocos2d.h"
#include"DBgame.h"
#include"Core\typedefine.h"
using namespace cocos2d;
class Boy:public CCNode
{
public:
    Boy(void);
    ~Boy(void);
    //静态方法用于创建hero实例
    static Boy* player();
    void setAnimation(Direction dir,Behaviour be);
    void setAnimation(Direction dir,Behaviour be,float time);
    Direction getDirection(); 
    Behaviour getBehaviour();
    void attack();
    void attackDone();
    void executeAnimation(Direction dir,Behaviour be,int nextAni);
    void executeDone(CCNode* pSender,void* i);
    void attacked();
    void attackedDone();
    BoundingBox hitBox;
    BoundingBox attackBox;
    CCRect getRect();
    CCRect getCollisionRect(int width,int height);
    Behaviour behaviour;
    Direction direction;
    CCSprite* getHeroSprite();
protected:
    CCAnimate *getAnimate();
    CCSprite *sprite;
    float xVel;
    float yVel;
    CCPoint touchPoint;
    //CCAnimate *getAnimate(char* playName);
    bool init();
};
#endif//

boy.cpp的实现

#include"core\boy.h"//215
#include"DBgame.h"
#include"core\Animation.h"
using namespace cocos2d;
Boy::Boy()
{
    xVel=0;
    yVel=0;
}
Boy::~Boy()
{
}
Boy* Boy::player()
{
    Boy *player = new Boy();
    if (player && player->init())
    {
        player->autorelease();
        return player;
    }
    CC_SAFE_DELETE(player);
    return NULL;
}
bool Boy::init()
{
    bool bRet = false;
    do{
        this->setAnchorPoint(CCPointZero);
        //创建动画
        sprite=CCSprite::spriteWithSpriteFrameName("toto_0.png");
        sprite->setAnchorPoint(CCPointZero);
        this->addChild(sprite);
        //设置状态
        behaviour=STAND;
        direction=OVERLOOK;
        //
        //behaviour=MOVE;
        //direction=ATTACKED;
                                                           
        sprite->runAction(CCRepeatForever::actionWithAction(getAnimate()));
                                                           
        bRet=true;
    }while(0);
    return bRet;
}
CCSprite* Boy::getHeroSprite()
{
    return this->sprite;
}
void Boy::setAnimation(Direction dir,Behaviour be)
{
    direction=dir;
    behaviour=be;
    sprite->stopAllActions();
    sprite->runAction(CCRepeatForever::actionWithAction(getAnimate()));
}
void Boy::setAnimation(Direction dir,Behaviour be,float time)
{
    CCAction* action=CCSequence::actions(
        getAnimate(),
        CCDelayTime::actionWithDuration(0.001f),
        NULL);
    //运行动画
    sprite->runAction(action);
}
//注意,不同精灵,这个函数写法不同,主要区别都是OVERLOOK上,有些精灵是没有四方向的
CCAnimate * Boy::getAnimate()
{
    if (behaviour==DEAD)
    {
        direction=OVERLOOK;
    }
    return AnimationManager::getInstance()->getAnimate("toto",behaviour,direction);
}
Direction Boy::getDirection()
{
    return this->direction;
}
Behaviour Boy::getBehaviour()
{
    return this->behaviour;
}

枚举定义的代码

#ifndef _TYPEDEFINE_H
#define _TYPEDEFINE_H
typedef enum {
    UP,
    DOWN,
    JUMP,
    ATTACK,
    JUMPATTACK,
    LEFT,
    RIGHT,
    MOVERLOOK,
    MATTACK,
    OVERLOOK, //任何朝向都一样
    ATTACKED,
    BOVERLOOK,
    BONE,
    BTWO,
    BTHREE,
    REMOVE,
    PORTALONE,
    PORTALTWO,
    CUBEONE,
    CUBETWO,
    FIRERIGHT,
    FIRELEFT,
    FIRESTAND,
    ICERIGHT,
    ICELEFT,
    ICESTAND,
    FIREEXPODE,
    SWORDRIGHT,
    SWORDSTAND,
    SWORDLEFT,
    SWORDATTACK,
    WRIGHT,
    WLEFT,
    WATTACK,
    WREMOVE,
    BOSSRIGHT,
    BOSSLEFT,
    BOSSREMOVE,
    BOSSATTACK,
    BOSSATTACKONE,
    BOSSATTACKTWO,
    BOSSATTACKTHREE,
    BOSSSTAND
}  Direction;
typedef enum{
    STAND,
    MOVE,
    DEAD
} Behaviour;
typedef enum{
    GETFIRE,
    GETICE,
    GETSWORD,
    GETHAM,
    GETHP,
    NOSTAGE
}STAGE;
#endif;


HelloWord中init()函数添加以下代码

player=Boy::player();
player->getHeroSprite()->setPosition(ccp(100,10));
map->addChild(player,1);
sprite=player->getHeroSprite();

待续-------------------------------------------------------------------------------------


你可能感兴趣的:(动作游戏)