Cocos2d-x 2,android系统工程师面试题

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()Cocos2d-x 2,android系统工程师面试题_第1张图片

{

// 地板精灵

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();

);

// 材料属性

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();

你可能感兴趣的:(程序员,架构,移动开发,android)