Cocos3.4 横版游戏制作-《KillBear》-加入Hero

来源:互联网 发布:地府淘宝商 编辑:程序博客网 时间:2024/06/07 01:25

转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。
资源为网上寻找的,仅研究学习用,若是侵犯版权请通知本人整改。


上一篇:Cocos3.4 横版游戏制作-《KillBear》-添加地图
在这一篇中,我们实现生成一个基础的Role类,Hero继承Role类创建.(我们敌人Enemy也会继承这个类)
最后把它放在我们的GameLayer中


开发环境


  • win64 : vs2010
  • Cocos2d-x v3.4Final
  • TexturePackerGUI
  • MapEdit

代码构建

角色Role

基础类Role

这是基础类,所有的角色都继承他.
受限篇幅,下面代码贴出一部分看注释吧

  • .h
typedef struct _BoundingBox{    Rect actual;    Rect original;}BoundingBox;typedef enum {    ACTION_STATE_NONE = 0,    ACTION_STATE_IDLE,    ACTION_STATE_WALK,    ...    ACTION_STATE_DEAD}ActionState;//基础角色类,主角和NPC都需要继承它//单纯的控制播放动画,何时播放它在具体的类里面设置class Role :public Sprite{public:    Role(void);    ~Role(void);    /* 角色状态设定,初始化角色状态等 */    CC_SYNTHESIZE(std::string,Name,Name);                           //角色名称    CC_SYNTHESIZE(float,curtLifevalue,CurtLifeValue);               //角色当前生命值    ...    /* 需要用creatNomalAnimation创建,只有普通动画,有受伤判定,无攻击判定 */    CC_SYNTHESIZE_RETAIN(Action*, m_pidleaction, IdleAction);       //角色空闲时序列    CC_SYNTHESIZE_RETAIN(Action*, m_pwalkaction, WalkAction);       //角色移动时动画帧序列    ...    void Role::callBackAction(Node* pSender);                       //动画执行完毕的通用回调处理    /*  下面是所有的动画回调函数,用来执行此动画,   */    virtual void runIdleAction();                               //执行闲置动画    virtual void runWalkAction();                               //执行移动行走动画    ...    BoundingBox createBoundingBox(Vec2 origin,Size size);    CC_SYNTHESIZE(BoundingBox, m_bodyBox, BodyBox);             //身体碰撞盒子    CC_SYNTHESIZE(BoundingBox, m_hitBox, HitBox);               //攻击碰撞盒子    virtual void setPosition(const Vec2 &position);    void updateBoxes();protected:    static Animation* createNomalAnimation(const char* formatStr, int frameCount, int fps);    static Animation* createAttackAnimation(const char* formatStr, int frameCountBegan, int frameCountEnd,int fps);private:    bool changeState(ActionState actionState);    ActionState proActionState;

CC_SYNTHESIZE(float,curtLifevalue,CurtLifeValue);宏定义
我们可以通过target->getCurtLifeValue()获得target的curtLifevalue,也可以通过set改变curtLifevalue的值.curtLifevalue是Role内部的一个私有成员.
其他宏功能类似

  • .cpp
//各种动作void Role::runIdleAction(){   //通过changeState判断是否可以变更状态,之后执行动作    if(changeState(ACTION_STATE_IDLE))    {        this->runAction(m_pidleaction);    }}    ...Animation* Role::createAttackAnimation(const char* formatStr, int frameCountBegan, int frameCountEnd,int fps){    //通过frameCountBegan,frameCountEnd从SpriteFrameCache中创建一个动作    Vector<SpriteFrame*> pFrames;     for(int i = frameCountBegan; i < frameCountEnd; i++ )    {        const char* imgName = String::createWithFormat(formatStr, i)->getCString();        SpriteFrame *pFrame = SpriteFrameCache::getInstance()->getSpriteFrameByName(imgName);        pFrames.insert(i-frameCountBegan,pFrame);    }    return Animation::createWithSpriteFrames(pFrames, 1.0f / fps);}    ...bool Role::changeState(ActionState actionState){    //允许改变状态,死了和状态不变不会在接受其他状态改变指令    if(currActionState == ACTION_STATE_DEAD || currActionState == actionState)    {        return false;    }    this->stopAllActions();    this->currActionState = actionState;    return true;}    ...BoundingBox Role::createBoundingBox(Vec2 origin, Size size){    //创建一个BoundingBox,用于设置身体碰撞和攻击碰撞检测    BoundingBox boundingBox;    boundingBox.original.origin= origin;    boundingBox.original.size= size;    boundingBox.actual.origin = this->getPosition() + boundingBox.original.origin;    boundingBox.actual.size= size;    return boundingBox;}void Role::updateBoxes(){    //通过方向刷行盒子位置    bool isFlippedX = this->isFlippedX();    float x = 0.0f;    if(isFlippedX)     {        x = this->getPosition().x - m_hitBox.original.origin.x;    }else     {        x = this->getPosition().x + m_hitBox.original.origin.x;    }    m_hitBox.actual.origin = Vec2(x, this->getPosition().y + m_hitBox.original.origin.y);    m_bodyBox.actual.origin = this->getPosition() + m_bodyBox.original.origin;}void Role::setPosition(const Vec2 &position){    //每次重新设定坐标的时候刷新盒子    Sprite::setPosition(position);    this->updateBoxes();}

英雄Hero

主角类
还是比较长的,关注下注释,.h只有一个init没啥好说的

  • .cpp
        this->initWithSpriteFrameName("boy_idle_00.png");        //站立时播放动画        Animation *idleAnim = this->createNomalAnimation("boy_idle_%02d.png", 3, 5);        this->setIdleAction(RepeatForever::create(Animate::create(idleAnim)));        ...        //普通攻击A,分出招和收招,期间夹杂攻击判定.自己可以通过调节fps控制出招速度之类的        Animation *attackAnima1 = this->createAttackAnimation("boy_attack_00_%02d.png", 0, 4, 10);        Animation *attackAnima2 = this->createAttackAnimation("boy_attack_00_%02d.png", 4, 8, 15);        this->setNomalAttackA(Sequence::create(            Animate::create(attackAnima1),             //CallFuncN::create(CC_CALLBACK_1(Hero::attackCallBackAction,this)),            Animate::create(attackAnima2),            Role::createIdleCallbackFunc(),            NULL));        ...        //碰撞盒子设定        this->m_bodyBox = this->createBoundingBox(Vec2(0,30), Size(30,60));        this->m_hitBox = this->createBoundingBox(Vec2(35,50), Size(80, 90));

游戏Game

GameLayer

  • cpp

init中

this->addHero();

实现方法是

void GameLayer::addHero(){    m_pHero = Hero::create();    m_pHero->setPosition(_visibleOrigin + Vec2(100, 50));    m_pHero->runIdleAction();    m_pHero->setLocalZOrder(_visibleSize.height - m_pHero->getPositionY());    this->addChild(m_pHero);}

效果

至此我们的第二步已经完成了,运行下可以看到一个窗口中我们的英雄站在那里(帧数不同是录制问题.):
这里写图片描述

结语

基础Role一次性构建完,之后调用就可以了.后续通过其他理解BoundingBox
下一篇,实现摇杆的添加和Hero的控制

0 0