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. JAVA学习课第五十八届 — GUI

    GUI Graghical User Interface(图形用户接口) java为GUI提供的对象都存在java.awt和java.swing包中 Java的GUI做的的确干只是C++等.不打算浪费 ...

  2. epoll()无论涉及wait队列分析

    事件1. epfd-file->eventpoll->wq: struct eventpoll {     ...     wait_queue_head_t wq;     //用于ep ...

  3. Grant的时候报错的解决:Access denied for user &#39;root&#39;@&#39;localhost&#39; (using password: YES)

    mysql> grant all on *.* to 'root'@'192.168.1.1' identified by 'password'; ERROR 1045 (28000): Acc ...

  4. ASP.NET MVC(C#)和Quartz.Net组件

    ASP.NET MVC(C#)和Quartz.Net组件 在之前的文章<推荐一个简单.轻量.功能非常强大的C#/ASP.NET定时任务执行管理器组件–FluentScheduler>和&l ...

  5. BZOJ 3505 CQOI 2014 数三角形 数学

    标题效果:到m*n该网络格,问:有网络格是一个三角形的顶点的数目. 思维:数学.首先计算所有三个相同的,不.然后,在上线的一个点失去了三个点是其中.需要注意的是,答案开放long long. CODE ...

  6. python 基础知识点整理 和详细应用

    Python教程 Python是一种简单易学,功能强大的编程语言.它包含了高效的高级数据结构和简单而有效的方法,面向对象编程.Python优雅的语法,动态类型,以及它天然的解释能力,使其成为理想的语言 ...

  7. 百度地图 Android SDK - 个性化地图

    什么是百度个性化地图Android SDK? 百度个性化地图Android SDK是一套基于Android 2.2及以上版本号设备的应用程序接口,您能够通过该套接口实现主要的地图功能,而且能够定制地图 ...

  8. IIS 7.0 Features and Vista Editions

    原文 IIS 7.0 Features and Vista Editions Overview of IIS 7.0 differences Across Windows Vista Editions ...

  9. Codeforces 448 D. Multiplication Table

    二分法判断答案 D. Multiplication Table time limit per test 1 second memory limit per test 256 megabytes inp ...

  10. android 环境使用smack 必须注冊的组件

    // Private Data Storage pm.addIQProvider("query", "jabber:iq:private",new Privat ...