cocos2d-x v3.2 FlappyBird 各个类对象具体代码分析(7)

来源:互联网 发布:caffe 数据增强 编辑:程序博客网 时间:2024/06/11 13:07

今天我们介绍最后两个类

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;//最终分数labelcocos2d::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.hint 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);}



1 0
原创粉丝点击