温馨提示×

温馨提示×

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

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

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

发布时间:2020-04-09 07:23:50 来源:网络 阅读:1786 作者:lonag 栏目:游戏开发

     这个实例基于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 BO×××IGHT:
            return "bo***ight";
        case BOSSLEFT:
            return "bossleft";
        case BOSSATTACK:
            return "bossattack";
        case BOSSATTACKONE:
            return "bossattackone";
        case BOSSATTACKTWO:
            return "bossattacktwo";
        case BOSSATTACKTHREE:
            return "bossattackthree";
        case BO×××EMOVE:
            return "bo***emove";
        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 BO×××IGHT:
            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 BO×××EMOVE:
            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,
    BO×××IGHT,
    BOSSLEFT,
    BO×××EMOVE,
    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();

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


向AI问一下细节

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

AI