Cocos2d 之FlyBird开发---GamePlay类
| 版权声明:本文为博主原创文章,未经博主允许不得转载。
这个是游戏的核心部分:(FlyBird游戏重中之重)
- 创建一个物理世界(世界设置重力加速度)
- 在物理世界中添加一个动态的刚体(小鸟)
- 在物理世界中添加一个静态的刚体(地板)和一个顶部边界(Edge)
- 在物理世界中添加一对浮动的刚体(Pipe),并设置线速度
- 设置每次点击屏幕小鸟上升的加速度
- 碰撞检测,判断游戏是否结束
下面贴上代码:
GamePlay.h
#ifndef _GAME_PLAY_H_
#define _GAME_PLAY_H_ #define PTM_RATIO 32 #include "cocos2d.h"
#include "Box2D\Box2D.h"
#include "SimpleAudioEngine.h" //背景音乐平台控制
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
#define MUSIC_FILE "music/background.wav"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_BLACKBERRY || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
#define MUSIC_FILE "music/background.ogg"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
#define MUSIC_FILE "music/background.caf"
#else
#define MUSIC_FILE "music/background.mp3"
#endif // CC_PLATFOR_WIN32 USING_NS_CC;
using namespace CocosDenshion; class GamePlay : public cocos2d::Layer, public b2ContactListener
{
private:
cocos2d::Sprite* backgroundA;
cocos2d::Sprite* backgroundB;
cocos2d::Sprite* ready;
cocos2d::Sprite* tutorial;
cocos2d::Sprite* bird;
cocos2d::Sprite* land;
cocos2d::Sprite* num;
cocos2d::Sprite* upPipe;
cocos2d::Sprite* downPipe;
cocos2d::Sprite* pipeContainer;
cocos2d::Sprite* model;
cocos2d::Sprite* gameEnd;
cocos2d::LabelTTF* score;
cocos2d::LabelTTF* best;
cocos2d::MenuItemImage* play;
cocos2d::MenuItemImage* exit;
b2World* world;
b2Body* birdBody;
b2Body* landBody;
b2Body* downBody;
b2Body* upBody;
int bestScore;
int times = 0; private:
void replaceBackground(int);
void tipInformation();
void addBird();
void addLand();
void addPipe(float dt);
void gameBegin(float dt);
void gameOver();
void timeAnimate();
void upperBoundary();
//int birdSelect(float); public:
static cocos2d::Scene* createScene();
virtual bool init();
void initPhysicsWorld();
virtual void update(float);
/// Called when two fixtures begin to touch.
virtual void BeginContact(b2Contact* contact);
/** Callback function for multiple touches began.
*
* @param touches Touches information.
* @param unused_event Event information.
* @js NA
*/
virtual void onTouchesBegan(const std::vector<Touch*>& touches, Event *unused_event);
void goPlay(cocos2d::Ref* pSender);
void goExit();
CREATE_FUNC(GamePlay);
}; #endif // _GAME_PLAY_H_
GamePlay.cpp
#include "GamePlay.h"
#include "GameUnit.h"
#include "GameData.h" unit u3; cocos2d::Scene* GamePlay::createScene()
{
auto scene = Scene::create();
auto layer = GamePlay::create();
scene->addChild(layer);
return scene;
} bool GamePlay::init()
{
if (!Layer::init())
{
return false;
}
SimpleAudioEngine::getInstance()->playBackgroundMusic(MUSIC_FILE, true);
this->initPhysicsWorld();
this->replaceBackground(1);
this->tipInformation();
this->upperBoundary();
this->addLand();
this->addBird();
this->timeAnimate();
//this->addPipe(); //设置多点触屏事件的监听器
auto listener = EventListenerTouchAllAtOnce::create();
listener->onTouchesBegan = CC_CALLBACK_2(GamePlay::onTouchesBegan, this);
//注册监听器
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); //设置物理世界监听
world->SetContactListener(this); scheduleOnce(schedule_selector(GamePlay::gameBegin), 3);
//scheduleUpdate(); return true;
} void GamePlay::initPhysicsWorld()
{
//设置重力加速度为9.8;方向向下
b2Vec2 gravity;
gravity.Set(0.0f, -9.8f);
//创建一个新的物理世界
world = new b2World(gravity); //设置是否允许物体休眠
world->SetAllowSleeping(true);
//连续物理测试,防止发生非子弹特性的物体发生穿透现象
world->SetContinuousPhysics(true);
} void GamePlay::timeAnimate()
{
num = Sprite::create("bird/n1.png");
num->setPosition(Vec2(u3.winOrigin().x + u3.winSize().width / 2,
u3.winOrigin().y + (4 * u3.winSize().height) / 5));
num->setScale(2);
auto repeat = Repeat::create(Animate::create(u3.gameAnimate(4)), 1);
num->runAction(repeat);
this->addChild(num, 1);
} void GamePlay::replaceBackground(int flag)
{
switch (flag)
{
case 1:
backgroundA = Sprite::create("background/light.png");
backgroundA->setPosition(Vec2(u3.winOrigin().x + u3.winSize().width / 2,
u3.winOrigin().y + u3.winSize().height / 2));
backgroundA->setScale(u3.scaleX(backgroundA, u3.winSize()),
u3.scaleY(backgroundA, u3.winSize()));
this->addChild(backgroundA, 0);
break;
case 2:
backgroundB = Sprite::create("background/night.png");
backgroundB->setPosition(Vec2(u3.winOrigin().x + u3.winSize().width / 2,
u3.winOrigin().y + u3.winSize().height / 2));
backgroundB->setScale(u3.scaleX(backgroundB, u3.winSize()),
u3.scaleY(backgroundB, u3.winSize()));
this->addChild(backgroundB, 0);
break;
default:
break;
}
} void GamePlay::tipInformation()
{
ready = Sprite::create("logo/text_ready.png");
ready->setPosition(Vec2(u3.winOrigin().x + u3.winSize().width / 2,
u3.winOrigin().y + u3.winSize().height - 3*ready->getContentSize().height));
ready->setScale(2);
this->addChild(ready, 1); tutorial = Sprite::create("logo/tutorial.png");
tutorial->setPosition(Vec2(u3.winOrigin().x + u3.winSize().width / 2,
u3.winOrigin().y + u3.winSize().height / 2));
tutorial->setScale(2);
this->addChild(tutorial, 1); //exit
exit = MenuItemImage::create(
"button/exit_f.png",
"button/exit_b.png",
CC_CALLBACK_0(GamePlay::goExit, this)
);
Menu* menu = Menu::create(exit, NULL);
menu->setPosition(Vec2(u3.winOrigin().x + exit->getContentSize().width / 2,
u3.winOrigin().y + exit->getContentSize().height / 2));
this->addChild(menu, 7);
} void GamePlay::addBird()
{
bird = Sprite::create("bird/littleBird.png");
bird->setPosition(Vec2(u3.winOrigin().x + u3.winSize().width / 3,
u3.winOrigin().y + u3.winSize().height - 5 * (ready->getContentSize().height)));
bird->setScale(1.5);
auto repeat = RepeatForever::create(Animate::create(u3.gameAnimate(1)));
bird->runAction(repeat);
this->addChild(bird, 1); //创建刚体
b2BodyDef birdBodyDef;
birdBodyDef.type = b2_dynamicBody;
birdBodyDef.position.Set(bird->getPosition().x / PTM_RATIO,
bird->getPosition().y / PTM_RATIO);
//将刚体,精灵与世界关联起来
birdBody = world->CreateBody(&birdBodyDef);
birdBody->SetUserData(bird); //定义一个盒子
b2PolygonShape birdBox;
birdBox.SetAsBox(bird->getContentSize().width / 3 / PTM_RATIO,
bird->getContentSize().height / 3 / PTM_RATIO);
//夹具
b2FixtureDef fixtureDef;
//设置夹具的形状
fixtureDef.shape = &birdBox;
birdBody->CreateFixture(&fixtureDef);
} void GamePlay::update(float dt)
{
world->Step(dt, 8, 3);
for (b2Body* bb = world->GetBodyList(); bb; bb = bb->GetNext())
{
if (bb->GetUserData() != nullptr)
{
Sprite* sprite = (Sprite*)bb->GetUserData();
//设置精灵的当前的位置,通过取得精灵的位置乘上相应的像素,这里的PTM_RATIO为32个像素为1m,就可以判断出精灵的位置处于物理世界的何处
sprite->setPosition(Vec2(bb->GetPosition().x*PTM_RATIO,
bb->GetPosition().y*PTM_RATIO));
//设置精灵的角度偏转
sprite->setRotation(0);
}
}
} void GamePlay::onTouchesBegan(const std::vector<Touch*>& touches, Event *unused_event)
{
birdBody->SetLinearVelocity(b2Vec2(0, 5));
//birdBody->SetLinearVelocity(b2Vec2(1, 5));
} //添加地面
void GamePlay::addLand()
{
//地板也是物理世界的一个刚体,是一个静态的刚体
land = Sprite::create("background/land.png");
land->setPosition(Vec2(u3.winOrigin().x + u3.winSize().width / 2,
u3.winOrigin().y + land->getContentSize().height / 2));
land->setScaleX(u3.winSize().width / 1.5*land->getContentSize().width);
land->setScaleY(u3.winSize().height / (land->getContentSize().height * 3));
this->addChild(land, 4); //创建刚体
b2BodyDef landBodyDef;
landBodyDef.type = b2_staticBody;
landBodyDef.position.Set(u3.winSize().width / 2 / PTM_RATIO,
land->getPosition().y / PTM_RATIO); landBody = world->CreateBody(&landBodyDef);
landBody->SetUserData(land); b2PolygonShape landShape;
landShape.SetAsBox(u3.winSize().width / 2 / PTM_RATIO,
backgroundA->getContentSize().height / 2 / PTM_RATIO);
//1.4*land->getContentSize().height / PTM_RATIO
b2FixtureDef landFixtureDef;
landFixtureDef.shape = &landShape;
landBody->CreateFixture(&landFixtureDef);
} void GamePlay::upperBoundary()
{
b2BodyDef upperBodyDef;
//左下角
upperBodyDef.position.Set(0, 0);
//创建地面物体
b2Body* upperBody = world->CreateBody(&upperBodyDef);
//定义一个有边的形状
b2EdgeShape upperBox; //顶部边界线
upperBox.Set(b2Vec2(0, u3.winSize().height / PTM_RATIO),
b2Vec2(u3.winSize().width / PTM_RATIO, u3.winSize().height / PTM_RATIO));
upperBody->CreateFixture(&upperBox, 0);
} void GamePlay::addPipe(float dt)
{
times++; float randPipe = -rand() % 3;
//down bar
downPipe = Sprite::create("pipe/down.png");
downPipe->setScaleY(u3.winSize().height / (downPipe->getContentSize().height*1.5));
this->addChild(downPipe, 3);
b2BodyDef downBodyDef;
downBodyDef.position = b2Vec2(u3.winSize().width / PTM_RATIO + 2,
downPipe->getContentSize().height / 2 / PTM_RATIO + randPipe);
// + land->getContentSize().height / PTM_RATIO
downBodyDef.type = b2_kinematicBody;
//修改速度可以提升游戏的难度
downBodyDef.linearVelocity = b2Vec2(-2, 0);
downBody = world->CreateBody(&downBodyDef);
downBody->SetUserData(downPipe);
b2PolygonShape downShape;
downShape.SetAsBox(downPipe->getContentSize().width / 2 / PTM_RATIO,
1.6*downPipe->getContentSize().height / PTM_RATIO);
b2FixtureDef downPipeFixture;
downPipeFixture.shape = &downShape;
downBody->CreateFixture(&downPipeFixture); upPipe = Sprite::create("pipe/upPipe.png");
upPipe->setScaleY(u3.winSize().height / (upPipe->getContentSize().height*1.5));
this->addChild(upPipe, 3);
b2BodyDef upBodyDef;
upBodyDef.position = b2Vec2(u3.winSize().width / PTM_RATIO + 2,
downPipe->getContentSize().height / PTM_RATIO + randPipe + 3 +2*upPipe->getContentSize().height / PTM_RATIO);
//
upBodyDef.type = b2_kinematicBody;
//修改速度可以提升游戏的难度
upBodyDef.linearVelocity = b2Vec2(-2, 0);
upBody = world->CreateBody(&upBodyDef);
upBody->SetUserData(upPipe);
b2PolygonShape upShape;
upShape.SetAsBox(upPipe->getContentSize().width / 2 / PTM_RATIO,
1.6*upPipe->getContentSize().height / PTM_RATIO);
b2FixtureDef upPipeFixture;
upPipeFixture.shape = &upShape;
upBody->CreateFixture(&upPipeFixture);
} void GamePlay::gameOver()
{
//显示Game Over的Logo
gameEnd = Sprite::create("logo/gameOver.png");
gameEnd->setPosition(Vec2(u3.winOrigin().x + u3.winSize().width / 2,
u3.winOrigin().y + u3.winSize().height - 3*gameEnd->getContentSize().height));
gameEnd->setScale(2);
this->addChild(gameEnd, 5); //显示奖章牌
model = Sprite::create("logo/score_panel.png");
model->setPosition(Vec2(u3.winOrigin().x + u3.winSize().width / 2,
u3.winOrigin().y + u3.winSize().height / 2));
model->setScale(u3.winSize().width / 1.5 / model->getContentSize().width,
u3.winSize().height / 4.5 / model->getContentSize().height);
this->addChild(model, 5); //奖章
Sprite* award = Sprite::create("logo/medals1.png");
award->setPosition(Vec2(u3.winOrigin().x + u3.winSize().width / 2 - model->getContentSize().width*0.6,
u3.winOrigin().y + u3.winSize().height / 2));
award->setScale(3);
this->addChild(award, 6); //显示成绩
score = LabelTTF::create("0", "Arial", 16);
score->setPosition(Vec2(u3.winOrigin().x + (u3.winSize().width / 3) * 2,
u3.winOrigin().y + u3.winSize().height / 2 + award->getContentSize().height));
this->addChild(score, 7);
//设置字体的颜色为黑色,并将成绩显示在panel面板上
score->setColor(Color3B(0, 0, 0));
score->setString(__String::createWithFormat("%5d", times - 1)->getCString()); bestScore = GameData::getGameData();
best = LabelTTF::create("0", "Arial", 16);
best->setPosition(Vec2(u3.winOrigin().x + (u3.winSize().width / 3) * 2,
u3.winOrigin().y + u3.winSize().height / 2 - 1.5*award->getContentSize().height));
this->addChild(best, 7);
best->setColor(Color3B(0, 0, 0));
best->setString(__String::createWithFormat("%5d", bestScore - 1)->getCString());
GameData::keepGameData(times); unscheduleUpdate();
unschedule(schedule_selector(GamePlay::addPipe));
} void GamePlay::gameBegin(float dt)
{
ready->setVisible(false);
tutorial->setVisible(false);
num->setVisible(false); scheduleUpdate();
//修改时间可以提升游戏的难易程度
schedule(schedule_selector(GamePlay::addPipe), 2);
} void GamePlay::BeginContact(b2Contact* contact)
{
if (contact->GetFixtureA()->GetBody() == birdBody || contact->GetFixtureB()->GetBody() == birdBody)
{
this->gameOver(); play = MenuItemImage::create(
"button/play.png",
"button/play.png",
CC_CALLBACK_1(GamePlay::goPlay, this)
);
play->setPosition(Vec2(u3.winOrigin().x + u3.winSize().width / 2,
u3.winOrigin().y + u3.winSize().height / 3));
Menu* menu = Menu::create(play, NULL);
menu->setPosition(Vec2::ZERO);
menu->setScale(1.5);
this->addChild(menu, 6);
}
} void GamePlay::goPlay(cocos2d::Ref* pSender)
{
times = 0;
Director::getInstance()->replaceScene(TransitionFadeTR::create(1,
GamePlay::createScene()));
} void GamePlay::goExit()
{
times = 0;
unscheduleUpdate();
unschedule(schedule_selector(GamePlay::addPipe)); Director::getInstance()->end();
}
函数功能详见:http://www.cnblogs.com/geore/p/5800009.html
效果图:
Cocos2d 之FlyBird开发---GamePlay类的更多相关文章
- Cocos2d 之FlyBird开发---MainMenu类
| 版权声明:本文为博主原创文章,未经博主允许不得转载. MainMenu类主要实现的是游戏主界面的布局,它相当于一个港口,有开向各处的航道,而游戏中的MainMenu则是有跳转到各个场景的一个集 ...
- Cocos2d 之FlyBird开发---GameUnit类
| 版权声明:本文为博主原创文章,未经博主允许不得转载. 这节来实现GameUnit类中的一些函数方法,其实这个类一般是一个边写边完善的过程,因为一般很难一次性想全所有的能够供多个类共用的方法.下 ...
- Cocos2d 之FlyBird开发---GameData类
| 版权声明:本文为博主原创文章,未经博主允许不得转载. 现在是大数据的时代,绝大多数的游戏也都离不开游戏数据的控制,简单的就是一般记录游戏的得分情况,高端大气上档次一点的就是记录和保存各方面的游 ...
- Cocos2d 之FlyBird开发---GameScore类
| 版权声明:本文为博主原创文章,未经博主允许不得转载. 这个类主要实现的是,显示历次成绩中的最好成绩.当然我写的这个很简洁,还可以写的更加的丰富.下面贴上代码: GameScore.h #ifn ...
- Cocos2d 之FlyBird开发---GameAbout类
| 版权声明:本文为博主原创文章,未经博主允许不得转载.(笔者才疏学浅,如有错误,请多多指教) 一般像游戏关于的这种界面中,主要显示的是游戏的玩法等. GameAbout.h #ifndef _G ...
- Cocos2d之FlyBird开发---简介
| 版权声明:本文为博主原创文章,未经博主允许不得转载. 开发FlyBird其实非常的简单,在游戏的核心部分,我们需要实现的只有: 创建一个物理世界(世界设置重力加速度) 在物理世界中添加一个动态 ...
- JAVA串口开发帮助类分享-及写在马年末
摘要: 在系统集成开发过程中,存在着各式的传输途径,其中串口经常因其安全性高获得了数据安全传输的重用,通过串口传输可以从硬件上保证数据传输的单向性,这是其它介质所不具备的物理条件.下面我就串口java ...
- iOS cocos2d 2游戏开发实战(第3版)书评
2013是游戏爆发的一年,手游用户也是飞速暴增.虽然自己不做游戏,但也是时刻了解手机应用开发的新动向.看到CSDN的"写书评得技术图书赢下载分"活动,就申请了一本<iOS c ...
- (转载)实例详解Android快速开发工具类总结
实例详解Android快速开发工具类总结 作者:LiJinlun 字体:[增加 减小] 类型:转载 时间:2016-01-24我要评论 这篇文章主要介绍了实例详解Android快速开发工具类总结的相关 ...
随机推荐
- 10: Django + Uwsgi + Nginx 的生产环境部署
1.1 一些重要概念 1.Web协议介绍 Web协议出现顺序: CGI -> FCGI -> WSGI -> uwsgi 1. CGI: 最早的协议 2. FCGI: 比CGI快 ...
- redis缓存架构-03-redis下的replication以及master+slave
1.master和slave的读写分离(水平扩容支持读高并发) 2.master主从复制流程 master开始复制给slave前的认证流程 master向slave复制流程 2.1 无磁盘化复制配置 ...
- 6个常用Java 源代码 保护工具(混淆、加密、底层)
6个常用Java 源代码 保护工具(混淆.加密.底层) ProGuard Java源代码保护工具ProGuard的3.6与4.1版 下载地址:http://download.csdn.net/sou ...
- 标签的增加、删除与复制,动态标签js不生效的解决
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 常用颜色的RGB分布
RGB色彩模式是工业界的一种颜色标准,它通过对红(RED).绿(GREEN).蓝(BLUE)三种基本颜色的相互组合从而叠加出各种颜色.RGB色彩模式为每一个红.绿.蓝分类了0-255范围内的亮度值. ...
- ubuntu-12.04.5-desktop-amd64 安装vmwaretools
百度文库地址:https://wenku.baidu.com/view/7c1cd211a216147917112820.html 注意:一定要把此文档中的vmwaretools 版本号换成你自己下载 ...
- ViewMode
一.ViewMode 实现使用场景-Model枚举的情景下, 注意:枚举声明在后台的时候,需要渲染界面,页面表格使用 Bootstrap Table插件-事先通过ajax 渲染(数据库读取值1.2.3 ...
- Java并发(基础知识)—— Java中断机制
上文讲解了Java线程的创建.启动以及停止,在讲到停止线程时说到了Java中断,Java中断是停止线程的一种协作机制,本文打算对Java中断机制进行详细讲解. 在网上搜索Java中断机制,发现两篇好文 ...
- 人生苦短_我用Python_Try_Exception异常捕捉_007
# coding=utf-8 ''' request+try__异常处理 ''' import requests class HttpRequests: def __init__(self, url, ...
- js DOM0级事件和DOM2级事件
注册事件有两种方式,分别是DOM0级和DOM2级 DOM0级就是通过事件绑定的形式dom元素只能有(绑定)一个事件处理函数,他的特点是同一个元素绑定相同事件, 后面函数会覆盖前面的 绑定: dom.o ...