Cocos2d-x3.5 设计Fly_bird(飞行的小鸟)并打包成APK文件

Cocos2d-x3.5 设计Fly_bird(飞行的小鸟)并打包成APK文件,第1张

概述这个小的游戏代码可以使我们理解常见的cocos的概念,从场景,精灵,图层,到导演,回调函数,更新函数,再到设置物理世界,设置精灵刚体。不得不说cocos博大精深,不过有个大家一直在意的问题,就是cocos版本更新太快,有些东西不能使用或者使用错误。个人建议去看cocos官网的版本更新信息和去官网论坛提问或者加群讨论,这样更利于大家提高! 上代码!代码大部分都有注释,如有问题可以提问! 游戏由三个场

这个小的游戏代码可以使我们理解常见的cocos的概念,从场景,精灵,图层,到导演,回调函数,更新函数,再到设置物理世界,设置精灵刚体。不得不说cocos博大精深,不过有个大家一直在意的问题,就是cocos版本更新太快,有些东西不能使用或者使用错误。个人建议去看cocos官网的版本更新信息和去官网论坛提问或者加群讨论,这样更利于大家提高!上代码!代码大部分都有注释,如有问题可以提问!

游戏由三个场景构成,HelloWorldScene,GameScene,GameOver。

HelloWorldScene是初始场景

#ifndef __HELLOWORLD_SCENE_H__#define __HELLOWORLD_SCENE_H__#include "cocos2d.h"//#include "Land.h"USING_NS_CC;class HelloWorld : public cocos2d::Layer{	voID scrollLand(float dt);	Sprite* land1;	Sprite* land2;public:    // there's no 'ID' in cpp,so we recommend returning the class instance pointer    static cocos2d::Scene* createScene();	//virtual voID update(float delta);	voID myupdate(float delta);    // Here's a difference. Method 'init' in cocos2d-x returns bool,instead of returning 'ID' in cocos2d-iphone    virtual bool init();        // a selector callback    voID menuCloseCallback(cocos2d::Ref* pSender);    	//voID scrollLand(float dt);    // implement the "static create()" method manually    CREATE_FUNC(HelloWorld);};#endif // __HELLOWORLD_SCENE_H__#include "HelloWorldScene.h"#include "SceneOne.h"#include"GameScene.h"#include "SimpleAudioEngine.h"USING_NS_CC;using namespace CocosDenshion;Scene* HelloWorld::createScene(){    // 'scene' is an autorelease object    auto scene = Scene::create();        // 'layer' is an autorelease object    auto layer = HelloWorld::create();    // add layer as a child to scene    scene->addChild(layer);    // return the scene    return scene;}// on "init" you need to initialize your instancebool HelloWorld::init(){    //////////////////////////////    // 1. super init first    if ( !Layer::init() )    {        return false;    }        Size visibleSize = Director::getInstance()->getVisibleSize();    Vec2 origin = Director::getInstance()->getVisibleOrigin();	SimpleAudioEngine::getInstance()->preloadEffect("dIE.mp3");	SimpleAudioEngine::getInstance()->preloadEffect("hit.mp3");	SimpleAudioEngine::getInstance()->preloadEffect("point.mp3");	SimpleAudioEngine::getInstance()->preloadEffect("swooshing.mp3");	SimpleAudioEngine::getInstance()->preloadEffect("wing.mp3");    /////////////////////////////    // 2. add a menu item with "X" image,which is clicked to quit the program    //    you may modify it.    // add a "close" icon to exit the progress. it's an autorelease object        /////////////////////////////    // 3. add your codes below...    // add a label shows "Hello World"    // create and initialize a label        auto label = Label::createWithTTF("Start_Scene","Fonts/Marker Felt.ttf",24);        // position the label on the center of the screen    label->setposition(Vec2(origin.x + visibleSize.wIDth/2,origin.y + visibleSize.height - label->getContentSize().height));    // add the label as a child to this layer  //  this->addChild(label,1);    // add "HelloWorld" splash screen"	SpriteFrameCache::getInstance()->addSpriteFramesWithfile("game.pList");    auto background = Sprite::createWithSpriteFramename("bg.png");    // position the sprite on the center of the screen	background->setposition(Vec2(visibleSize.wIDth / 2 + origin.x,visibleSize.height / 2 + origin.y));    // add the sprite as a child to this layer	this->addChild(background,0);    	auto bird = Sprite::createWithSpriteFramename("bird1.png");		auto animation = Animation::create();	for (int i = 1; i <= 3; ++i)	{		char szname[100] = { 0 };		sprintf(szname,"bird%d.png",i);		auto _sprite = Sprite::createWithSpriteFramename(szname);		animation->addSpriteFrame(_sprite->getSpriteFrame());					}	animation->setDelayPerUnit(1.5f / 14.0f);	animation->setRestoreOriginalFrame(true);	auto action = Animate::create(animation);	auto swing = MoveBy::create( 0.5f,Vec2(0,10));		bird->runAction(RepeatForever::create(action)); 	bird->runAction(RepeatForever::create(Sequence::create(swing,swing->reverse(),NulL)));	bird->setposition(Vec2(visibleSize.wIDth / 2 + origin.x,visibleSize.height / 2 + origin.y));	this->addChild(bird,10);	auto flappybird = Sprite::createWithSpriteFramename("bird_logo.png");	flappybird->setposition(Vec2(visibleSize.wIDth / 2 + origin.x,visibleSize.height / 2 + origin.y+3*flappybird->getContentSize().height));	this->addChild(flappybird,100);	  	/*auto land1 = Sprite::createWithSpriteFramename("land.png");	land1->setposition(Vec2(visibleSize.wIDth / 2 + origin.x,visibleSize.height/2-background->getpositionY()+land1->getContentSize().height));	this->addChild(land1,100);	auto land1move = MoveBy::create(3.0f,Vect(land1->getContentSize().wIDth,0));		auto land2 = Sprite::createWithSpriteFramename("land.png");	land2->setposition(Vec2(visibleSize.wIDth / 2 + origin.x-land1->getContentSize().wIDth,visibleSize.height / 2 - background->getpositionY() + land1->getContentSize().height));	this->addChild(land2,100);	auto land2move = MoveBy::create(3.0f,Vect(land2->getContentSize().wIDth,0));	 		land1->runAction(land1move);		land2->runAction(land2move);*/	land1 = Sprite::createWithSpriteFramename("land.png");	land1->setAnchorPoint(Point::ZERO);	land1->setposition(Point::ZERO);	this->addChild(land1,10);  //置于最顶层  	land2 = Sprite::createWithSpriteFramename("land.png");	land2->setAnchorPoint(Point::ZERO);	land2->setposition(Point::ZERO);	this->addChild(land2,10);	//this->schedule(schedule_selector(HelloWorld::scrollLand),0.01f);	//land = Land::create();	//land->setposition(Vec2(visibleSize.wIDth,visibleSize.height));	//this->addChild(land,100);	auto start_bt = Sprite::createWithSpriteFramename("start_btn.png");	auto pressed_bt = Sprite::createWithSpriteFramename("start_btn_pressed.png");	auto closeItem = MenuItemSprite::create(		start_bt,pressed_bt,CC_CALLBACK_1(HelloWorld::menuCloseCallback,this));	closeItem->setposition(Vec2(visibleSize.wIDth / 2 + origin.x,visibleSize.height / 2 - background->getpositionY() +3* closeItem->getContentSize().height));	// create menu,it's an autorelease object	auto menu = Menu::create(closeItem,NulL);	menu->setposition(Vec2::ZERO);		this->addChild(menu,101);		//this->scheduleUpdate();//使用update()函数来更新		this->schedule(schedule_selector(HelloWorld::myupdate));//使用自定义函数来更新		    return true;}voID HelloWorld::menuCloseCallback(Ref* pSender){#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)	Message@R_419_6951@("You pressed the close button. windows Store Apps do not implement a close button.","Alert");    return;#endif	auto scene = GameScene::createScene();	auto Transition = TransitionFade::create(1,scene);	// run	Director::getInstance()->replaceScene(Transition);#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)    exit(0);#endif}/*voID HelloWorld::scrollLand(float dt){	this->land1->setpositionX(this->land1->getpositionX() - 2.0f);	this->land2->setpositionX(this->land1->getpositionX() + this->land1->getContentSize().wIDth - 2.0f);	if (this->land2->getpositionX() == 0) {		this->land1->setpositionX(0);	}}voID HelloWorld::update(float delta){	int posLand1 = land1->getpositionX();	int posLand2 = land2->getpositionX();	int speed = 1;	posLand1 -= speed;	posLand2 -= speed;		auto landsize = land2->getContentSize();	if (posLand1 < -landsize.wIDth / 2+142)	{		posLand2 = landsize.wIDth / 2;		posLand1 = landsize.wIDth + landsize.wIDth / 2;	}	if (posLand2 < -landsize.wIDth / 2+142)	{		posLand1 = landsize.wIDth / 2;		posLand2 = landsize.wIDth + landsize.wIDth / 2;	}	land1->setpositionX(posLand1);	land2->setpositionX(posLand2);}*/voID HelloWorld::myupdate(float delta){	int posLand1 = land1->getpositionX();	int posLand2 = land2->getpositionX();	int speed = 1;	posLand1 -= speed;	posLand2 -= speed;	auto landsize = land2->getContentSize();	if (posLand1 < -landsize.wIDth / 2 + 142)	{		posLand2 = 0;		posLand1 = landsize.wIDth + 0;	}	if (posLand2 < -landsize.wIDth / 2 + 142)	{		posLand1 = 0;		posLand2 = landsize.wIDth + 0;	}	land1->setpositionX(posLand1);	land2->setpositionX(posLand2);}

接下来是游戏核心的GameScene代码:
#pragma once#include "cocos2d.h"//一些全局常量const int BIRD_RADIUS = 15; //小鸟半径const int PIPE_HEIGHT = 320;//半根管道长度const int PIPE_WIDTH = 52; //管道宽度const int PIPE_SPACE = 100; //上下管之间的缝隙const int PIPE_INTERVAL = 170;//横向两根管子之间的间距,288/2+52/2const int WAIT_disTANCE = 380;//等待距离enum GAME_STATUS  //游戏状态,准备,开始,结束{	GAME_READY,GAME_START,GAME_OVER};class GameScene :public cocos2d::Layer{public:	static cocos2d::Scene* createScene();	virtual bool init();	CREATE_FUNC(GameScene);	voID update(float dt);	voID scrollLand(float dt);	voID setPhysicWorld(cocos2d::PhysicsWorld *world);	virtual bool onContactBegin(const cocos2d::PhysicsContact& contact);	virtual bool ontouchBegan(cocos2d::touch *touch,cocos2d::Event *event);	virtual voID ontouchended(cocos2d::touch *touch,cocos2d::Event *event);	voID createPipes();	int getRandomHeight();	voID gameStart();	voID gameOver();	voID gameRetart(Ref *sender);	voID gamePanelAppear();private:	cocos2d::Sprite *birdSprite; //小鸟	cocos2d::RepeatForever *swingAction; //小鸟的晃动动画	cocos2d::LabelTTF *scoreLabel; //计分	cocos2d::Sprite *land1,*land2;  //地板	cocos2d::Vector<cocos2d::Node*> pipes; //管道,用容器装起来	cocos2d::PhysicsWorld *m_physicWorld; //游戏层物理世界	GAME_STATUS gameStatus; //游戏状态变量	int score,bestscore;   //游戏当前分数和最好分数	int touchX;  //触摸点横坐标}; #include "GameScene.h"#include "SimpleAudioEngine.h"#include "HelloWorldScene.h"#include "GameOver.h"USING_NS_CC;using namespace CocosDenshion;Scene* GameScene::createScene(){	//创建游戏场景	auto gameScene = Scene::createWithPhysics(); //用物理世界初始化场景	gameScene->getPhysicsWorld()->setGravity(Vec2(0,-700)); //设置重力场,重力加速度可以根据手感改小点	//添加主游戏层	auto gameLayer = GameScene::create();	gameLayer->setPhysicWorld(gameScene->getPhysicsWorld()); //绑定物理世界	gameScene->addChild(gameLayer);	return gameScene;}bool GameScene::init(){	if (!Layer::init())		return false;	Size visibleSize = Director::getInstance()->getVisibleSize();	Point visibleOrigin = Director::getInstance()->getVisibleOrigin();	//初始化游戏状态	gameStatus = GAME_READY;	score = 0;		//添加游戏背景	Sprite *backGround = Sprite::createWithSpriteFramename("bg.png");	backGround->setposition(visibleOrigin.x + visibleSize.wIDth / 2,visibleOrigin.y + visibleSize.height / 2);	this->addChild(backGround);	//logo	auto gamelogo = Sprite::createWithSpriteFramename("bird_logo.png");	gamelogo->setposition(visibleOrigin.x + visibleSize.wIDth / 2,visibleOrigin.y + visibleSize.height / 2 + 100);	gamelogo->setname("logo");	this->addChild(gamelogo);	//添加管子	createPipes();	//小鸟	birdSprite = Sprite::create();	birdSprite->setposition(visibleOrigin.x + visibleSize.wIDth / 3,visibleOrigin.y + visibleSize.height / 2);	this->addChild(birdSprite);	auto birdAnimation = Animation::create();	birdAnimation->setDelayPerUnit(0.2f);	birdAnimation->addSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByname("bird1.png"));	birdAnimation->addSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByname("bird2.png"));	birdAnimation->addSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByname("bird3.png"));	auto birdAnim = Animate::create( birdAnimation);	birdSprite->runAction(RepeatForever::create(birdAnim));  //挥翅动画	auto up = MoveBy::create(0.4f,Point(0,8));	auto upBack = up->reverse();	if (gameStatus == GAME_READY)	{		swingAction = RepeatForever::create(Sequence::create(up,upBack,NulL));		birdSprite->runAction(swingAction); //上下晃动动画	}	//小鸟绑定刚体	auto birdBody = PhysicsBody::createCircle(BIRD_RADIUS); //将小鸟当成一个圆,懒得弄精确的轮廓线了	birdBody->setDynamic(true);   //设置为可以被物理场所作用而动作	birdBody->setContactTestBitmask(1); //必须设置这项为1才能检测到不同的物体碰撞	birdBody->setGravityEnable(false);   //设置是否被重力影响,准备画面中不受重力影响	birdSprite->setPhysicsBody(birdBody); //为小鸟设置刚体	//添加两个land	land1 = Sprite::createWithSpriteFramename("land.png");	land1->setAnchorPoint(Point::ZERO);	land1->setposition(Point::ZERO);	this->addChild(land1,10);  //置于最顶层	land2 = Sprite::createWithSpriteFramename("land.png");	land2->setAnchorPoint(Point::ZERO);	land2->setposition(Point::ZERO);	this->addChild(land2,10);	//设置地板刚体	Node *groundNode = Node::create();	auto groundBody = PhysicsBody::create@R_419_6951@(Size(visibleSize.wIDth,land1->getContentSize().height));	groundBody->setDynamic(false);	groundBody->setContactTestBitmask(1);	groundNode->setAnchorPoint(Vec2::ANCHOR_MIDDLE); //物理引擎中的刚体只允许结点锚点设置为中心	groundNode->setPhysicsBody(groundBody);	groundNode->setposition(visibleOrigin.x + visibleSize.wIDth / 2,land1->getContentSize().height / 2);	this->addChild(groundNode);	//设置界面顶部刚体	Node * UpgroundNode = Node::create();	auto UpgroudBody = PhysicsBody::create@R_419_6951@(Size(visibleSize.wIDth,1));	UpgroudBody->setDynamic(false);	UpgroudBody->setcategoryBitmask(1);	UpgroundNode->setAnchorPoint(Vec2::ANCHOR_MIDDLE);	UpgroundNode->setPhysicsBody(UpgroudBody);	UpgroundNode->setposition(visibleOrigin.x + visibleSize.wIDth / 2,visibleSize.height+0.5f);	this->addChild(UpgroundNode);	//记分牌,在最外层,这里懒得弄图片文字了^_^	scoreLabel = LabelTTF::create("0","Felt",35);	scoreLabel->setposition(visibleOrigin.x + visibleSize.wIDth / 2,visibleOrigin.y + visibleSize.height / 2 + 200);	scoreLabel->setVisible(false); //一开始隐藏	this->addChild(scoreLabel);	//添加碰撞监测	auto contactListener = EventListenerPhysicsContact::create();	contactListener->onContactBegin = CC_CALLBACK_1(GameScene::onContactBegin,this);	_eventdispatcher->addEventListenerWithSceneGraPHPriority(contactListener,this);	//添加触摸监听	auto touchListener = EventListenertouchOneByOne::create();	touchListener->ontouchBegan = CC_CALLBACK_2(GameScene::ontouchBegan,this);	touchListener->ontouchended = CC_CALLBACK_2(GameScene::ontouchended,this);	_eventdispatcher->addEventListenerWithSceneGraPHPriority(touchListener,this);	return true;}//设置层的物理世界voID GameScene::setPhysicWorld(PhysicsWorld *world){	m_physicWorld = world;}//游戏开始voID GameScene::gameStart(){	gameStatus = GAME_START;	score = 0;//重置分数	scoreLabel->setString(String::createWithFormat("%d",score)->getCString());	this->getChildByname("logo")->setVisible(false); //logo消失	scoreLabel->setVisible(true); //计分开始	this->scheduleUpdate();//启动默认更新	this->schedule(schedule_selector(GameScene::scrollLand),0.01f); //启动管子和地板滚动	birdSprite->stopAction(swingAction); //游戏开始后停止上下浮动	birdSprite->getPhysicsBody()->setGravityEnable(true); //开始受重力作用}//游戏结束voID GameScene::gameOver(){	gameStatus = GAME_OVER;	//获取历史数据	bestscore = UserDefault::getInstance()->getIntegerForKey("BEST");	if (score > bestscore)	{		bestscore = score;  //更新最好分数		UserDefault::getInstance()->setIntegerForKey("BEST",bestscore);	}	SimpleAudioEngine::getInstance()->playEffect("hit.mp3");	//游戏结束后停止地板和管道的滚动	this->unschedule(schedule_selector(GameScene::scrollLand));}//碰撞监测bool GameScene::onContactBegin(const PhysicsContact& contact){	if (gameStatus == GAME_OVER)  //当游戏结束后不再监控碰撞		return false;	gameOver();//如果游戏状态不是GAMEOVER就调用gameOver函数来设置碰撞后游戏结束的信息	return true;}//触摸监听bool GameScene::ontouchBegan(touch *touch,Event *event){	switch (gameStatus)	{	case GAME_OVER:		break;	case GAME_READY:	{		gameStart();		birdSprite->getPhysicsBody()->setVeLocity(Vec2(0,100)); //给一个向上的初速度		SimpleAudioEngine::getInstance()->playEffect("wing.mp3");		//这里也要写,不然touchx的值是未知值,负无穷,导致BUG		touchX = touch->getLocation().x;	}		break;	case GAME_START:	{		auto curVeLocity = birdSprite->getPhysicsBody()->getVeLocity();		birdSprite->getPhysicsBody()->setVeLocity(Vec2(0,100 > (curVeLocity.y + 500) ? (curVeLocity.y + 500) : 100)); //向上的速度受下降影响		SimpleAudioEngine::getInstance()->playEffect("wing.mp3");		//开上帝视角,留个后门,嘿嘿		touchX = touch->getLocation().x;	}		break;	default:		break;	}	return true;}voID GameScene::ontouchended(touch *touch,Event *event){	//当触摸点滑动超过100,分数瞬间涨100	if (touch->getLocation().x - touchX > 100)	{		score += 100;		scoreLabel->setString(String::createWithFormat("%d",score)->getCString());		SimpleAudioEngine::getInstance()->playEffect("point.mp3");	}}//地板滚动自定义计时器回调voID GameScene::scrollLand(float dt){	Size visibleSize = Director::getInstance()->getVisibleSize();	//两个图片循环移动	land1->setpositionX(land1->getpositionX() - 1.0f);	land2->setpositionX(land1->getpositionX() + land1->getContentSize().wIDth - 2.0f);	if (land2->getpositionX() <= 0)		land1->setposition(Point::ZERO);		//管子滚动	for (auto &singlePipe : pipes)	{		singlePipe->setpositionX(singlePipe->getpositionX() - 1.0f);//每次向左移动一个单位		if (singlePipe->getpositionX() < -PIPE_WIDTH / 2)//如果管子完全移除了界面		{			singlePipe->setpositionX(visibleSize.wIDth + PIPE_WIDTH / 2);//设置管子从界面右侧进入			singlePipe->setpositionY(getRandomHeight());//Y的位置设置为随机值			singlePipe->setname("newPipe");  //每次重设一根管子,标为new		}	}}//获取随机高度,用于管道int GameScene::getRandomHeight(){	auto size = Director::getInstance()->getVisibleSize();	//使得单根管子纵向坐标在屏幕中心点-(40~270)中间随机波动,这个是自己试出来的	return size.height / 2 - 40 - CCRANDOM_0_1() * (270 - 40);}//创建管道 voID GameScene::createPipes(){	//同屏幕出现的只有两根管子,放到容器里面,上下绑定为一根	for (int i = 0; i < 2; i++)	{		auto visibleSize = Director::getInstance()->getVisibleSize();		Sprite *pipeUp = Sprite::createWithSpriteFramename("pipe_up.png");		Sprite *pipeDown = Sprite::createWithSpriteFramename("pipe_down.png");		Node *singlePipe = Node::create();		//给上管绑定刚体		auto pipeUpBody = PhysicsBody::create@R_419_6951@(pipeUp->getContentSize());		pipeUpBody->setDynamic(false);		pipeUpBody->setContactTestBitmask(1);		pipeUp->setAnchorPoint(Vec2::ANCHOR_MIDDLE);		pipeUp->setPhysicsBody(pipeUpBody);		//给两个管子分开设置刚体,可以留出中间的空隙使得小鸟通过		//给下管绑定刚体		auto pipeDownBody = PhysicsBody::create@R_419_6951@(pipeDown->getContentSize());		pipeDownBody->setDynamic(false);		pipeDownBody->setContactTestBitmask(1);		pipeDown->setAnchorPoint(Vec2::ANCHOR_MIDDLE);		pipeDown->setPhysicsBody(pipeDownBody);		pipeUp->setposition(0,PIPE_HEIGHT + PIPE_SPACE);//上面管子设置在Y为管子的高度和管子空隙高度之和(相对于父节点,也就是singlePipe)		singlePipe->addChild(pipeUp);		//下面管子pipeDown没有设置位置,就是设置在默认位置(0,0)		singlePipe->addChild(pipeDown);  //pipeDown默认加到(0,0),上下合并,此时singlePipe以下面的管子中心为锚点,此时singlePipe由两个管子组合而成		singlePipe->setposition(i*PIPE_INTERVAL + WAIT_disTANCE,getRandomHeight()); //设置初始位置,X方向为等待距离和管子间隔之和,Y设置为随机位置		singlePipe->setname("newPipe");		this->addChild(singlePipe);  //把两个管子都加入到层		pipes.pushBack(singlePipe);  //两个管子先后添加到容器	}}//默认的更新函数voID GameScene::update(float dt){	//当游戏开始时,判断得分,这个其实也可以写在其他地方,比如管子滚动的更新函数里面或者触摸监测里面	if (gameStatus == GAME_START)	{		for (auto &pipe : pipes)		{			if (pipe->getname() == "newPipe") //新来一根管子就判断			{				if (pipe->getpositionX() < birdSprite->getpositionX())				{					score++;					scoreLabel->setString(String::createWithFormat("%d",score)->getCString());					SimpleAudioEngine::getInstance()->playEffect("point.mp3");					pipe->setname("passed"); //标记已经过掉的管子				}			}		}	}	//小鸟的旋转	auto curVeLocity = birdSprite->getPhysicsBody()->getVeLocity();	birdSprite->setRotation(-curVeLocity.y*0.1 - 20);  //根据竖直方向的速度算出旋转角度,逆时针为负	auto visibleSize = Director::getInstance()->getVisibleSize();	if (birdSprite->getpositionY() <= land1->getContentSize().height + BIRD_RADIUS )			{		birdSprite->stopAllActions(); //小鸟挂了就不能再扇翅了		birdSprite->setRotation(70);  //设置为嘴朝下,顺时针70度旋转		birdSprite->getPhysicsBody()->setDynamic(false);  //设置为不动了		SimpleAudioEngine::getInstance()->playEffect("dIE.mp3");		this->unscheduleUpdate();  //在小鸟掉到地面上再停止默认更新		gamePanelAppear();  //d出记分牌	}}//加入记分板和重玩菜单voID GameScene::gamePanelAppear(){	Size size = Director::getInstance()->getVisibleSize();	Vec2 origin = Director::getInstance()->getVisibleOrigin();	//用node将gameoverlogo和记分板绑在一起	Node *gameOverPanelNode = Node::create();		auto gameOverLabel = Sprite::createWithSpriteFramename("gameover.png");	gameOverPanelNode->addChild(gameOverLabel);	auto panel = Sprite::createWithSpriteFramename("board.PNG");//注意这里是大写PNG,原图片用什么后缀这里就用什么,区分大小写	gameOverLabel->setpositionY(panel->getContentSize().height); //设置一下坐标	gameOverPanelNode->addChild(panel);	//记分板上添加两个分数	auto curscoreTTF = LabelTTF::create(String::createWithFormat("%d",score)->getCString(),"Arial",20);	curscoreTTF->setposition(panel->getContentSize().wIDth - 40,panel->getContentSize().height - 45);	curscoreTTF->setcolor(color3B(255,0));	panel->addChild(curscoreTTF);	auto bestscoreTTF = LabelTTF::create(String::createWithFormat("%d",bestscore)->getCString(),20);	bestscoreTTF->setposition(panel->getContentSize().wIDth - 40,panel->getContentSize().height - 90);	bestscoreTTF->setcolor(color3B(0,255,0));	panel->addChild(bestscoreTTF);	this->addChild(gameOverPanelNode);	gameOverPanelNode->setposition(origin.x + size.wIDth / 2,origin.y + size.height);	//滑入动画	gameOverPanelNode->runAction(Moveto::create(0.5f,Vec2(origin.x + size.wIDth / 2,origin.y + size.height / 2)));	SimpleAudioEngine::getInstance()->playEffect("swooshing.mp3");	//添加菜单	auto start_bt = Sprite::createWithSpriteFramename("start_btn.png");	auto pressed_bt = Sprite::createWithSpriteFramename("start_btn_pressed.png");	auto restartItem = MenuItemSprite::create(start_bt,NulL,this,menu_selector(GameScene::gameRetart));//调用重新开启游戏函数	restartItem->setposition(Vec2(size.wIDth / 2 + origin.x,size.height / 2 - 1.5* restartItem->getContentSize().height));	auto menu = Ccmenu::createWithItem(restartItem);	menu->setposition(Vec2::ZERO);	this->addChild(menu,10);}//游戏重新开始voID GameScene::gameRetart(Ref *sender){	//重新回到初始画面	auto gameScene = GameOver::createScene();//切换到GameOver场景	Director::getInstance()->replaceScene(gameScene);  	 }



最后是GameOver场景,可以退出游戏或者继续游戏:


#ifndef __GAMEOVER_H__#define __GAMEOVER_H__//#include "@R_419_6951@2D/@[email protected]"#include "cocos2d.h"USING_NS_CC;class GameOver : public cocos2d::Layer{	voID scrollLand(float dt);	Sprite *land1;	Sprite *land2;	//b2World *world;public:	// there's no 'ID' in cpp,so we recommend returning the class instance pointer	static cocos2d::Scene* createScene();	virtual voID update(float delta);	voID myupdate(float delta);	// Here's a difference. Method 'init' in cocos2d-x returns bool,instead of returning 'ID' in cocos2d-iphone	virtual bool init();	// a selector callback	voID menuReStartCallback(cocos2d::Ref* pSender);	voID menuGameOverCallback(cocos2d::Ref* pSender);	//voID scrollLand(float dt);	// implement the "static create()" method manually	CREATE_FUNC(GameOver);};#endif // __HELLOWORLD_SCENE_H__#include "HelloWorldScene.h"#include "SceneOne.h"#include "GameOver.h"#include "GameScene.h"USING_NS_CC;Scene* GameOver::createScene(){	// 'scene' is an autorelease object	auto scene = Scene::create();	// 'layer' is an autorelease object	auto layer = GameOver::create();	// add layer as a child to scene	scene->addChild(layer);	// return the scene	return scene;}bool GameOver::init(){		if (!Layer::init())	{		return false;	} 	Size visibleSize = Director::getInstance()->getVisibleSize();	Vec2 origin = Director::getInstance()->getVisibleOrigin();	 	auto label = Label::createWithTTF("GameOver_Scene",24);	 	label->setposition(Vec2(origin.x + visibleSize.wIDth / 2,origin.y + visibleSize.height - label->getContentSize().height));	//this->addChild(label); 	SpriteFrameCache::getInstance()->addSpriteFramesWithfile("game.pList");//使用pList文件来加载精灵帧	auto background = Sprite::createWithSpriteFramename("bg.png");//使用精灵帧名字来初始化背景	background->setposition(Vec2(visibleSize.wIDth / 2 + origin.x,visibleSize.height / 2 + origin.y));	this->addChild(background,0);	auto gameoverSprite = Sprite::createWithSpriteFramename("gameover.png");//设置gameover图标	gameoverSprite->setposition(Vec2(visibleSize.wIDth/2,2*visibleSize.height/3));	this->addChild(gameoverSprite,1); 	auto start_bt = Sprite::createWithSpriteFramename("start_btn.png");//初始化两个按钮精灵	auto pressed_bt = Sprite::createWithSpriteFramename("start_btn_pressed.png");	//设置菜单精灵,并调用重启游戏回调函数	auto reStartItem = MenuItemSprite::create(		start_bt,CC_CALLBACK_1(GameOver::menuReStartCallback,this));	reStartItem->setposition(Vec2(visibleSize.wIDth / 2 + origin.x,visibleSize.height / 2 - background->getpositionY() + 3 * reStartItem->getContentSize().height));	 	auto menu = Menu::create(reStartItem,NulL);//使用菜单精灵创建菜单	menu->setposition(Vec2::ZERO);	this->addChild(menu,101);	auto GameOverlabel = Label::createWithTTF("EXIT","Fonts/arial.ttf",24);//设置退出菜单,调用退出游戏回掉函数	auto gameOverItem = MenuItemLabel::create(GameOverlabel,CC_CALLBACK_1(GameOver::menuGameOverCallback,this));	gameOverItem->setposition(Vec2(visibleSize.wIDth / 2 + origin.x,visibleSize.height / 2 - background->getpositionY() + 4 * gameOverItem->getContentSize().height));	auto gameovermenu = Menu::create(gameOverItem,NulL);	gameovermenu->setposition(Vec2::ZERO);	this->addChild(gameovermenu,101); 	return true;}voID GameOver::menuReStartCallback(Ref* pSender){#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)	Message@R_419_6951@("You pressed the close button. windows Store Apps do not implement a close button.","Alert");	return;#endif	auto scene = GameScene::createScene();//初始化游戏场景	auto Transition = TransitionFade::create(1,scene);	// run	Director::getInstance()->replaceScene(Transition);#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)	exit(0);#endif}voID GameOver::menuGameOverCallback(cocos2d::Ref* pSender){#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)	Message@R_419_6951@("You pressed the close button. windows Store Apps do not implement a close button.","Alert");	return;#endif 	Director::getInstance()->end();//直接退出#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)	exit(0);#endif}voID GameOver::scrollLand(float dt){	this->land1->setpositionX(this->land1->getpositionX() - 2.0f);	this->land2->setpositionX(this->land1->getpositionX() + this->land1->getContentSize().wIDth - 2.0f);	if (this->land2->getpositionX() == 0) {		this->land1->setpositionX(0);	}}voID GameOver::update(float delta){	int posLand1 = land1->getpositionX();	int posLand2 = land2->getpositionX();	int speed = 1;	posLand1 -= speed;	posLand2 -= speed;	auto landsize = land2->getContentSize();	if (posLand1 < -landsize.wIDth / 2 + 142)	{		posLand2 = landsize.wIDth / 2;		posLand1 = landsize.wIDth + landsize.wIDth / 2;	}	if (posLand2 < -landsize.wIDth / 2 + 142)	{		posLand1 = landsize.wIDth / 2;		posLand2 = landsize.wIDth + landsize.wIDth / 2;	}	land1->setpositionX(posLand1);	land2->setpositionX(posLand2);}voID GameOver::myupdate(float delta){	int posLand1 = land1->getpositionX();	int posLand2 = land2->getpositionX();	int speed = 1;	posLand1 -= speed;	posLand2 -= speed;	auto landsize = land2->getContentSize();	if (posLand1 < -landsize.wIDth / 2 + 142)	{		posLand2 = landsize.wIDth / 2;		posLand1 = landsize.wIDth + landsize.wIDth / 2;	}	if (posLand2 < -landsize.wIDth / 2 + 142)	{		posLand1 = landsize.wIDth / 2;		posLand2 = landsize.wIDth + landsize.wIDth / 2;	}	land1->setpositionX(posLand1);	land2->setpositionX(posLand2);}

参考博文:http://blog.csdn.net/u012234115/article/details/40487557


APK下载地址:https://github.com/Tingmaobaobei/Fly_Bird-1/blob/22d3739f0c635548f3e51848e674424d8f01a58d/bin/deBUG/androID/happybird-deBUG.apk;

源码下载地址:https://github.com/Tingmaobeobei/Fly_Bird/commit/22d3739f0c635548f3e51848e674424d8f01a58d

图片资源下载地址:https://github.com/Tingmaobeobei/Fly_Bird/commit/cbc061673883db1824d5bec76753b8eaa9150039

总结

以上是内存溢出为你收集整理的Cocos2d-x3.5 设计Fly_bird(飞行小鸟)并打包成APK文件全部内容,希望文章能够帮你解决Cocos2d-x3.5 设计Fly_bird(飞行的小鸟)并打包成APK文件所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1060988.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存