cocos2d-x 《Flappy Bird 》二、物理世界搭建(Box2d物理引擎)

本文介绍了使用cocos2d-x 2.2.1版本在Mac上开发《Flappy Bird》游戏时,如何利用Box2d物理引擎搭建游戏物理世界。开发者通过处理图片资源,控制小鸟飞行的节奏,使其穿越水管障碍。文章提供了一、效果图及小鸟实现的初步内容。
摘要由CSDN通过智能技术生成

《flappy bird》是由来自越南的独立游戏开发者Dong Nguyen所开发的作品,游戏中玩家必须控制一只小鸟,跨越由各种不同长度水管所组成的障碍,而这只鸟其实是根本不会飞的……所以玩家每点击一下小鸟就会飞高一点,不点击就会下降,玩家必须控制节奏,拿捏点击屏幕的时间点,让小鸟能在落下的瞬间跳起来,恰好能够通过狭窄的水管缝隙,只要稍一分神,马上就会失败阵亡。

图片资源提取后使用PS5 处理,Zwoptex 重新打包。

======================================================================================

开发环境:

  Cocos2d-x  cocos2d-x-2.2.1

  MacBook Pro 13'  10.9

  Xcode 5.0.2

  iPhone5   IOS 7.0.4

======================================================================================

一、效果图



二、小鸟的实现

//
//  Bird.h
//  Flappy
//
//  Created by yuzai on 14-2-12.
//
//

#ifndef __Flappy__Bird__
#define __Flappy__Bird__

#include "cocos2d.h"
#include "Box2D/Box2D.h"
using namespace cocos2d;
class Bird:public cocos2d::CCNode
{
public:
    Bird(void);
    virtual ~Bird(void);
    
    virtual void onEnter();
    virtual void onExit();
    
    
    CREATE_FUNC(Bird);
    b2Body* m_pBody;//物理
private:
    CCSprite *body;
    
    
};


#endif /* defined(__Flappy__Bird__) */

三、物理世界搭建

//
//  GameLayer.h
//  Flappy
//
//  Created by yuzai on 14-2-12.
//
//

#ifndef __Flappy__GameLayer__
#define __Flappy__GameLayer__

#include "cocos2d.h"
#include "Box2D.h"
#include "Bird.h"
using namespace cocos2d;
class GameLayer:public cocos2d::CCLayer
{
public:
	GameLayer(void);
	~GameLayer(void);
    //背景
    CCSprite *bg;
    //路
    CCSprite *land1;
    CCSprite *land2;
    //水管
    CCSprite *pipe1;
    CCSprite *pipe2;
    CCSprite *pipe3;
    CCSprite *pipe4;
    Bird *bird;
    void setBackgroud(unsigned int bg);
	CREATE_FUNC(GameLayer);
	virtual bool init();
    virtual void update(float time);
    void initPhysics();
 
private:
    b2World* world;//定义物理世界
    b2BodyDef groundBodyDef;//定义物体(世界的)
    
    
    
};

#endif /* defined(__Flappy__GameLayer__) */

//
//  GameLayer.cpp
//  Flappy
//
//  Created by yuzai on 14-2-12.
//
//

#include "GameLayer.h"

#define PTM_RATIO 32.0  //设定每32像素为一米

GameLayer::GameLayer(void)
{
    
}

GameLayer::~GameLayer(void)
{
     CC_SAFE_DELETE(world);
}
bool GameLayer::init()
{
    if (!CCLayer::init())
    {
        return false;
    }
    //屏幕宽高比 首先 适配IPHONE5
    CCSize frameSize = CCEGLView::sharedOpenGLView()->getFrameSize();
    float scales = (float) frameSize.width/ 288;
    CCSize winSize=CCDirector::sharedDirector()->getWinSize();
    CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("res/default.plist");
    CCSpriteFrame *bg1Frame=CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("bg_day.png");
    bg=CCSprite::create();
    bg->setAnchorPoint(ccp(0, 0));
    bg->setDisplayFrame(bg1Frame);
    bg->setScale(scales);
    bg->setPosition(ccp(0,0));
    addChild(bg);
    
    //2.陆地
    
    CCSpriteFrame *landFrame=CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("land.png");
    land1=CCSprite::create();
    land1->setAnchorPoint(ccp(0, 0));
    land1->setDisplayFrame(landFrame);
    land1->setScale(scales);
    land1->setPosition(ccp(0, 0));
    addChild(land1,1);
    land2=CCSprite::create();
    land2->setAnchorPoint(ccp(0, 0));
    land2->setDisplayFrame(landFrame);
    land2->setScale(scales);
    land2->setPosition(ccp(frameSize.width, 0));
    addChild(land2,1);
    
    //3.添加小鸟
    bird=new Bird();
    bird->setPosition(winSize.width/2,winSize.height/2);
    bird->setScale(scales);
    addChild(bird,2);

    //4.水管
    
    //5.物理世界
    this->initPhysics();
    // Define the dynamic body.
    //Set up a 1m squared box in the physics world
    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;//小鸟是运动的 所有设置为动态刚体
    bodyDef.position.Set(bird->getPositionX()/PTM_RATIO,bird->getPositionY()/PTM_RATIO);//转化真实世界坐标  Pix/PTM_RATIO
    bodyDef.userData=bird;
    bird->m_pBody=world->CreateBody(&bodyDef);
    
    // Define another box shape for our dynamic body.
    b2PolygonShape dynamicBox;
    dynamicBox.SetAsBox(0.5f,0.5f);//These are mid points for our 1m box
    
    // Define the dynamic body fixture.
    b2FixtureDef fixtureDef;
    fixtureDef.shape = &dynamicBox;
    fixtureDef.density = 1.0f;
    fixtureDef.friction = 0.3f;
    fixtureDef.restitution=0.8f;
    bird->m_pBody->CreateFixture(&fixtureDef);
    

    
    scheduleUpdate();
    return true;
}
//改变背景
void GameLayer::setBackgroud(unsigned int bg)
{
    
    switch (bg) {
        case 1:
        {
            
        }
            break;
            
        default:
            break;
    }
}

void GameLayer::update(float time){
    //land移动逻辑
    CCSize frameSize = CCEGLView::sharedOpenGLView()->getFrameSize();

    float dif=4;
    land1->setPosition(ccp(land1->getPositionX()-dif,land1->getPositionY()));
    land2->setPosition(ccp(land2->getPositionX()-dif,land2->getPositionY()));
    if (land2->getPositionX()<0) {
        float temp=land2->getPositionX()+frameSize.width;
        land1->setPosition(ccp(temp,land2->getPositionY()));
    }
    if (land1->getPositionX()<0) {
        float temp=land1->getPositionX()+frameSize.width;
        land2->setPosition(ccp(temp,land1->getPositionY()));
    }
    
  
    
    float32 timeStep = 1.0f / 60.0f;
    int32 velocityIterations = 6;
    
    int32 positionIterations = 2;

    
        world->Step(timeStep, velocityIterations, positionIterations);
        
        b2Vec2 position = bird->m_pBody->GetPosition();
        
        float32 angle = bird->m_pBody->GetAngle();
        
        for (b2Body *body=world->GetBodyList(); body!=NULL; body=body->GetNext()) {
            Bird *bir=(Bird*)body->GetUserData();
            if (bir!=NULL) {
                bir->setPosition(ccp(position.x*PTM_RATIO, position.y*PTM_RATIO));
                bir->setRotation(CC_RADIANS_TO_DEGREES(body->GetAngle())*-1);
            }
        }
        
        printf("%4.2f %4.2f %4.2f\n", position.x, position.y, angle);


    
}
//初始化物理引擎的方法
void GameLayer::initPhysics()
{
    
    
    //0.屏幕大小
    CCSize winSize=CCDirector::sharedDirector()->getWinSize();
    //1.重力向量
    b2Vec2 gravity=b2Vec2(0.0f, -10.0f);//模拟真实世界
    
    world = new b2World(gravity);
    
    //2.设置是否持续物理模拟
    world->SetAllowSleeping(true);
    
    world->SetContinuousPhysics(true);

    
    //3.设置世界盒子的位置
    // Define the ground body. 定义 边缘刚体
    groundBodyDef.position.Set(0,0); // bottom-left corner
    
    // Call the body factory which allocates memory for the ground body
    // from a pool and creates the ground box shape (also from a pool).
    // The body is also added to the world.
    //所有的b2Body都由b2World示例创建
    b2Body* groundBody = world->CreateBody(&groundBodyDef);
    
    // Define the ground box shape.//创建边缘刚体
    b2PolygonShape groundBox;
    
    b2FixtureDef boxShapeBox;
    boxShapeBox.shape=&groundBox;

    //屏幕宽高比 首先 适配IPHONE5
    CCSize frameSize = CCEGLView::sharedOpenGLView()->getFrameSize();
    float scales = (float) frameSize.width/ 288;
    
    
    //定义物体边界
    // bottom   112*scales 设置的是地面的高度
    groundBox.SetAsBox(winSize.width/PTM_RATIO,112*scales/PTM_RATIO, b2Vec2(0, 0), 0);
    groundBody->CreateFixture(&groundBox,0);
    
    // top
    groundBox.SetAsBox(winSize.width/PTM_RATIO, 0, b2Vec2(0, winSize.height/PTM_RATIO), 0);
    groundBody->CreateFixture(&groundBox,0);
    
    // left
    groundBox.SetAsBox(0, winSize.height/PTM_RATIO, b2Vec2(0, 0), 0);
    groundBody->CreateFixture(&groundBox,0);
    
    // right
    groundBox.SetAsBox(0, winSize.height/PTM_RATIO, b2Vec2(winSize.width/PTM_RATIO, 0), 0);
    groundBody->CreateFixture(&groundBox,0);

 
    
}

注:代码迭代随时有变动

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值