这篇文章主要围绕火云开发课堂-《使用Cocos2d-x开发3D游戏》系列第二十四节:小项目实训《绝命沙滩》展开,旨在为您提供一份详细的参考资料。我们将全面介绍火云开发课堂-《使用Cocos2d-x开发
这篇文章主要围绕火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第二十四节:小项目实训《绝命沙滩》展开,旨在为您提供一份详细的参考资料。我们将全面介绍火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第二十四节:小项目实训《绝命沙滩》,同时也会为您带来Cocos2d-x 3.2 大富翁游戏项目开发-第二十三部分 购买彩票、Cocos2d-x 3.2 大富翁游戏项目开发-第二十九部分 游戏配音、Cocos2d-x 3.2 大富翁游戏项目开发-第二十八部分 游戏保存和载入存档游戏、Cocos2d-x 3.2 大富翁游戏项目开发-第二十四部分 彩票开奖的实用方法。
本文目录一览:- 火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第二十四节:小项目实训《绝命沙滩》
- Cocos2d-x 3.2 大富翁游戏项目开发-第二十三部分 购买彩票
- Cocos2d-x 3.2 大富翁游戏项目开发-第二十九部分 游戏配音
- Cocos2d-x 3.2 大富翁游戏项目开发-第二十八部分 游戏保存和载入存档游戏
- Cocos2d-x 3.2 大富翁游戏项目开发-第二十四部分 彩票开奖
火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第二十四节:小项目实训《绝命沙滩》
《使用Cocos2d-x 开发3D游戏》系列在线课程
第二十四节:小项目实训《绝命沙滩》
视频地址:http://edu.csdn.net/course/detail/1330/20824?auto_start=1
交流论坛:http://www.firestonegames.com/bbs/forum.php
工程下载地址:请成为正式学员获取工程
课程截图:
Cocos2d-x 3.2 大富翁游戏项目开发-第二十三部分 购买彩票
当角色路过彩票的标志或者停留位置有彩票标志时,弹出购买彩票的对话框,提示购买彩票,已经买过的号码,不显示。当机器对手路过时则直接购买彩票。
1、
在RicherPlayer.h中增加std::vector<int> lottery_vector;用来存储购买的彩票号码
2、
RicherGameController 修改endGo方法,每走完一步就会进入该方法,判断是否有彩票标示图标,有的话发送MSG_LottERY彩票消息,MOVEPASS标示走完一步的标志
void RicherGameController::endGo() { ................... Size titleSize = GameBaseScene::wayLayer->getLayerSize(); int passId = GameBaseScene::wayLayer->getTileGIDAt(Point(currentCol,titleSize.height-currentRow-1)); if(passId == GameBaseScene::lottery_tiledID) { String * str = String::createWithFormat("%d-%f-%f-%d-%d",MSG_LottERY_TAG,1.0f,_richerPlayer->getTag(),MOVEPASS); NotificationCenter::getInstance()->postNotification(MSG_LottERY,str); return; } .............. }
3、
角色行走完毕后,判断停留地点是否有彩票标志,有的话发送MSG_LottERY彩票消息,GOEND标示行走完毕的标志
void RicherGameController::handlePropEvent() { ............... if(endId == GameBaseScene::lottery_tiledID) { String * str = String::createWithFormat("%d-%f-%f-%d-%d",pointInMap.x,pointInMap.y,GOEND); NotificationCenter::getInstance()->postNotification(MSG_LottERY,str); return; } ............... }
4、新建彩票号码类LotteryCard ,该类里面的按键是菜单按钮
void LotteryCard::cardInit(int numbers,int width,int height,float CardSpriteX,float CardSpriteY) { //设置初始化值 lotteryNumber = numbers; //背景颜色 layerColorBG = LayerColor::create(Color4B(100,100,255),width-5,height-5); layerColorBG->setPosition(Point(CardSpriteX,CardSpriteY)); if(lotteryNumber > 0) { //创建menuitem,设置其tag为彩票的号码 ballMenuImage = MenuItemImage::create("images/lt_defalut_ball.png","images/lt_blueball.png",this,menu_selector(LotteryCard::ballButtonCallback)); ballMenuImage->setTag(lotteryNumber); ballMenuImage->setPosition(Point(layerColorBG->getContentSize().width/2,layerColorBG->getContentSize().height/2)); // 添加文字说明并设置位置 labelLotteryNumber = LabelTTF::create(String::createWithFormat("%i",lotteryNumber)->getCString(),"HiraKakuProN-W6",25); labelLotteryNumber->setColor(Color3B(200,200,200)); labelLotteryNumber->setPosition(Point(layerColorBG->getContentSize().width/2,layerColorBG->getContentSize().height/2)); ballMenuImage->addChild(labelLotteryNumber); //创建menu,添加menuitem Menu* menu = Menu::create(); menu->setPosition(CCPointZero); layerColorBG->addChild(menu); menu->addChild(ballMenuImage); //该彩票sprite的tag也是彩票号码 this->setTag(lotteryNumber); } this->addChild(layerColorBG); } //调用彩票菜单按键的回调函数 void LotteryCard::ballButtonCallback(CCObject* pSender) { Node* node = dynamic_cast<Node*>(pSender); ballMenuImage->selected(); if (m_callback && m_callbackListener) { (m_callbackListener->*m_callback)(node); } } //设置菜单为不选中状态 void LotteryCard::setUnSelected() { ballMenuImage->unselected(); } //设置彩票菜单按键的回调函数 void LotteryCard::setBallCallbackFunc(cocos2d::Object *target,SEL_CallFuncN callfun) { m_callbackListener = target; m_callback = callfun; } //返回彩票号码 int LotteryCard::getLotteryNumber() { return lotteryNumber; } //设置彩票号码 void LotteryCard::setLotteryNumber(int num) { lotteryNumber = num; if(lotteryNumber > 0) { labelLotteryNumber->setString(String::createWithFormat("%i",lotteryNumber)->getCString()); } }
5、修改PopupLayer类,添加彩票布局
在PopupLayer.h头文件中添加对话框类型枚举 enum POP_TYPE { norMAL,//普通对话框 LottERY,//彩票对话框 STOCK,//留作后面的股票对话框 }; void setLotteryContext(Size size); //设置彩票号码布局内容 POP_TYPE pop_type; //当前对话框类型 void setPopType(POP_TYPE type); //设置当前对话框类型 Vector<LotteryCard*> lotteryVector; //所有彩票号码容器 void refreshBallBackGround(Node *pNode); //点击一个彩票号码后,更新其他彩票背景为不选中 int lottery_selected; //选中的彩票号码 std::vector<int> selected_number_vector; //已选择的彩票号码容器 void setHasSelectedLotteryNumber(std::vector<int> _vector); //设置已经选择的彩票号码 看具体的实现 bool PopupLayer::init() { ......... lottery_selected = 0;//初始化时,没有选中的号码 .......... } void PopupLayer::onEnter() { ............ switch(pop_type) { case LottERY: { //如果对话框是彩票类型,则添加彩票布局 setLotteryContext(contentSize); break; } case STOCK: { break; } default: { // 此处表示普通对话框,则只显示文本内容 if (getLabelContentText()) { LabelTTF* ltf = getLabelContentText(); ltf->setPosition(ccp(winSize.width / 2,winSize.height / 2)); ltf->setDimensions(CCSizeMake(contentSize.width - m_contentPadding * 2,contentSize.height - m_contentPaddingTop)); ltf->setHorizontalAlignment(kCCTextAlignmentLeft); ltf->setColor(ccc3(0,0)); this->addChild(ltf); } } } ............ } //设置彩票号码布局内容 void PopupLayer::setLotteryContext(Size size) { Size winSize = Director::getInstance()->getWinSize(); Size center =(winSize - size)/2; //彩票布局行列为 10 X 3 for(int row=0; row<10; row++) { for(int col=0; col<3; coL++) { //创建彩票号码 LotteryCard* card = LotteryCard::createCardSprite((row+1)+ col*10,40,center.width+20+row*(size.width/11),(winSize.height/2+30)-40*col); //设置彩票的tag为彩票号码 card->setTag((row+1)+ col*10); //注册彩票点击回调函数refreshBallBackGround() card->setBallCallbackFunc(this,callfuncN_selector(PopupLayer::refreshBallBackGround)); addChild(card); //号码放到彩票容器中 lotteryVector.pushBack(card); //遍历已经选择过的彩票容器,把已经选过的置为不可见 for(int i=0;i<selected_number_vector.size();i++) { if(selected_number_vector.at(i) == (row+1)+ col*10) { card->setVisible(false); } } } } } //把选择的号码,放入已经选择过的彩票容器。参数_vector是表示已经选择过的,由角色调用时把角色自带的lottery_vector传来 void PopupLayer::setHasSelectedLotteryNumber(std::vector<int> _vector) { for(int i=0;i<_vector.size();i++) { selected_number_vector.push_back(_vector.at(i)); } } //更新号码背景,并把选中的号码做为tag传给购买按钮,由购买按键回传给主场景 void PopupLayer::refreshBallBackGround(Node *pNode) { int tag2= pNode->getTag(); for(auto it=lotteryVector.begin();it!=lotteryVector.end();it++) { LotteryCard* node = (LotteryCard*)(*it); int tag1= node->getTag(); if(node->getTag() != pNode->getTag()) { node->setUnSelected(); } } lottery_selected = tag2; Vector<Node*> menuItemVector = getMenuButton()->getChildren(); for(int i=0;i< getMenuButton()->getChildrenCount();i++) { if(menuItemVector.at(i)->getTag() != 0) { menuItemVector.at(i)->setTag(tag2); break; } } }
6、回到游戏主场景,看看是怎么显示出彩票对话框的
/注册彩票消息的观察者 void GameBaseScene::registerNotificationObserver() { ............. NotificationCenter::getInstance()->addobserver( this,callfuncO_selector(GameBaseScene::receivednotificationOMsg),MSG_LottERY,NULL); } //彩票消息处理 void GameBaseScene::receivednotificationOMsg(Object* data) { .............. case MSG_LottERY_TAG: { int playerTag = messageVector.at(3)->intValue(); moveTag = messageVector.at(4)->intValue(); switch(playerTag) { case PLAYER_1_TAG: { //如果是第一角色,创建对话框,设置类型为彩票类型 PopupLayer* popDialogLottery = PopupLayer::create(DIALOG_BG); popDialogLottery->setContentSize(CCSizeMake(Dialog_Size_Width,Dialog_Size_Height)); popDialogLottery->setTitle(LanguageString::getInstance()->getLanguageString(SELECT_LottERY_TITLE)->getCString()); popDialogLottery->setContentText("",20,60,250); popDialogLottery->setPopType(LottERY); //添加回调函数lotteryButtonCallback,当点击购买或取消将调用该方法 popDialogLottery->setCallbackFunc(this,callfuncN_selector(GameBaseScene::lotteryButtonCallback)); //把角色已经买过的号码传给对话框,让其不可见 popDialogLottery->setHasSelectedLotteryNumber(player1->lottery_vector); //添加2个按键,购买 取消 popDialogLottery->addButton(BUTTON_BG1,BUTTON_BG3,LanguageString::getInstance()->getLanguageString(BUY_OK)->getCString(),Btn_OK_TAG); popDialogLottery->addButton(BUTTON_BG2,LanguageString::getInstance()->getLanguageString(CANCEL)->getCString(),Btn_Cancel_TAG); this->addChild(popDialogLottery); break; } case PLAYER_2_TAG: { //如果是角色2,则随机购买彩票,不弹出对话框 int random_lottery_number = rand()%(30) + 1; repeatForCheck: for(int i=0;i<player2->lottery_vector.size();i++) { if(player2->lottery_vector.at(i) == random_lottery_number) { random_lottery_number = rand()%(30) + 1; goto repeatForCheck; } } //把购买后的彩票放到角色彩票容器中 player2->lottery_vector.push_back(random_lottery_number); //更新角色资金 refreshMoneyLabel(player2,-BUY_LottERY_MONEY); //如果是角色行走完毕,停留位置有彩票标志导致发送的彩票消息,则购买彩票完毕后,需要发送处理角色上下左右相邻地块的消息 if(moveTag == GOEND) { CocosToast::createtoast(this,String::createWithFormat("%s %d",LanguageString::getInstance()->getLanguageString(BUY_LottERY)->getCString(),BUY_LottERY_MONEY)->getCString(),TOAST_SHOW_TIME,player2->getPosition(),(SEL_CallFun)&GameBaseScene::sendMSGDealAroundLand2); } //如果是走完一步,就是路过彩票标示发送的彩票消息,则发送行走下一步的消息,继续走下一步 else if(moveTag == MOVEPASS) { CocosToast::createtoast(this,(SEL_CallFun)&GameBaseScene::sendMSGMoveOnestep); } break; } } break; } } //发送走下一步的消息 void GameBaseScene::sendMSGMoveOnestep() { NotificationCenter::getInstance()->postNotification(MSG_MOVE_ONE_STEP,String::createWithFormat("%d",MSG_MOVE_ONE_STEP_TAG)); } //对话框购买或取消按键点击后的回调函数 void GameBaseScene::lotteryButtonCallback(Node *pNode) { //如果点击的是购买按键 if(pNode->getTag() != -1 && pNode->getTag() != Btn_Cancel_TAG) { //更新角色1的彩票容器 player1->lottery_vector.push_back(pNode->getTag()); //更新资金 refreshMoneyLabel(player1,-BUY_LottERY_MONEY); //如果是角色行走完毕,停留位置有彩票标志导致发送的彩票消息,则购买彩票完毕后,需要发送处理角色上下左右相邻地块的消息 if(moveTag == GOEND) { CocosToast::createtoast(this,player1->getPosition(),(SEL_CallFun)&GameBaseScene::sendMSGDealAroundLand2); }else if(moveTag == MOVEPASS)//如果是走完一步,就是路过彩票标示发送的彩票消息,则发送行走下一步的消息,继续走下一步 { CocosToast::createtoast(this,(SEL_CallFun)&GameBaseScene::sendMSGMoveOnestep); } pNode->getParent()->getParent()->removeFromParent(); } else //处理取消按键 { pNode->getParent()->getParent()->removeFromParent(); if(moveTag == GOEND) { sendMSGDealAroundLand2(); }else if(moveTag == MOVEPASS) { sendMSGMoveOnestep(); } } }
7、
在控制器中注册走下一步的观察者
void RicherGameController::registerNotificationObserver() { ..... NotificationCenter::getInstance()->addobserver( this,callfuncO_selector(RicherGameController::receivedMsg),MSG_MOVE_ONE_STEP,NULL); } //收到走一不的消息后,调用moveOnestep ,继续下一步的行走,至此购买彩票事件处理完毕 void RicherGameController::receivedMsg(Object* data) { .............. if(retMsgType == MSG_MOVE_ONE_STEP_TAG) { moveOnestep(_richerPlayer); } }
点击下载代码
未完待续........................
Cocos2d-x 3.2 大富翁游戏项目开发-第二十九部分 游戏配音
我从大富翁里提取出来里面的wav音效文件,放到我们的游戏中以增加趣味性,仅供学习研究之用
1、修改AppDelegate.cpp文件
// This function will be called when the app is inactive. When comes a phone call,it's be invoked too void AppDelegate::applicationDidEnterBackground() { Director::getInstance()->stopAnimation(); // if you use SimpleAudioEngine,it must be pause //后台暂停 SimpleAudioEngine::getInstance()->pauseBackgroundMusic(); } // this function will be called when the app is active again void AppDelegate::applicationWillEnterForeground() { Director::getInstance()->startAnimation(); // if you use SimpleAudioEngine,it must resume here //恢复播放 SimpleAudioEngine::getInstance()->resumeBackgroundMusic(); }
2、在resources 目录下新建sound文件夹,存放游戏声音文件
角色的声音文件定义到ConstUtil.h文件中,大体如下:
#define P1_DEYIDEYITIAN "sound/byelottery.wav"//拜拜 祝您中奖 #define P1_need1000 "sound/need1000.wav"//只要1000元 #define P1_select_lottery "sound/select_lottery.wav"//请圈选你要购买的彩票 #define P1_meirendejiang "sound/meirendejiang.wav"//sorry 本月份没有人得奖 #define P1_xiwangshini "sound/xiwangshini.wav"//希望下次得奖者就是您 #define P1_Speaking_00181 "sound/Speaking_00181.wav"//投资获利 #define P1_Speaking_00182 "sound/Speaking_00182.wav"//投资失败
角色相关声音大体依据如下内容进行分类定义:
//交过路费声音
//抢夺别人地块
//房屋被抢夺
//房屋被摧毁
//摧毁别人房屋
//螃蟹伤人
//看到别人住院
//收取过路费
//升级房子
//不交过路费
//买地
//捡到珍珠
//对方被罚收税
例如:角色1的文件定义
//交过路费声音 #define P1_Speaking_00435 "sound/Speaking_00435.wav"//oh 哈利路亚 #define P1_Speaking_00461 "sound/Speaking_00461.wav"//oh 我的血汗钱 #define P1_Speaking_00475 "sound/Speaking_00475.wav"//算了算了 老子有的是钱 #define P1_Speaking_01060 "sound/Speaking_01060.wav"//老本都快没了 #define P1_Speaking_001062 "sound/Speaking_001062.wav"//拿去了不用找了 //抢夺别人地块 #define P1_Speaking_00429 "sound/Speaking_00429.wav"//让我把他据为己有 //房屋被抢夺 #define P1_Speaking_00430 "sound/Speaking_00430.wav"//黄金地段 让给你 #define P1_Speaking_00464 "sound/Speaking_00464.wav"//太不给面子了 #define P1_Speaking_00469 "sound/Speaking_00469.wav"//你皮子痒啊 #define P1_Speaking_00470 "sound/Speaking_00470.wav"//竟敢在太岁头上动土 #define P1_Speaking_00476 "sound/Speaking_00476.wav"//算你狠 //房屋被摧毁 #define P1_Speaking_00462 "sound/Speaking_00462.wav"//好大的胆子 #define P1_Speaking_00463 "sound/Speaking_00463.wav"//谁敢动我的地 #define P1_Speaking_00466 "sound/Speaking_00466.wav"//竟敢破坏我的好事 #define P1_Speaking_00468 "sound/Speaking_00468.wav"//拆的还真干净 #define P1_Speaking_00474 "sound/Speaking_00474.wav"//你有没有搞错啊 #define P1_Speaking_001061 "sound/Speaking_001061.wav"//真没良心 //摧毁别人房屋 #define P1_Speaking_00433 "sound/Speaking_00433.wav"//不必谢我 #define P1_Speaking_00437 "sound/Speaking_00437.wav"//全部夷为平地 //螃蟹伤人 #define P1_Speaking_00449 "sound/Speaking_00449.wav"//快来帮我把 #define P1_Speaking_01054 "sound/Speaking_01054.wav"//我惨了 #define P1_Speaking_01055 "sound/Speaking_01055.wav"//哎呦喂啊 #define P1_Speaking_001071 "sound/Speaking_001071.wav"//我不要打针 //看到别人住院 #define P1_Speaking_001073 "sound/Speaking_001073.wav"//别闹了 //收取过路费 #define P1_Speaking_00453 "sound/Speaking_00453.wav"//小本经营 概不赊欠 #define P1_Speaking_01059 "sound/Speaking_01059.wav"//蝇头小利 #define P1_Speaking_01057 "sound/Speaking_01057.wav"//这是我应得的 //升级房子 #define P1_Speaking_01051 "sound/Speaking_01051.wav"//别嫉妒我 #define P1_Speaking_001066 "sound/Speaking_001066.wav"//我真佩服自己 //不交过路费 #define P1_Speaking_00446 "sound/Speaking_00446.wav"//有钱也不给你 #define P1_Speaking_00477 "sound/Speaking_00477.wav"//可别想占我便宜啊 //买地 #define P1_Speaking_00458 "sound/Speaking_00458.wav"//盖什么好呢 #define P1_Speaking_001067 "sound/Speaking_001067.wav"//我是个大地主 //捡到珍珠 #define P1_Speaking_01052 "sound/Speaking_01052.wav"//鸿运当头 #define P1_Speaking_001063 "sound/Speaking_001063.wav"//上帝保佑 //对方被罚收税 #define P1_Speaking_00452 "sound/Speaking_00452.wav"//别想偷漏税
3、
根据声音的分类把文件名称放入到Vector中,然后根据场景随机从Vector中取出声音进行播放。
在GameBaseScene.cpp的initAudioEffect方法中,据声音的分类把文件名称放入到Vector中
void GameBaseScene::initAudioEffect() { ......... player2EffectVec_1.pushBack(String::create(P2_SPEAKING01)); player2EffectVec_1.pushBack(String::create(P2_QISIWOLE)); player2EffectVec_1.pushBack(String::create(P2_XINHAOKONGA)); player2EffectVec_1.pushBack(String::create(P2_BUHUIBA)); player2EffectVec_1.pushBack(String::create(P2_PAYHIGH)); player2EffectVec_1.pushBack(String::create(P2_QIANGQIANA)); player2EffectVec_1.pushBack(String::create(P2_HEBAOCHUXIE)); .......... }在Util.cpp中定义声音播放方法,根据声音开关设置,进行声音的播放
void Util::playAudioEffect(const char* effectName,bool isLoop) { bool music_on = UserDefault::getInstance()->getBoolForKey(MUSIC_ON_KEY,true); if(music_on) { CocosDenshion::SimpleAudioEngine::getInstance()->playEffect(effectName,isLoop); } }
//随机从Vector中取出声音进行播放
void Util::playAudioEffectRandom(Vector<String*> effectVec,bool isLoop) { playAudioEffect(effectVec.at(rand() % effectVec.size())->getCString(),isLoop); } void Util::stopAudioPlay() { CocosDenshion::SimpleAudioEngine::getInstance()->stopBackgroundMusic(); CocosDenshion::SimpleAudioEngine::getInstance()->stopAllEffects(); }
4、添加背景音乐,共3首背景音乐,随机播放
void GameBaseScene::initAudioEffect() { bgMusicVector.push_back(BG01_MP3); bgMusicVector.push_back(BG02_MP3); bgMusicVector.push_back(BG03_MP3); for (int i = 0; i<bgMusicVector.size(); i++) { CocosDenshion::SimpleAudioEngine::getInstance()->preloadBackgroundMusic(bgMusicVector.at(i)); } this->schedule(schedule_selector(GameBaseScene::playerBgMusic),5.0f); ..... }
5、角色对话相关的音效,就是根据具体场景,添加相应的音效播放就可以了
关于音乐音效的比较简单,可以参考 http://cn.cocos2d-x.org/tutorial/show?id=2448
这篇文章http://cn.cocos2d-x.org/tutorial/show?id=2352 ,里面的转盘界面效果做得挺好,稍微修改一下,拿到我们大富翁中来吧。
代码同下一节一并发布.
Cocos2d-x 3.2 大富翁游戏项目开发-第二十八部分 游戏保存和载入存档游戏
1、游戏保存如图,在右下角增加保存图标,点击后进行游戏的保存。
游戏保存采用json格式,具体如下: { "map_level":2,// 游戏关卡 "gameRoundCount":66,// 游戏回合数 "players":[ //角色信息 { "playerTag":1,//角色1 "playerPosition_x":320,//角色所处的x坐标 "playerPosition_y":192,//角色所处的y坐标 "restTimes":3,//角色休息回合数 "stop_x":0,//角色停留的x坐标 "stop_y":0,//角色停留的y坐标 "money":509000,//角色资金 "strength":100,//角色体力 "comeFromeRow":4,//角色从上一个位置的行 "comeFromCol":10,//角色从上一个位置的列 "isMyTurn":false,//角色是否该行走 "skill":"1-2-2",//角色技能等级 "lottery":"",//角色购买的彩票号码 "stocks":[ //角色持有的股票信息 {"stockCode":800100,"makedealprice":10,"storeNumber":100},{"stockCode":800200,"makedealprice":0,"storeNumber":0},{"stockCode":800300,{"stockCode":800400,"storeNumber":400},{"stockCode":800500,"storeNumber":0} ] },{ "playerTag":2,//角色2的保存信息,同上 "playerPosition_x":423.635,"playerPosition_y":96,"restTimes":0,"stop_x":10,"stop_y":13,"money":410300,"strength":80,"comeFromeRow":2,"comeFromCol":15,"isMyTurn":false,"skill":"3-2-1","lottery":"","stocks":[ {"stockCode":800100,"makedealprice":20,"storeNumber":200},"storeNumber":0} ] } ],"landlayer":[ //地块的信息,在x行,y列 地块的gid值 {"x":5,"y":7,"gid":12},{"x":5,"y":12,{"x":6,"y":9,"y":10,"gid":11},{"x":7,"gid":1},"y":13,{"x":8,"y":11,{"x":9,"y":8,{"x":10,"y":6,{"x":11,"gid":13},"gid":15},{"x":12,"gid":14},{"x":13,{"x":14,"gid":10},{"x":15,{"x":16,{"x":17,"gid":10} ] }
//在添加go按钮的方法中同时添加保存按钮 void GameBaseScene::addGoButton() { ...... saveMenuItemButton = MenuItemImage::create("map/save_normal.png","map/save_pressed.png",this,menu_selector(GameBaseScene::goButtonCallback)); saveMenuItemButton->setPosition(ccp(winSize.width,0)); saveMenuItemButton->setAnchorPoint(ccp(1,0)); saveMenuItemButton->setTag(saveButtonTag); menu->addChild(saveMenuItemButton); } void GameBaseScene::goButtonCallback(cocos2d::CCObject *pSender) { ......... //当点击后调用saveGame()方法保存游戏 if(tag == saveButtonTag) { if(saveGame()) { CocosToast::createtoast(this,LanguageString::getInstance()->getLanguageString(SAVE_SUCESS)->getCString(),TOAST_SHOW_TIME,winSize/2); }else { CocosToast::createtoast(this,LanguageString::getInstance()->getLanguageString(SAVE_FAIL)->getCString(),winSize/2); } } }
saveGame()进行具体的游戏保存
cocos2dx使用了rapidjson库来替换原来的jsoncpp,我们就用这个cocos2dx自带的json库
//*** 生成 json 文件,存储在 getWritablePath 文件夹下 *** ,当前在proj.win32\Debug.win32目录下
bool GameBaseScene::saveGame() { rapidjson::Document writedoc; //创建Document writedoc.Setobject(); rapidjson::Document::AllocatorType& allocator = writedoc.GetAllocator(); rapidjson::Value players(rapidjson::kArrayType);//创建players数组 writedoc.AddMember("map_level",map_level,allocator); //添加map_level属性值 writedoc.AddMember("gameRoundCount",gameRoundCount,allocator); //添加gameRoundCount回合数 int playerNumber=1; rapidjson::Value player1_json(rapidjson::kObjectType); //创建player1的json对象 rapidjson::Value player2_json(rapidjson::kObjectType); //创建player2的json对象 rapidjson::Value player3_json(rapidjson::kObjectType); //创建player3的json对象 //保存各个角色的信息 for(auto it=players_vector.begin();it!=players_vector.end();it++) { RicherPlayer* richerPlayer = dynamic_cast<RicherPlayer*>(*it); switch(playerNumber) { case 1: { //在player1_json对象中添加角色各个属性值,json object 格式 “名称/值” player1_json.AddMember("playerTag",richerPlayer->getTag(),allocator); player1_json.AddMember("playerPosition_x",richerPlayer->getPosition().x,allocator); player1_json.AddMember("playerPosition_y",richerPlayer->getPosition().y,allocator); player1_json.AddMember("restTimes",richerPlayer->restTimes,allocator); player1_json.AddMember("stop_x",richerPlayer->stop_x,allocator); player1_json.AddMember("stop_y",richerPlayer->stop_y,allocator); player1_json.AddMember("money",richerPlayer->getMoney(),allocator); player1_json.AddMember("strength",richerPlayer->getStrength(),allocator); player1_json.AddMember("comeFromeRow",richerPlayer->getComeFromeRow(),allocator); player1_json.AddMember("comeFromCol",richerPlayer->getComeFromCol(),allocator); player1_json.AddMember("isMyTurn",richerPlayer->getIsMyTurn(),allocator); player1_json.AddMember("skill",String::createWithFormat("%d-%d-%d",richerPlayer->skill_vector.at(0),richerPlayer->skill_vector.at(1),richerPlayer->skill_vector.at(2))->getCString(),allocator); std::string tempstr; tempstr = ""; for(auto i=0;i<richerPlayer->lottery_vector.size();i++) { tempstr.append(String::createWithFormat("%02d",richerPlayer->lottery_vector.at(i))->getCString()).append("_"); } player1_json.AddMember("lottery",String::createWithFormat("%s",tempstr.c_str())->getCString(),allocator); rapidjson::Value stocks(rapidjson::kArrayType); for(auto i=0;i<richerPlayer->stockMap.size();i++) { rapidjson::Value stock(rapidjson::kObjectType); stock.AddMember("stockCode",richerPlayer->stockMap.at(i)->getCode(),allocator); stock.AddMember("makedealprice",richerPlayer->stockMap.at(i)->getMakedealprice(),allocator); stock.AddMember("storeNumber",richerPlayer->stockMap.at(i)->getStoreNumber(),allocator); stocks.PushBack(stock,allocator); } player1_json.AddMember("stocks",stocks,allocator); // 将player1_json加入到players数组 players.PushBack(player1_json,allocator); break; } case 2: { //添加角色2属性值 player2_json.AddMember("playerTag",allocator); player2_json.AddMember("playerPosition_x",allocator); player2_json.AddMember("playerPosition_y",allocator); player2_json.AddMember("restTimes",allocator); player2_json.AddMember("stop_x",allocator); player2_json.AddMember("stop_y",allocator); player2_json.AddMember("money",allocator); player2_json.AddMember("strength",allocator); player2_json.AddMember("comeFromeRow",allocator); player2_json.AddMember("comeFromCol",allocator); player2_json.AddMember("isMyTurn",allocator); player2_json.AddMember("skill",allocator); std::string tempstr; tempstr = ""; for(auto i=0;i<richerPlayer->lottery_vector.size();i++) { tempstr.append(String::createWithFormat("%02d",richerPlayer->lottery_vector.at(i))->getCString()).append("_"); } player2_json.AddMember("lottery",allocator); } player2_json.AddMember("stocks",allocator); players.PushBack(player2_json,allocator); break; } case 3: { //添加角色3属性值 player3_json.AddMember("playerTag",allocator); player3_json.AddMember("playerPosition_x",allocator); player3_json.AddMember("playerPosition_y",allocator); player3_json.AddMember("restTimes",allocator); player3_json.AddMember("stop_x",allocator); player3_json.AddMember("stop_y",allocator); player3_json.AddMember("money",allocator); player3_json.AddMember("strength",allocator); player3_json.AddMember("comeFromeRow",allocator); player3_json.AddMember("comeFromCol",allocator); player3_json.AddMember("isMyTurn",allocator); player3_json.AddMember("skill",richerPlayer->lottery_vector.at(i))->getCString()).append("_"); } player3_json.AddMember("lottery",allocator); } player3_json.AddMember("stocks",allocator); players.PushBack(player3_json,allocator); break; } } playerNumber++; } //将players数组写入到writedoc writedoc.AddMember("players",players,allocator); // 保存地块json rapidjson::Value landlayerjson(rapidjson::kArrayType); Size _landLayerSize = landLayer->getLayerSize(); for (int j = 0; j < _landLayerSize.width; j++) { for (int i = 0; i < _landLayerSize.height; i++) { Sprite* _sp = landLayer->tileAt(Point(j,i)); if (_sp) { rapidjson::Value landJson(rapidjson::kObjectType); int gid = landLayer->getTileGIDAt(Point(j,i)); landJson.AddMember("x",j,allocator); landJson.AddMember("y",i,allocator); landJson.AddMember("gid",gid,allocator); landlayerjson.PushBack(landJson,allocator); } } } writedoc.AddMember("landlayer",landlayerjson,allocator); //把json数据保存到path路径文件下,文件名称为saveJsonName ,saveJsonName在SeaScene.cpp中赋值 StringBuffer buffer; rapidjson::Writer<StringBuffer> writer(buffer); writedoc.Accept(writer); auto path = FileUtils::getInstance()->getWritablePath(); path.append(saveJsonName); FILE* file = fopen(path.c_str(),"wb"); if(file) { fputs(buffer.GetString(),file); fclose(file); } cclOG("%s",buffer.GetString()); return true; }
2、载入存档
效果如图
//在addMenuSprites()增加载入游戏按钮 void MenuScene:: addMenuSprites() { ............. LabelTTF* loadGameTTF = LabelTTF::create(LanguageString::getInstance()->getLanguageString(LOAD_GAME)->getCString(),FONT_MENU,Btn_FontSize); ControlButton* loadGameBtn = ControlButton::create(loadGameTTF,btnnormal4); loadGameBtn->setBackgroundSpriteForState(btnPress4,Control::State::SELECTED); loadGameBtn->setPosition(ccp(visibleSize.width/2,visibleSize.height-360)); loadGameBtn->setPreferredSize(Size(Btn_Width,Btn_Height)); loadGameBtn->addTargetWithActionForControlEvents(this,cccontrol_selector(MenuScene::menuTouchDown),Control::EventType::TOUCH_DOWN); loadGameBtn->setTag(Btn_Load_Game_TAG); addChild(loadGameBtn); ........ }
//点击后进入到popupLoadGameLayer(),弹出游戏存档的界面 void MenuScene::popupLoadGameLayer() { PopupLayer* popDialog = PopupLayer::create(DIALOG_BG); popDialog->setContentSize(CCSizeMake(Quit_Dialog_Size_Width,winSize.height)); popDialog->setTitle(LanguageString::getInstance()->getLanguageString(LOAD_GAME)->getCString()); popDialog->setContentText(LanguageString::getInstance()->getLanguageString(DIALOG_CONTENT)->getCString(),20,60,250); popDialog->setPopType(LOADGAME); popDialog->setCallbackFunc(this,callfuncN_selector(MenuScene::quitButtonCallback)); popDialog->addButton(BUTTON_BG2,BUTTON_BG3,LanguageString::getInstance()->getLanguageString(CANCEL)->getCString(),Btn_Quit_Cancel_TAG); this->addChild(popDialog); }
PopupLayer会根据pop类型,调用setLoadGameContext(),创建载入游戏的对话框界面 void PopupLayer::onEnter() { ...... case LOADGAME: { setLoadGameContext(contentSize); break; } ...... }
//该方法主要是判断path路径下是否有存档文件。如果没有存档,显示无存档,有则显示关卡图片 void PopupLayer::setLoadGameContext(Size size) { Menu* menu = Menu::create(); menu->setPosition(CCPointZero); //判断是否有夏日海滩的存档文件 auto beach_path = FileUtils::getInstance()->getWritablePath(); beach_path.append("beach_save.json"); FILE* beach_file = fopen(beach_path.c_str(),"r"); //有则显示海滩图片,否则显示无存档 if(beach_file) { beachLoadGameMenuItem = MenuItemImage::create("map/beach_load_normal.png","map/beach_load_pressed.png",menu_selector(PopupLayer::loadGameButtonCallback)); beachLoadGameMenuItem->setPosition(winSize/2+Size(0,120)); beachLoadGameMenuItem->setTag(save_beach_tag); menu->addChild(beachLoadGameMenuItem); fclose(beach_file); }else { beachLoadGameMenuItem = MenuItemImage::create("map/blank.png","map/blank.png",menu_selector(PopupLayer::loadGameButtonCallback)); beachLoadGameMenuItem->setPosition(winSize/2+Size(0,120)); menu->addChild(beachLoadGameMenuItem); } //判断是否有海底世界的存档文件 auto sea_path = FileUtils::getInstance()->getWritablePath(); sea_path.append("sea_save.json"); FILE* sea_file = fopen(sea_path.c_str(),"r"); if(sea_file) { seaLoadGameMenuItem = MenuItemImage::create("map/sea_load_normal.png","map/sea_load_pressed.png",menu_selector(PopupLayer::loadGameButtonCallback)); seaLoadGameMenuItem->setPosition(winSize/2+Size(0,20)); seaLoadGameMenuItem->setTag(save_sea_tag); menu->addChild(seaLoadGameMenuItem); fclose(sea_file); }else { seaLoadGameMenuItem = MenuItemImage::create("map/blank.png",menu_selector(PopupLayer::loadGameButtonCallback)); seaLoadGameMenuItem->setPosition(winSize/2+Size(0,20)); menu->addChild(seaLoadGameMenuItem); } //判断是否有空中花园的存档文件 auto garden_path = FileUtils::getInstance()->getWritablePath(); garden_path.append("garden_save.json"); FILE* garden_file = fopen(garden_path.c_str(),"r"); if(garden_file) { gardenLoadGameMenuItem = MenuItemImage::create("map/garden_load_normal.png","map/garden_load_pressed.png",menu_selector(PopupLayer::loadGameButtonCallback)); gardenLoadGameMenuItem->setPosition(winSize/2+Size(0,-80)); gardenLoadGameMenuItem->setTag(save_garden_tag); menu->addChild(gardenLoadGameMenuItem); fclose(garden_file); }else { gardenLoadGameMenuItem = MenuItemImage::create("map/blank.png",menu_selector(PopupLayer::loadGameButtonCallback)); gardenLoadGameMenuItem->setPosition(winSize/2+Size(0,-80)); menu->addChild(gardenLoadGameMenuItem); } addChild(menu); }
//当点击各个存档文件图片后,载入相应的游戏存档,恢复游戏 void PopupLayer::loadGameButtonCallback(cocos2d::CCObject *pSender) { int tag = ((Node*)pSender)->getTag(); if(tag == save_beach_tag) { log("beach load"); } if(tag == save_sea_tag) { //点击海底世界图片,首先进入海底世界关卡 TransitionFadeBL* scene = TransitionFadeBL::create(1,SeaScene::createScene()); Director::getInstance()->pushScene(scene); //然后发送载入游戏的消息 String * str = String::createWithFormat("%d-%d",MSG_LOAD_GAME_TAG,tag); NotificationCenter::getInstance()->postNotification(MSG_LOAD_GAME,str); log("sea load"); } if(tag == save_garden_tag) { log("garden load"); } }
//GameBaseScene收到载入的消息后,调用reloadGame()方法,载入游戏存档 void GameBaseScene::receivednotificationOMsg(Object* data) { ........ case MSG_LOAD_GAME_TAG: { int map_level = messageVector.at(1)->intValue(); reloadGame(map_level); break; } ....... }
//开始具体游戏的载入恢复 bool GameBaseScene::reloadGame(int map_level) { //根据关卡,载入相应的存档文件 auto path = FileUtils::getInstance()->getWritablePath(); switch(map_level) { case 1: { path.append("beach_save.json"); break; } case 2: { path.append("sea_save.json"); break; } case 3: { path.append("garden_save.json"); break; } } //*** 读取 json 文件 *** rapidjson::Document readdoc; bool bRet = false; ssize_t size = 0; std::string load_str; // getFileData 如果不指定,读取根目录是 Resource 文件夹 unsigned char* titlech = FileUtils::getInstance()->getFileData(path,"r",&size); load_str = std::string((const char*)titlech,size); readdoc.Parse<0>(load_str.c_str()); if(readdoc.HasParseError()) { cclOG("GetParseError%s\n",readdoc.GetParseError()); } if(!readdoc.IsObject()) return 0; //回合数载入 rapidjson::Value& _gameRoundCount = readdoc["gameRoundCount"]; gameRoundCount = _gameRoundCount.GetInt(); refreshRounddisplay(); //土地等级载人 rapidjson::Value& _landlayer = readdoc["landlayer"]; if(_landlayer.IsArray()) { for(int i=0; i<_landlayer.Capacity(); i++) { rapidjson::Value& arraydoc = _landlayer[i]; int x = arraydoc["x"].GetInt(); cclOG("x:%d",x); int y = arraydoc["y"].GetInt(); cclOG("y:%d",y); int gid = arraydoc["gid"].GetInt(); cclOG("gid:%d",gid); landLayer->setTileGID(gid,ccp(x,y)); } } //人物信息载人 rapidjson::Value& _players = readdoc["players"]; if(_players.IsArray()) { for(int i=0; i<_players.Capacity(); i++) { rapidjson::Value& arraydoc = _players[i]; RicherPlayer* _richerPY = players_vector.at(i); int _restTimes = arraydoc["restTimes"].GetInt(); float _playerPositionX = arraydoc["playerPosition_x"].GetDouble(); float _playerPositionY = arraydoc["playerPosition_y"].GetDouble(); int _stop_x = arraydoc["stop_x"].GetInt(); int _stop_y = arraydoc["stop_y"].GetInt(); int _money = arraydoc["money"].GetInt(); int _strength = arraydoc["strength"].GetInt(); int _comeFromeRow = arraydoc["comeFromeRow"].GetInt(); int _comeFromCol = arraydoc["comeFromCol"].GetInt(); bool _isMyTurn = arraydoc["isMyTurn"].GetBool(); const char* _skill = arraydoc["skill"].GetString(); const char* _lottery = arraydoc["lottery"].GetString(); Vector<String*> lotteryVector = Util::splitString(_lottery,"_"); for(int i=0;i<lotteryVector.size();i++ ) { _richerPY->lottery_vector.push_back(lotteryVector.at(i)->intValue()); } _richerPY->restTimes = _restTimes; _richerPY->setPosition(ccp(_playerPositionX,_playerPositionY)); _richerPY->setComeFromeRow(_comeFromeRow); _richerPY->setComeFromCol(_comeFromCol); _richerPY->setIsMyTurn(_isMyTurn); _richerPY->stop_x = _stop_x; _richerPY->stop_y = _stop_y; _richerPY->setMoney(_money); _richerPY->setStrength(_strength); Vector<String*> skillVs = Util::splitString(_skill,"-"); _richerPY->skill_vector.at(0) = skillVs.at(0)->intValue(); _richerPY->skill_vector.at(1) = skillVs.at(1)->intValue(); _richerPY->skill_vector.at(2) = skillVs.at(2)->intValue(); refreshMoneyLabel(_richerPY,0); refreshStrengthLabel(_richerPY,0); } } //股票载入 for(int i=0; i<players_vector.size(); i++) { RicherPlayer* _richerPY = players_vector.at(i); rapidjson::Value& _stocks = _players[i]["stocks"]; if(_stocks.IsArray()) { for(int i=0; i<_stocks.Capacity(); i++) { rapidjson::Value& arraydoc = _stocks[i]; int _stockCode = arraydoc["stockCode"].GetInt(); int _makedealprice = arraydoc["makedealprice"].GetInt(); int _storeNumber = arraydoc["storeNumber"].GetInt(); _richerPY->stockMap.at(i)->setMakedealprice(_makedealprice); _richerPY->stockMap.at(i)->setStoreNumber(_storeNumber); } } } return 0; }
至此,游戏从保存文档中恢复完毕。
点击下载代码 未完待续................
Cocos2d-x 3.2 大富翁游戏项目开发-第二十四部分 彩票开奖
每隔N个回合,彩票开奖一次,每期开奖奖金固定5万,暂不累积。摇奖效果一般,以后考虑用物理引擎实现1、定义彩票开奖类
bool LotteryPublish::init() { addItemSpriteFrameCache(); SpriteFrame* spf; spf = itemSpriteFrameCache->getSpriteFrameByName("publish_ly01.png"); Sprite::initWithSpriteFrame(spf); setItemAnimate(); return true; } void LotteryPublish::addItemSpriteFrameCache() { itemSpriteFrameCache = SpriteFrameCache::getInstance(); itemSpriteFrameCache->addSpriteFramesWithFile("images/publish_ly.plist","images/publish_ly.png"); memset(name,20); for (int i=1; i<=21; i++) { sprintf(name,"publish_ly%02d.png",i); item_anim_vector.pushBack(itemSpriteFrameCache->getSpriteFrameByName(name)); } } //开奖动画 void LotteryPublish::setItemAnimate() { if(!AnimationCache::getInstance()->getAnimation("publish_ly_animation")) { AnimationCache::getInstance()->addAnimation(Animation::createWithSpriteFrames(item_anim_vector,0.1f),"publish_ly_animation"); } normal_anmi = Animate::create(AnimationCache::getInstance()->getAnimation("publish_ly_animation")); normal_anmi->retain(); }
2、创建开奖画面的对话框。
void GameBaseScene::initPopPublishLottery() { popDialogLottery = PopupLayer::create(DIALOG_BG); popDialogLottery->setContentSize(CCSizeMake(Dialog_Size_Width,Dialog_Size_Height+180)); popDialogLottery->setTitle(LanguageString::getInstance()->getLanguageString(PUBLISH_LottERY)->getCString()); popDialogLottery->setContentText("",20,60,250); popDialogLottery->setPopType(LottERY_PUBLISH);//开奖类型的对话框 popDialogLottery->setPlayerVector(players_vector);//传入角色容器,开奖画面会根据这个显示角色购买的彩票号码 popDialogLottery->setTag(100); this->addChild(popDialogLottery); popDialogLottery->setVisible(false); } 在显示Go按钮之前,根据回合数显示开奖界面 void GameBaseScene::receivednotificationOMsg(Object* data) { ............. case MSG_GO_SHOW_TAG: { //便于测试,每一回合结束都显示开奖画面 if(gameRoundCount !=0 && gameRoundCount%1 == 0) { //前面角色买地等,会播放动画,所以这里延迟一下,显示开奖画面 scheduleOnce(schedule_selector( GameBaseScene::popPublishLottery),2.0f); }else { showGoButton(); } break; } ............ } //把开奖画面显示出来,并播放摇奖动画 void GameBaseScene::popPublishLottery(float dt) { popDialogLottery->setVisible(true); //开奖画面中添加角色购买的彩票号码 popDialogLottery->addplayersLottery(); //播放摇奖动画 popDialogLottery->runPublishAnmi(); }
3、在PopupLayer.h中添加开奖对话框枚举LottERY_PUBLISH
enum POP_TYPE { norMAL,LottERY,LottERY_PUBLISH,STOCK,}; //当对话框进入后调用setPublishLotteryContext,在对话框中添加开奖画面 void PopupLayer::onEnter() { ...... case LottERY_PUBLISH: { setPublishLotteryContext(contentSize); break; } ..... } //在对话框中添加开奖画面 void PopupLayer::setPublishLotteryContext(Size size) { Size winSize = Director::getInstance()->getWinSize(); lp = LotteryPublish::create(); addChild(lp); lp->setPosition((winSize)/2); addplayersInfo(size); }
//添加角色图标
void PopupLayer::addplayersInfo(Size size) { Size winSize = Director::getInstance()->getWinSize(); Size center =(winSize-size)/2; int j=0; for(auto it=players_vector.begin();it!=players_vector.end();it++) { RicherPlayer* player = dynamic_cast<RicherPlayer*>(*it); SpriteFrame* spf; int tag = player->getTag(); switch(tag) { case PLAYER_1_TAG: { spf = player->player_spriteFrameCache->getSpriteFrameByName("player1_anim_01.png"); break; } case PLAYER_2_TAG: { spf = player->player_spriteFrameCache->getSpriteFrameByName("player2_anim_02.png"); break; } } Sprite* playerSprite = Sprite::createWithSpriteFrame(spf); playerSprite->setPosition( center.width+20,(winSize.height/2+50)+j*50); addChild(playerSprite); j++; } }
//添加角色购买的彩票
void PopupLayer::addplayersLottery() { for(int i=1;i<=30;i++) { if(this->getChildByTag(1000+i) != NULL) { this->removeChildByTag(1000+i); } } Size winSize = Director::getInstance()->getWinSize(); Size size = this->getContentSize(); Size center =(winSize-size)/2; int j=0; for(auto it=players_vector.begin();it!=players_vector.end();it++) { RicherPlayer* player = dynamic_cast<RicherPlayer*>(*it); playerLotteryVector.clear(); for(int i=0;i < player->lottery_vector.size();i++) { LabelTTF* labelLotteryNumber = LabelTTF::create(String::createWithFormat("%i",player->lottery_vector.at(i))->getCString(),"",15); labelLotteryNumber->setPosition(ccp( center.width+20+(i+1)*20,(winSize.height/2+30)+j*50)); labelLotteryNumber->setColor(Color3B(255,100,100)); labelLotteryNumber->setTag(1000+player->lottery_vector.at(i)); playerLotteryVector.pushBack(labelLotteryNumber); } for(int i=0;i < playerLotteryVector.size();i++) { addChild(playerLotteryVector.at(i)); } j++; } }
//开始摇奖动画
void PopupLayer::runPublishAnmi() { scheduleOnce(schedule_selector( PopupLayer::realRunPublishAnmi),3.0f); }
//开始真正摇奖
void PopupLayer::realRunPublishAnmi(float dt) { lp->runAction(Sequence::create(lp->getnormal_anmi(),CallFunc::create([this]() { int lott = rand()%(30)+1; //四秒后 让开奖画面消失 scheduleOnce(schedule_selector( PopupLayer::dismissFromParent),4.0f); Sprite* ball = Sprite::create("images/orange_ball.png"); ball->setPosition(lp->getPosition()-lp->getContentSize()/2 + ccp(0,13)); ball->setAnchorPoint(ccp(0,0)); addChild(ball); LabelTTF* ltf = LabelTTF::create(String::createWithFormat("%02d",lott)->getCString(),20); ltf->setPosition(ball->getPosition()+ccp(5,6)); ltf->setAnchorPoint(ccp(0,0)); addChild(ltf); Size winSize = Director::getInstance()->getWinSize(); Size center =(winSize)/2; int j=0; //判断角色是否中奖 for(auto it=players_vector.begin();it!=players_vector.end();it++) { RicherPlayer* player = dynamic_cast<RicherPlayer*>(*it); //player->lottery_vector.push_back(8); for(int i=0;i < player->lottery_vector.size();i++) { if(player->lottery_vector.at(i) == lott) { player->setMoney(player->getMoney()+LottERY_WIN_MONEY); ParticleSystem* lotteryWinParticle = ParticleSystemQuad::create("images/lottery_win.plist"); lotteryWinParticle->retain(); ParticleBatchNode *batch = ParticleBatchNode::createWithTexture(lotteryWinParticle->getTexture()); batch->addChild(lotteryWinParticle); addChild(batch); lotteryWinParticle->setPosition( center.width+20,(winSize.height/2+50)+j*50 ); lotteryWinParticle->release(); lotteryWinParticle->setAutoRemoveOnFinish(true); } } player->lottery_vector.clear(); j++; } } ),NULL)); }
//发送对话框消失消息,并设置为不可见
void PopupLayer::dismissFromParent(float dt) { NotificationCenter::getInstance()->postNotification(MSG_DIMISS_DIALOG,String::createWithFormat("%d",MSG_DIMISS_DIALOG_PUBLISH_LottERY_TAG)); this->setVisible(false); }
4、GameBaseScene收到该消息后,更新资金,并显示Go按钮
case MSG_DIMISS_DIALOG_PUBLISH_LottERY_TAG: { //this->removeChildByTag(100); for(auto it=players_vector.begin();it!=players_vector.end();it++) { RicherPlayer* player = dynamic_cast<RicherPlayer*>(*it); refreshMoneyLabel(player,0); } showGoButton(); break; }
点击下载
未完待续................
今天关于火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第二十四节:小项目实训《绝命沙滩》的分享就到这里,希望大家有所收获,若想了解更多关于Cocos2d-x 3.2 大富翁游戏项目开发-第二十三部分 购买彩票、Cocos2d-x 3.2 大富翁游戏项目开发-第二十九部分 游戏配音、Cocos2d-x 3.2 大富翁游戏项目开发-第二十八部分 游戏保存和载入存档游戏、Cocos2d-x 3.2 大富翁游戏项目开发-第二十四部分 彩票开奖等相关知识,可以在本站进行查询。
本文标签: