标签:cocos2d-x 代码分析 游戏 game 手机游戏
今天我们介绍最后两个类
GameOverLayer类
GameLayer类
GameLayer类是整个游戏中最重要的类,因为是整个游戏的中央系统,控制着各个类(层)之间的交互,这个类中实现了猪脚小鸟和它的敌人(管道和草地- . -)碰撞检测,说道物理引擎的碰撞检测,我也是第一次接触,也没多大难度,就直接调用了cocos2d-x的接口,这个类就是游戏的主场景,游戏就是在这里进行的。
GameOverLayer类,游戏结束后一些分数的显示,还有就是奖牌的实现(楼主写的很简单......),这边比较有意思的就是加分效果的实现,这个楼主以前在写AS3的时候经常用到,最后就是两个按钮,一个重新开始按钮,一个排名按钮,排名按钮没有写功能,这个要跟手机的游戏中心配合。这边放一张游戏结束后的图片:
差不多了,这个游戏所有的类都介绍的差不多了,游戏的源码和图片:
http://download.csdn.net/detail/u011373759/7941891
下面是这两个类的源码分析,谢谢大家,结束
//GameOverLayer.h #pragma once #include "cocos2d.h" class GameOverLayer:public cocos2d::Layer { public: GameOverLayer(); ~GameOverLayer(); bool init(); //回调函数 void callBack(); //再来一次 void gameAgain(); //获取排名 void getRank(); //显示分数 void showScore(float); CREATE_FUNC(GameOverLayer); private: //计分板精灵 cocos2d::Sprite * box; //最终分数label cocos2d::Label * numberLabel; int score; int highScore; };
//GameOverLayer.cpp #include "GameOverLayer.h" #include "define.h" #include "GameLayer.h" #include "NumberLayer.h" #include "GetLocalScore.h" USING_NS_CC; GameOverLayer::GameOverLayer() { } GameOverLayer::~GameOverLayer() { } bool GameOverLayer::init() { if (!Layer::init()) { return false; } auto origin=Director::getInstance()->getVisibleOrigin(); auto visibleSize=Director::getInstance()->getVisibleSize(); //历史最高分 highScore=GetLocalScore::getInstance()->getHighScore(); //计分板 box=Sprite::createWithSpriteFrameName("score_panel.png"); box->setPosition(Point(origin.x+visibleSize.width/2,origin.y-visibleSize.height/2)); this->addChild(box); //游戏结束后,计分板要从屏幕底部向上运动出现 //动画结束后要显示分数和两个按钮(在回调函数里) auto moveto=MoveTo::create(SCORECARD_SHOW_TIME,Point(origin.x+visibleSize.width/2,origin.y+visibleSize.height*0.5)); auto callback=CallFuncN::create(CC_CALLBACK_0(GameOverLayer::callBack,this)); auto sequence=Sequence::create(moveto,callback,NULL); box->runAction(sequence); //动画的声音 CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("sounds/sfx_swooshing.mp3"); //gameover 字 auto gameover=Sprite::createWithSpriteFrameName("text_game_over.png"); gameover->setPosition(Point(origin.x+visibleSize.width/2,origin.y+visibleSize.height+gameover->getContentSize().height/2)); //gameover精灵也要执行相同的动画,不过它是从上到下运动 auto moveto2=MoveTo::create(SCORECARD_SHOW_TIME,Point(origin.x+visibleSize.width/2,origin.y+visibleSize.height*0.7)); gameover->runAction(moveto2); this->addChild(gameover); return true; } void GameOverLayer::callBack() { log("callback"); auto origin=Director::getInstance()->getVisibleOrigin(); auto visibleSize=Director::getInstance()->getVisibleSize(); //排名和再来一次按钮 //计分板和gameover精灵执行完动画后,出现按钮 auto again=Sprite::createWithSpriteFrameName("button_play.png"); auto menuAgain=MenuItemSprite::create(again,again,CC_CALLBACK_0(GameOverLayer::gameAgain,this)); auto rank=Sprite::createWithSpriteFrameName("button_score.png"); auto menuRank=MenuItemSprite::create(rank,rank,CC_CALLBACK_0(GameOverLayer::getRank,this)); //两个按钮坐标的设定 int l=(visibleSize.width-again->getContentSize().width*2)/3; menuAgain->setPosition(Point(origin.x+l+again->getContentSize().width/2,origin.y+visibleSize.height*0.3)); menuRank->setPosition(Point(origin.x+visibleSize.width-l-again->getContentSize().width/2,origin.y+visibleSize.height*0.3)); //把按钮放到菜单中去 auto menu=Menu::create(menuAgain,menuRank,NULL); menu->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT); menu->setPosition(Point::ZERO); this->addChild(menu); //分数显示 score=0; auto str=__String::createWithFormat("%d",score); numberLabel=Label::createWithBMFont("font2.fnt",str->getCString()); numberLabel->setPosition(Point(origin.x+visibleSize.width/2+65,origin.y+visibleSize.height*0.5+10)); this->addChild(numberLabel); //当分数大于0时执行一个分数从0到n的动画 if (NumberLayer::getInstance()->getScore()>0) { this->schedule(schedule_selector(GameOverLayer::showScore),ADDSCORE_FRE); } //历史最高分 auto str1=__String::createWithFormat("%d",highScore); auto highScoreLabel=Label::createWithBMFont("font2.fnt",str1->getCString()); highScoreLabel->setPosition(Point(origin.x+visibleSize.width/2+65,origin.y+visibleSize.height*0.5-30)); this->addChild(highScoreLabel); //如果当前分数大于历史最高分,则会出现new的字样 if (NumberLayer::getInstance()->getScore()>highScore) { GetLocalScore::getInstance()->setHighScore(NumberLayer::getInstance()->getScore()); auto picNew=Sprite::createWithSpriteFrameName("new.png"); picNew->setPosition(Point(origin.x+visibleSize.width/2+37,origin.y+visibleSize.height*0.5-4)); this->addChild(picNew); } //奖牌显示 //这边的奖牌显示是自己定的 //各个奖牌之间要达到多少分数请看define.h int l2=(visibleSize.width-box->getContentSize().width)/2; if (NumberLayer::getInstance()->getScore()<MEDALS_0) { return; } Sprite * medals; if (NumberLayer::getInstance()->getScore()>=MEDALS_0&&NumberLayer::getInstance()->getScore()<MEDALS_1) { medals=Sprite::createWithSpriteFrameName("medals_0.png"); } if (NumberLayer::getInstance()->getScore()>=MEDALS_1&&NumberLayer::getInstance()->getScore()<MEDALS_2) { medals=Sprite::createWithSpriteFrameName("medals_1.png"); } if (NumberLayer::getInstance()->getScore()>=MEDALS_2&&NumberLayer::getInstance()->getScore()<MEDALS_3) { medals=Sprite::createWithSpriteFrameName("medals_2.png"); } if (NumberLayer::getInstance()->getScore()>=MEDALS_3) { medals=Sprite::createWithSpriteFrameName("medals_3.png"); } medals->setPosition(Point(origin.x+l2+54,origin.y+visibleSize.height*0.49)); this->addChild(medals); } //再来一次,场景切换 void GameOverLayer::gameAgain() { Director::getInstance()->replaceScene(TransitionFade::create(CHANGESCENE_TIME,GameLayer::createScene())); } //排名按钮的回调,这里没写,因为这里要调用的是手机游戏中心的资料 void GameOverLayer::getRank() { log("get rank"); } //分数显示动画 void GameOverLayer::showScore( float ) { score++; auto str=__String::createWithFormat("%d",score); numberLabel->setString(str->getCString()); if (score==NumberLayer::getInstance()->getScore()) { this->unschedule(schedule_selector(GameOverLayer::showScore)); } }
//GameLayer.h #pragma once #include "cocos2d.h" #include "SpriteBird.h" class GameLayer:public cocos2d::Layer { public: GameLayer(); ~GameLayer(); static cocos2d::Scene * createScene(); bool init(); //游戏开始 void startGame(); CREATE_FUNC(GameLayer); private: //猪脚层 SpriteBird * bird; //物理碰撞侦听 cocos2d::EventListenerPhysicsContact * contactListener; };
//GameLayer.cpp #include "GameLayer.h" #include "define.h" #include "HelpLayer.h" #include "PipeLayer.h" #include "LandLayer.h" #include "NumberLayer.h" #include "GameOverLayer.h" USING_NS_CC; GameLayer::GameLayer() { } GameLayer::~GameLayer() { } cocos2d::Scene * GameLayer::createScene() { //注意我们这边创造的是物理场景 auto scene=Scene::createWithPhysics(); //加入了重力,GRAVITY的值为(0,-980) //跟我们的世界重力加速度是一样的,比较真实 scene->getPhysicsWorld()->setGravity(GRAVITY); auto gameLayer=GameLayer::create(); scene->addChild(gameLayer); return scene; } bool GameLayer::init() { if (!Layer::init()) { return false; } auto origin=Director::getInstance()->getVisibleOrigin(); auto visibleSize=Director::getInstance()->getVisibleSize(); //背景图片,根据时间加载晚上和白天的图片 time_t t=time(NULL); tm * lt=localtime(&t); int hour=lt->tm_hour; Sprite * bg; if (hour>=6&&hour<=17) { bg=Sprite::createWithSpriteFrameName("bg_day.png"); } else { bg=Sprite::createWithSpriteFrameName("bg_night.png"); } bg->setPosition(Point(origin.x+visibleSize.width/2,origin.y+visibleSize.height/2)); this->addChild(bg); //下面就是我们前几章讲的各个类的实例的运用了 //这个游戏就像贴纸一样,一层一层叠起来,各层执行各层的逻辑 //靠这个游戏层来控制各层的之间的交互 //草底层 auto landLayer=LandLayer::create(); landLayer->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT); landLayer->setPosition(Point::ZERO); this->addChild(landLayer,2); //帮助界面 auto helpLayer=HelpLayer::create(); helpLayer->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT); helpLayer->setPosition(Point::ZERO); this->addChild(helpLayer); //管子层 auto pipeLayer=PipeLayer::create(); pipeLayer->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT); pipeLayer->setPosition(Point::ZERO); this->addChild(pipeLayer,1); //主角 bird=SpriteBird::createBird(); bird->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT); bird->setPosition(Point::ZERO); this->addChild(bird,2); bird->changeState(ACTION_STATE_IDLE); //这里创建了触控侦听 //当玩家点击屏幕时,游戏开始,并移除这个侦听 auto listener=EventListenerTouchOneByOne::create(); listener->setSwallowTouches(false); listener->onTouchBegan=[=](Touch * t,Event * e) { log("GameLayer touch begin"); return true; }; listener->onTouchEnded=[=](Touch * t,Event * e) { pipeLayer->startPipe(); startGame(); _eventDispatcher->removeEventListener(listener); }; _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this); //碰撞检测侦听 contactListener=EventListenerPhysicsContact::create(); contactListener->onContactBegin=[=](const PhysicsContact& contact) { log("1111111111111111111111111"); //当检测到碰撞的时候,播放hit声音 //小鸟要么撞到草地,要么撞到管道 CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("sounds/sfx_hit.mp3"); //管道停止运动 pipeLayer->stopPipe(); //草地停止运动 landLayer->stopLand(); //小鸟改变状态 bird->changeState(ACTION_STATE_DIE); //移除积分器 this->removeChild(NumberLayer::getInstance()); //游戏结束后计分板出现 auto scorecard=GameOverLayer::create(); scorecard->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT); scorecard->setPosition(Point::ZERO); this->addChild(scorecard,99); _eventDispatcher->removeEventListener(contactListener); return true; }; _eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener,this); return true; } void GameLayer::startGame() { //游戏开始,小鸟转换到飞行状态 bird->changeState(ACTION_STATE_FLY); //加入积分器并初始化 NumberLayer::getInstance()->initScore(); this->addChild(NumberLayer::getInstance(),10); }
cocos2d-x v3.2 FlappyBird 各个类对象具体代码分析(7)
标签:cocos2d-x 代码分析 游戏 game 手机游戏
原文地址:http://blog.csdn.net/u011373759/article/details/39396391