基于cocos2dx 3.0的卡牌游戏战斗环节探究一

卡牌游戏作为重度游戏的典型,其魅力就不用多说了,好了,让我们一起动手写一个简单的战斗环节的例子吧。

说明,为简单起见,只写了一个1 vs 1的例子,也没有使用特效。


废话不说,上代码:

1、角色血量条的使用:

_blood=ProgressTimer::create(Sprite::create("bloodProgress.png"));

        _blood->setScale(_showWidth/_blood->getContentSize().width);

        _blood->setPosition(0,_showHeight/2+5);

        _blood->setMidpoint(Point(0,0.5));

        _blood->setType(ProgressTimer::Type::BAR);

        _blood->setPercentage(100);

     

        role里面既包括卡牌角色 _body,也使用ProgressTimer的_blood作为血量条显示,需要注意对战双方的setMidPoint()设置的减少方向最好不一样,美观。


2、重中之重,状态机FSM来了:

   

      (1)创建存放状态、进入状态时回调函数、回调函数对状态的签约等数据的存放,我们使用

std::unordered_map作为主要的容器:

Array *_status=Array::create();

std::unordered_map<std::string, std::function<void()>> _onEnters;

std::unordered_map<std::string, std::unordered_map<std::string,std::string>> _events;

(2)数据初始化

Array *_status, _events可以在FSM类里面直接加载:

fsm->_status->addObject(String::createWithFormat("idle"));

    fsm->_status->addObject(String::createWithFormat("walk"));

    fsm->_status->addObject(String::createWithFormat("attack"));

    fsm->_status->addObject(String::createWithFormat("beHit"));

    fsm->_status->addObject(String::createWithFormat("dead"));

    

    fsm->addEvents("doWalk","idle","walk");

    fsm->addEvents("doAttack","walk","attack");

    fsm->addEvents("doBeHit","attack","beHit");

    fsm->addEvents("doAttack","beHit","attack");

    fsm->addEvents("doAttack","attack","attack");

    fsm->addEvents("doDead","attack","dead");

    fsm->addEvents("doDead","beHit","dead");

那么问题来了,当然不是挖掘机, _onEnters容器因为存放的更多是Role类的动作,因此把这个容器的初始化交给Role类吧。

//intial _onEnters

    _fsm->_onEnters.insert(std::pair<std::string,std::function<void()>>(String::createWithFormat("idle")->getCString(), onIdle));

    _fsm->_onEnters.insert(std::pair<std::string,std::function<void()>>(String::createWithFormat("walk")->getCString(), onWalk));

    _fsm->_onEnters.insert(std::pair<std::string,std::function<void()>>(String::createWithFormat("attack")->getCString(), onAttack));

    _fsm->_onEnters.insert(std::pair<std::string,std::function<void()>>(String::createWithFormat("beHit")->getCString(), onBeHit));

    _fsm->_onEnters.insert(std::pair<std::string,std::function<void()>>(String::createWithFormat("dead")->getCString(), onDead));


(3)每个状态的对应的动作,

    auto onIdle=[&](){log("i am idle");};

    

    

    auto onWalk=[&](){

        

        log("i am walk");

        auto moveTo=MoveTo::create(8, _tagetPoint);

        this->runAction(moveTo);

        

    };

    

    

    auto onAttack=[&](){

        log("i am attack");

        

        if(_health>0){

            

            this->stopAllActions();

            

            if(_relation==good){

                this->schedule(schedule_selector(Role::attackFromPlayer),2);

            }

            else{

                this->schedule(schedule_selector(Role::attackFromMonster),3);}

            

        }else{

            //this->unscheduleAllSelectors();

            if(_fsm->getStatus()=="dead"){

                

                

            }else{

                

                _fsm->doEvent("doDead");


            }

                    }

       

       

     };

    

    

    auto onBeHit=[&](){

        log("i am beHit");

        //this->stopAllActions();

        if(_health>0){

            

                auto moveLeft=MoveBy::create(0.1, Point(-20,0));

                auto moveRight=MoveBy::create(0.1, Point(20,0));

                auto onBeHitCall=CallFunc::create([&](){

                _health=_health-400;

                _blood->setPercentage((_health/1000)*100);

                    

                    if(_health>0){

                        

                        this->_fsm->doEvent("doAttack");

                        

                    }else{

                        

                        log("signa, h1");

                        _fsm->doEvent("doDead");

                    }

                    

                

            });

            auto delay=DelayTime::create(2);

            

            if(_relation!=good){

                

                auto seq=Sequence::create(moveRight,moveLeft,onBeHitCall,NULL);

                

                this->runAction(seq);

                //this->_fsm->doEvent("doAttack");

                

            }else{

                

                auto seq=Sequence::create(moveLeft,moveRight,onBeHitCall,NULL);

                this->runAction(seq);

            }

            

        }

            

        else{

            log("%f",_health);

        

        }

};

    

    

    auto onDead=[&](){

        this->unscheduleAllSelectors();

        this->stopAllActions();

        log("i am dead");

        CCNotificationCenter::sharedNotificationCenter()->postNotification("someone is killed", NULL);

    };


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值