程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> Cocos2d-x 系列八之Box2d入門

Cocos2d-x 系列八之Box2d入門

編輯:C++入門知識

  既然已有了cocos2d-x,為什麼還要Box2d呢,是因為cocos2d-x作為一個圖像引擎,只是用於顯示圖像,圖像之間可以任意的重合,如果想要做到類物理學的碰撞等運動效果,就需要用到Box2d這個物理引擎用來模仿物理世界中的物體;

  本講主要簡單講述如何創建動態物體,靜態物體,漂浮物體,以及它們與圖像的綁定; 

下面直接通過一個例子來看三種物體的創建方法;

  首先需要說明的一點是:在Box2d中,使用的單位是米,而不是像素,所以,在進行位置轉換的時候,需要按比例縮放,Box2d中,比較理想的距離大小是10米,所以,得對屏幕寬高進行一定的比例縮放(如下面例子中定義的RADIO,就是我定義的比例);

HelloWorldScene.cpp

#include "HelloWorldScene.h"

#define RADIO 80

Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::create();

    // 'layer' is an autorelease object
    auto 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 ( !Layer::init() )
    {
        return false;
    }

    world = new b2World(b2Vec2(0,-10)); //x 方向加速度為0,y方向加速度為10 
    world->SetContactListener(this); // 添加物體撞擊事件監聽

    addGround();
    addRect();

    scheduleUpdate(); // 開始執行handler,第幀執行一次update方法

    return true;
}

void HelloWorld::update(float dt){
    world->Step(dt,8,3); // 三個參數分別表示當前幀和最後一幀之間的時間間隔,由於update方法是程序每一幀執行一次,所以直接傳入幀頻dt;
                //第二個參數表示速度迭代次數,官方建議8;
                //第三個參數表示位置迭代次數,官方建議3; Sprite *s; for(b2Body *b = world->GetBodyList();b;b= b->GetNext()){ if(b->GetUserData()){ s = (Sprite*)b->GetUserData(); s->setPosition(b->GetPosition().x * RADIO ,b->GetPosition().y *RADIO); // 更新物體的位置 } } } void HelloWorld::BeginContact(b2Contact* contact){ // b2ContactListener物體發生碰撞時的回調接口 log("contact?"); if(contact->GetFixtureA()->GetBody() == ground ||contact->GetFixtureB()->GetBody() == ground){ log("yeah,contacted!"); } } void HelloWorld::addRect(){ // 添加一個動態的Rect,並且綁定一個Sprite; b2BodyDef def; def.type = b2_dynamicBody; // 指定type為動態物體 @1 def.position = b2Vec2(3,1); // 起始位置(3,1) def.linearVelocity = b2Vec2(0,10); // (初始)線性速度,如果type為漂浮的,則物體會沒這個方向做勻速運動,如果為動態,則會進行預先設定的加速度進行速度變換; b2PolygonShape shape; shape.SetAsBox(0.5,0.5); // 設置一個Shape,兩個參數分別表示左半邊和上半邊的大小,所以,這裡兩個0.5其實就定義了一個1x1的塊 b2FixtureDef fixtureDef; fixtureDef.density = 1; // 指定物體密度 fixtureDef.friction = 0.3; // 指定物體摩擦 fixtureDef.shape = &shape; // 指定物體的shape b2Body *body = world->CreateBody(&def); auto s = Sprite::create(); s->setTextureRect(Rect(0 , 0, 30, 30)); // 設置sprite所顯示的區域 addChild(s); body->CreateFixture(&fixtureDef); // 設置FixtureDef之後,兩個物體之間就會有碰撞的效果了,如果沒有碰撞的效果,則物體會一直沿某一個方向不停運動; body->SetUserData(s); // 將Sprite綁定到物體上 } void HelloWorld::addGround(){ //添加一個靜態物體,在為裡為添加到底部,阻止上一步中創建的自由落體的物體 b2BodyDef def; def.type = b2_staticBody; def.position = b2Vec2(0, 0); b2PolygonShape shape; shape.SetAsBox(400/RADIO, 10 / RADIO); // 設置物體大小 ground = world->CreateBody(&def); auto s = Sprite::create(); s->setTextureRect(Rect(0,0,1600,40)); b2FixtureDef fixtureDef; fixtureDef.density = 0.5; fixtureDef.friction = 0.3; fixtureDef.shape = &shape; addChild(s); ground->CreateFixture(&fixtureDef); ground->SetUserData(&def); }

HelloWorldScene.h

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"
#include <Box2D/Box2D.h>

USING_NS_CC;

class HelloWorld : public Layer,public b2ContactListener
{
private :
    b2World *world;
    b2Body *ground;
public:
    // there's no 'id' in cpp, so we recommend returning the class instance pointer
    static cocos2d::Scene* createScene();

    // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
    virtual bool init();  

    // a selector callback
    void menuCloseCallback(cocos2d::Ref* pSender);

    // implement the "static create()" method manually
    CREATE_FUNC(HelloWorld);

    virtual void update(float dt);

    void addRect();
    void addGround();

    /// Called when two fixtures begin to touch.
    virtual void BeginContact(b2Contact* contact) ;

};

#endif // __HELLOWORLD_SCENE_H__

@1: 這裡的type有三種類型如下

  • b2_staticBody(靜態)
  • b2_kinematicBody(漂浮,可以運動,但是速度恆定)
  • b2_dynamicBody(動態,速度在變化)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved