基于cocos2dx 3.0的卡牌游戏战斗环节探究一
2014-11-07 13:48
183 查看
卡牌游戏作为重度游戏的典型,其魅力就不用多说了,好了,让我们一起动手写一个简单的战斗环节的例子吧。
说明,为简单起见,只写了一个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);
};
说明,为简单起见,只写了一个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);
};
相关文章推荐
- 基于cocos2dx 3.0的卡牌游戏战斗环节探究二
- 基于Cocos2dx开发卡牌游戏Demo_放开那三国 2.0
- cocos2dx shader实现的简单滤镜 基于3.0版本
- Blue Path(基于cocos2dx 3.0)
- 基于Cocos2dx开发卡牌游戏_松开,这三个国家
- Blue Path(基于cocos2dx 3.0)
- 基于Cocos2dx开发卡牌游戏_松开,这三个国家
- 基于Cocos2dx 3.0beta2小游戏《砸鸡蛋》,仿韩国综艺
- 如何使用cocos2dx3.0制作基于tilemap的游戏:第一部分
- 基于Cocos2dx开发卡牌游戏Demo_放开那三国 2.0
- 如何使用cocos2dx3.0制作基于tilemap的游戏:第二部分
- 如何使用cocos2dx3.0制作基于tilemap的游戏:第三部分·完
- 基于Cocos2dx开发卡牌游戏_放开那三国
- cocos2dx 3D战斗类游戏制作:【三】——基于数据库的3D精灵动画2
- cocos2dx 3D战斗类游戏制作:【三】——基于数据库的3D精灵动画1
- Spring 3.0 基于 Annotation 的依赖注入实现
- cocos2dx 3.0 安装
- cocos2dx-3.0 移植android平台
- cocos2dx3.0中文乱码-随心
- Cocos2dx 3.0 正式版本开发环境搭建