Cocos2d-x 2.3.3版本 FlappyBird
  本篇博客基于Cocos2d-x 2.3.3, 介绍怎样开发一款之前非常火的一款游戏FlappyBird。本篇博客内容大纲例如以下:
  1. 怎样创建Cocos2d-x 2.3.3 项目
  2. 初始化Box2d物理世界,并模拟物理世界
  3. 怎样加入小鸟到物理世界
  4. 怎样加入地板
  5. 加入水管
  6. 碰撞检測
  7. 本文总结
效果图:

1. 怎样创建Cocos2d-x 2.3.3

本篇博客是基于Cocos2d-x 2.3.3,刚開始学习的人能够选择这个版本号学习,也能够从3.x版本号学习。但版本号差异较大。

用命令行进入文件夹D:\cocos2d-x-2.2.3\tools\project-creator,敲入下面命令创建项目:
python create_project.py -project FlappyBirdCpp -package com.wwj.flappybird -language cpp
创建了名为FlappyBirdCpp的Cocos2d-x项目。包名为com.wwj.flappybird,开发语言为c++

2. 初始化Box2d物理世界,并模拟物理世界

Cocos2d-x使用了Box2d物理引擎来模拟物理世界,它还支持Chipmunk物理引擎。这里我们使用Box2d来为我们创建一个看似比較真实的世界。
// -10表示重力加速度方向为向下
world = new b2World(b2Vec2(0, -10));

// 模拟物理世界
// Box2D建议的迭代次数是速度阶段8次,位置阶段3次
world->Step(dt, 8, 3);

3. 怎样加入小鸟到物理世界

小鸟在Cocos2d-x就是一个Sprite(精灵),我们知道精灵是须要加入到层其中的。我们还要设置我们小鸟在物理世界的刚体。

关于Box2d相关的概念。笔者在这里不具体说,读者能够自己找百度老师。学习很多其它关于Box2d的知识。

我们定义下面方法:
/**
* 加入小鸟
*
*/
void HelloWorld::addBird()
{
// 创建小鸟
bird = B2Sprite::create("bird.png");
// 获取内容大小
CCSize size = bird->getContentSize(); // 刚体属性
b2BodyDef bodyDef;
// 动态刚体
bodyDef.type = b2_dynamicBody;
// 设置初始位置
bodyDef.position = b2Vec2(screenSize.width/2/RATIO, screenSize.height/2/RATIO);
// 创建一个小鸟刚体
b2Body *birdBody = world->CreateBody(&bodyDef); // 隐形形状
b2PolygonShape birdShape;
// 设置为盒子。參数为内容的半宽半高
birdShape.SetAsBox(size.width/2/RATIO, size.height/2/RATIO); // 材料属性
b2FixtureDef birdFixtureDef;
// 形状
birdFixtureDef.shape = &birdShape;
// 加入地表物体
birdBody->CreateFixture(&birdFixtureDef); // 设置度量比例
bird->setPTMRatio(RATIO);
// 设置小鸟刚体
bird->setB2Body(birdBody);
// 加入小鸟到层中
addChild(bird); }

4. 怎样加入地板

地板跟小鸟也是相似的。仅仅是设置地板刚体的类型为静态的。由于它相对精巧的也不受重力影响。

/**
* 加入地板
*/
void HelloWorld::addGround()
{
// 地板精灵
B2Sprite *ground = B2Sprite::create("ground.png");
// 得到地板内容的大小
CCSize size = ground->getContentSize(); // 用于初始化刚体在物理世界的一些属性。比方位置,类型
b2BodyDef bDef;
// 静态的刚体
bDef.type = b2_staticBody;
// 设置位置
bDef.position = b2Vec2(size.width/2/RATIO, size.height/2/RATIO);
// 创建刚体
b2Body *groundBody = world->CreateBody(&bDef); // 形状
b2PolygonShape groundShape;
// 设置为矩形
groundShape.SetAsBox(size.width/2/RATIO, size.height/2/RATIO);
// 材料定制器
b2FixtureDef groundFixtureDef;
// 设置形状
groundFixtureDef.shape = &groundShape;
// 创建定制器
groundBody->CreateFixture(&groundFixtureDef);
// 为精灵设置刚体
ground->setB2Body(groundBody);
// 设置度量比例
ground->setPTMRatio(RATIO);
// 加入地板到层其中
addChild(ground); }

5. 加入水管

我们玩FlappyBird的时候,会知道水管高低不同,然后是从右往左运动的,这就须要我们随机设置上下两根水管的位置了,而且不停的加入水管。
/ 加入运动的水管
void HelloWorld::addBar(float dt) {
// 随机生成偏移量
float offset = -rand() %5; // 创建向下水管的精灵
B2Sprite *down_bar = B2Sprite::create("down_bar.png");
// 得到水管的大小
CCSize down_bar_size = down_bar->getContentSize(); // 下水管
b2BodyDef down_bar_body_def;
// 运动学物体,但不受重力影响
down_bar_body_def.type = b2_kinematicBody;
// 设置下水管的位置
down_bar_body_def.position = b2Vec2(screenSize.width/RATIO + 2, down_bar_size.height/RATIO/2 +offset);
// 线性速度,从右往左移动
down_bar_body_def.linearVelocity = b2Vec2(-5,0);
// 创建刚体
b2Body *down_bar_body = world->CreateBody(&down_bar_body_def); // 隐形形状
b2PolygonShape down_bar_shape;
// 设置为盒子,參数为内容的半宽半高
down_bar_shape.SetAsBox(down_bar_size.width/2/RATIO, down_bar_size.height/2/RATIO);
// 声明定制器
b2FixtureDef down_bar_fixture_def;
// 定制器形状
down_bar_fixture_def.shape = &down_bar_shape;
// 为刚体创建定制器
down_bar_body->CreateFixture(&down_bar_fixture_def); // 设置精灵刚体
down_bar->setB2Body(down_bar_body);
// 设置度量
down_bar->setPTMRatio(RATIO); // 上水管
B2Sprite *up_bar = B2Sprite::create("up_bar.png");
// 获得内容大小
CCSize up_bar_size = up_bar->getContentSize(); b2BodyDef up_bar_body_def;
// 运动学物体。但不受重力影响
up_bar_body_def.type = b2_kinematicBody;
// 设置水管位置
up_bar_body_def.position = b2Vec2(screenSize.width/RATIO+2, down_bar_size.height/RATIO+offset+2+up_bar_size.height/2/RATIO);
up_bar_body_def.linearVelocity = b2Vec2(-5, 0);
b2Body *up_bar_body = world->CreateBody(&up_bar_body_def); // 隐形形状
b2PolygonShape up_bar_shape;
// 设置为盒子形状,參数为半宽半高
up_bar_shape.SetAsBox(up_bar_size.width/2/RATIO, up_bar_size.height/2/RATIO);
b2FixtureDef up_bar_fixture_def;
up_bar_fixture_def.shape = &up_bar_shape;
up_bar_body->CreateFixture(&up_bar_fixture_def);
up_bar->setB2Body(up_bar_body);
up_bar->setPTMRatio(RATIO); barContainer->addChild(down_bar);
barContainer->addChild(up_bar); }

6. 加入碰撞检測

这里须要说一下怎样让小鸟运动。我们须要设置屏幕的监听事件,而且让小鸟有一个向上的线性速度。点击屏幕的时候小鸟向上运动,松开则下坠。

我们须要重写方法:
virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent);

实现:

// 触摸事件開始
void HelloWorld::ccTouchesBegan(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent) {
bird->getB2Body()->SetLinearVelocity(b2Vec2(0, 5));
}

接下来讲碰撞检測,这个我们相同也要设置监听器,我们设置的是物理世界的事件监听。

// 加入碰撞监听
world->SetContactListener(this);
然后重写下面方法:
 virtual void BeginContact(b2Contact* contact);

void HelloWorld::BeginContact(b2Contact *contact) {
// 发生碰撞,则弹出对话框
if (contact->GetFixtureA()->GetBody()->GetUserData() == bird ||
contact->GetFixtureB()->GetBody()->GetUserData() == bird) {
stopGame();
CCMessageBox("游戏失败","游戏失败");
} }

7. 本文总结

以上内容就是开发一款FlappyBird的简单Demo,读者能够在这个的基础上实现更丰富的功能,笔者认为不想一步到位把全部东西介绍完成。最重要的还是思路。把主要的东西掌握了,然后就能够依照这种思路去做一个这种东西。
能够到下面地址下载源代码:https://github.com/devilWwj/eoeFlappyBird
下面是完整实现:
HelloWorldScene.h
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__ #include "cocos2d.h"
#include "Box2D\Box2D.h"// 引入Box2D物理引擎
#include "B2Sprite.h" // 定义物理世界的比例
#define RATIO 48.0f
class HelloWorld : public cocos2d::CCLayer,public b2ContactListener
{
public:
// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
virtual bool init(); // there's no 'id' in cpp, so we recommend returning the class instance pointer
static cocos2d::CCScene* scene(); // a selector callback
void menuCloseCallback(CCObject* pSender); // implement the "static node()" method manually
CREATE_FUNC(HelloWorld); virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent);
virtual void BeginContact(b2Contact* contact); // 重写update方法
virtual void update(float dt); // 声明物理世界引用
b2World *world;
B2Sprite *bird;
CCSize screenSize;
CCSprite *barContainer; private:
// 加入小鸟
void addBird();
// 初始化物理世界
void initWorld();
// 加入地板
void addGround();
// 加入水管
void addBar(float dt);
// 加入一个容器
void addBarContainer();
// 開始游戏
void startGame(float dt);
// 结束游戏
void stopGame();
}; #endif // __HELLOWORLD_SCENE_H__

HelloWorldScene.cpp

#include "HelloWorldScene.h"

USING_NS_CC;

CCScene* HelloWorld::scene()
{
// 'scene' is an autorelease object
CCScene *scene = CCScene::create(); // 'layer' is an autorelease object
HelloWorld *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 instance
bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
if ( !CCLayer::init() )
{
return false;
}
// 获取屏幕大小
screenSize = CCDirector::sharedDirector()->getVisibleSize();
initWorld();
addBird();
addBarContainer();
addGround(); // 设置可点击
setTouchEnabled(true);
//scheduleUpdate();
//schedule(schedule_selector(HelloWorld::addBar), 1);
// 3秒之后运行
scheduleOnce(schedule_selector(HelloWorld::startGame),3);
return true;
} /**
* 加入小鸟
*
*/
void HelloWorld::addBird()
{
// 创建小鸟
bird = B2Sprite::create("bird.png");
// 获取内容大小
CCSize size = bird->getContentSize(); // 刚体属性
b2BodyDef bodyDef;
// 动态刚体
bodyDef.type = b2_dynamicBody;
// 设置初始位置
bodyDef.position = b2Vec2(screenSize.width/2/RATIO, screenSize.height/2/RATIO);
// 创建一个小鸟刚体
b2Body *birdBody = world->CreateBody(&bodyDef); // 隐形形状
b2PolygonShape birdShape;
// 设置为盒子。參数为内容的半宽半高
birdShape.SetAsBox(size.width/2/RATIO, size.height/2/RATIO); // 材料属性
b2FixtureDef birdFixtureDef;
// 形状
birdFixtureDef.shape = &birdShape;
// 加入地表物体
birdBody->CreateFixture(&birdFixtureDef); // 设置度量比例
bird->setPTMRatio(RATIO);
// 设置小鸟刚体
bird->setB2Body(birdBody);
// 加入小鸟到层中
addChild(bird); }
// 初始化物理世界
void HelloWorld::initWorld()
{
// -10表示重力加速度方向为向下
world = new b2World(b2Vec2(0, -10));
// 加入碰撞监听
world->SetContactListener(this);
} // 更新
void HelloWorld::update(float dt)
{
// 模拟物理世界
// Box2D建议的迭代次数是速度阶段8次。位置阶段3次
world->Step(dt, 8, 3);
CCSprite *s; // 遍历销毁
for (b2Body *b = world->GetBodyList(); b!= NULL; b=b->GetNext()) {
if (b->GetPosition().x<-3) {
s = (CCSprite*)b->GetUserData();
if (s != NULL) {
s->removeFromParent();
CCLog("Remove");
}
world->DestroyBody(b);
}
}
} /**
* 加入地板
*/
void HelloWorld::addGround()
{
// 地板精灵
B2Sprite *ground = B2Sprite::create("ground.png");
// 得到地板内容的大小
CCSize size = ground->getContentSize(); // 用于初始化刚体在物理世界的一些属性。比方位置,类型
b2BodyDef bDef;
// 静态的刚体
bDef.type = b2_staticBody;
// 设置位置
bDef.position = b2Vec2(size.width/2/RATIO, size.height/2/RATIO);
// 创建刚体
b2Body *groundBody = world->CreateBody(&bDef); // 形状
b2PolygonShape groundShape;
// 设置为矩形
groundShape.SetAsBox(size.width/2/RATIO, size.height/2/RATIO);
// 材料定制器
b2FixtureDef groundFixtureDef;
// 设置形状
groundFixtureDef.shape = &groundShape;
// 创建定制器
groundBody->CreateFixture(&groundFixtureDef);
// 为精灵设置刚体
ground->setB2Body(groundBody);
// 设置度量比例
ground->setPTMRatio(RATIO);
// 加入地板到层其中
addChild(ground); } // 触摸事件開始
void HelloWorld::ccTouchesBegan(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent) {
bird->getB2Body()->SetLinearVelocity(b2Vec2(0, 5));
} // 加入运动的水管
void HelloWorld::addBar(float dt) {
// 随机生成偏移量
float offset = -rand() %5; // 创建向下水管的精灵
B2Sprite *down_bar = B2Sprite::create("down_bar.png");
// 得到水管的大小
CCSize down_bar_size = down_bar->getContentSize(); // 下水管
b2BodyDef down_bar_body_def;
// 运动学物体,但不受重力影响
down_bar_body_def.type = b2_kinematicBody;
// 设置下水管的位置
down_bar_body_def.position = b2Vec2(screenSize.width/RATIO + 2, down_bar_size.height/RATIO/2 +offset);
// 线性速度,从右往左移动
down_bar_body_def.linearVelocity = b2Vec2(-5,0);
// 创建刚体
b2Body *down_bar_body = world->CreateBody(&down_bar_body_def); // 隐形形状
b2PolygonShape down_bar_shape;
// 设置为盒子。參数为内容的半宽半高
down_bar_shape.SetAsBox(down_bar_size.width/2/RATIO, down_bar_size.height/2/RATIO);
// 声明定制器
b2FixtureDef down_bar_fixture_def;
// 定制器形状
down_bar_fixture_def.shape = &down_bar_shape;
// 为刚体创建定制器
down_bar_body->CreateFixture(&down_bar_fixture_def); // 设置精灵刚体
down_bar->setB2Body(down_bar_body);
// 设置度量
down_bar->setPTMRatio(RATIO); // 上水管
B2Sprite *up_bar = B2Sprite::create("up_bar.png");
// 获得内容大小
CCSize up_bar_size = up_bar->getContentSize(); b2BodyDef up_bar_body_def;
// 运动学物体,但不受重力影响
up_bar_body_def.type = b2_kinematicBody;
// 设置水管位置
up_bar_body_def.position = b2Vec2(screenSize.width/RATIO+2, down_bar_size.height/RATIO+offset+2+up_bar_size.height/2/RATIO);
up_bar_body_def.linearVelocity = b2Vec2(-5, 0);
b2Body *up_bar_body = world->CreateBody(&up_bar_body_def); // 隐形形状
b2PolygonShape up_bar_shape;
// 设置为盒子形状,參数为半宽半高
up_bar_shape.SetAsBox(up_bar_size.width/2/RATIO, up_bar_size.height/2/RATIO);
b2FixtureDef up_bar_fixture_def;
up_bar_fixture_def.shape = &up_bar_shape;
up_bar_body->CreateFixture(&up_bar_fixture_def);
up_bar->setB2Body(up_bar_body);
up_bar->setPTMRatio(RATIO); barContainer->addChild(down_bar);
barContainer->addChild(up_bar); } // 运动条的容器
void HelloWorld::addBarContainer()
{
barContainer = CCSprite::create(); addChild(barContainer);
} // 開始游戏
void HelloWorld::startGame(float dt) {
scheduleUpdate();
schedule(schedule_selector(HelloWorld::addBar),1);
} // 结束游戏
void HelloWorld::stopGame() {
unscheduleUpdate();
unschedule(schedule_selector(HelloWorld::addBar)); } void HelloWorld::BeginContact(b2Contact *contact) {
// 发生碰撞,则弹出对话框
if (contact->GetFixtureA()->GetBody()->GetUserData() == bird ||
contact->GetFixtureB()->GetBody()->GetUserData() == bird) {
stopGame();
CCMessageBox("游戏失败","游戏失败");
} } void HelloWorld::menuCloseCallback(CCObject* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
CCMessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
#else
CCDirector::sharedDirector()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
#endif
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

Cocos2d-x 2.3.3版本 FlappyBird的更多相关文章

  1. mac下搭建cocos2d-x2.2.1版本android编译环境教程

    首先我们先以引擎2.2.1为例子来新建一个TestJni的项目,来作为测试例. 创建方式如下: python create_project.py -project TestJni -package o ...

  2. 如何在cocos2d项目中enable ARC

    如何在cocos2d项目中enable ARC 基本思想就是不支持ARC的代码用和支持ARC的分开,通过xcode中设置编译选项,让支持和不支持ARC的代码共存. cocos2d是ios app开发中 ...

  3. HTML5 学习总结(四)——canvas绘图、WebGL、SVG

    一.Canvas canvas是HTML5中新增一个HTML5标签与操作canvas的javascript API,它可以实现在网页中完成动态的2D与3D图像技术.<canvas> 标记和 ...

  4. canvas绘图、WebGL、SVG

    目录 一.Canvas 1.1.创建canvas元素 1.2.画线 1.3.绘制矩形 1.4.绘制圆弧 1.5.绘制图像 1.6.绘制文字 1.7.随机颜色与简单动画 二.WebGL 2.1.HTML ...

  5. HTML5 学习笔记(四)——canvas绘图、WebGL、SVG

    一.Canvas canvas是HTML5中新增一个HTML5标签与操作canvas的javascript API,它可以实现在网页中完成动态的2D与3D图像技术.<canvas> 标记和 ...

  6. project.json

    概述 项目相关配置,由原来的cocos2d.js中转移到project.json中,该文件需要与index.html同级,一般建议放在根目录下. 字段说明 debugMode 相当于原来的COCOS2 ...

  7. 使用 CocoStudio UI 编辑器实现《乱斗堂》设置界面

    由于是引用别人的,所以直接贴上地址了.http://www.cocoachina.com/bbs/read.php?tid=164820&fpage=7 1 游戏中必不可少的 UI 元素    ...

  8. HTML学习总结(四)【canvas绘图、WebGL、SVG】

    一.Canvas canvas是HTML5中新增一个HTML5标签与操作canvas的javascript API,它可以实现在网页中完成动态的2D与3D图像技术.<canvas> 标记和 ...

  9. cocos2d-js V3.0 V3.1使用DragonBones

    DragonBones是Adobe支持的一个开源项目,用于制作和播放骨骼动画,官网地址是:http://dragonbones.effecthub.com/.DragonBones首先在Flash和S ...

随机推荐

  1. HDU 4946 Area of Mushroom 凸包

    链接:pid=4946">http://acm.hdu.edu.cn/showproblem.php?pid=4946 题意:有n个人.在位置(xi,yi),速度是vi,假设对于某个点 ...

  2. 《TCP/IP作品详细解释2:达到》注意事项--ARP:地址解析协议

    Net/3于ARP和实施密切与路由表相关联的,下图显示了我们的叙述性说明ARP使用样品. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvVE9ERDkxMQ ...

  3. C++ do while 0 使用和含义

    /* do while 0 的使用方法和意义 */ //近期在非常多代码里都看到do while 0的身影. 乍一看,这不是没有做不论什么事情吗?为什么还要这样写.难道这是多此一举的吗?当然不是. / ...

  4. cocos2d-x3.x屏蔽遮罩层屏蔽触摸button

    cocos2d-x3.x触摸方法改变后,.屏蔽掉的层实际上触摸事件的非常easy,首先touchbegan一定要回true,第二,该事件被设定为听吞没触摸true.最近登录触摸水平必须低于0,现在,我 ...

  5. MEF初体验之五:Lazy Exports

    在一个部件组合中,导入将触发一个部件或者多个部件的实例化,这些部件暴露了所需原请求部件的必要的导入.对于一些应用程序来说,延迟实例化-防止图结构下的递归组合-可能对于将创建一个长久复杂的开销很大而不必 ...

  6. 如何有效抓取SQL Server的BLOCKING信息

    原文:如何有效抓取SQL Server的BLOCKING信息 转自:微软亚太区数据库技术支持组 官方博客 http://blogs.msdn.com/b/apgcdsd/archive/2011/12 ...

  7. HDU1160(LIS)

    主题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1160 题意:求体重下降.速度添加的样例最多有多少个 依据体重降序排一下,然后求速度的最长上升子序列 , ...

  8. adp设备是什么

    今天在写软工文档的可行性分析部分的时候.遇到一个新名词--adp,瞬间就不淡定了.原话例如以下: 6.1.1 基本建设投资 包含採购.开发和安装下列各项所需的费用,如: a. 须要提供一件教室,供开发 ...

  9. 编写高质量JavaScript代码绳之以法(The Essentials of Writing High Quality JavaScript)翻译

    原文:The Essentials of Writing High Quality JavaScript 才华横溢的Stoyan Stefanov,在他写的由O'Reilly初版的新书<Java ...

  10. swift新手入门视频教程-08-枚举

    我自己录制的swift菜鸟入门,大家拍砖,有什么问题能够在这里留言. 主要内容: 枚举语法(Enumeration Syntax) 匹配枚举值与Swith语句(Matching Enumeration ...