1. 程式人生 > >Cocos2dx雜記:推小球,box2d與TiledMap的使用

Cocos2dx雜記:推小球,box2d與TiledMap的使用

前面介紹了box2d和tiledmap
下面以一個物理遊戲Demo為例來介紹下box2d與TiledMap基本使用方式

1、Demo執行截圖(Demo素材收集與網路,如有侵權請告知刪除

這裡寫圖片描述

2、遊戲功能介紹

點選藍色的物體變成小球把紅色的球推下去,並且吃掉場景中的星星,右面三角形的是蹺蹺板,沒什麼作用,大家當做不存在就好。。。

3、目錄結構

這裡寫圖片描述
Constants.h 中定義了畫素和米數的比
GLES-Render.h 顯示box2d除錯效果
HelloWorldScene.h主要方法

4、載入地圖

整個遊戲場景屬性是使用TiledMap編輯的,編輯完成後載入,相關TiledMap操作可以參見

Cocos2dx雜記:Tiledmap讀取

首先看一下Tiled的設計結構(圖片中高亮的部分就是當前層的物件

(1)結構
這裡寫圖片描述

(2)層
a、背景層(背景)
這裡寫圖片描述
b、敵人(enemy)
這裡寫圖片描述
c、玩家操作單位(player)
這裡寫圖片描述
d、物理路徑(phy)
這裡寫圖片描述
e、星星(stars)
這裡寫圖片描述
f、木頭等障礙物(wood)
這裡寫圖片描述

整個場景在Tiled中設計好之後,載入。

5、建立物理世界

建立一個與場景一樣大小的物理世界

bool HelloWorld::initPhysics
() { Size s = Director::getInstance()->getVisibleSize(); //重力引數 b2Vec2 gravity; //重力,1個g gravity.Set(0.0f, -9.8f); //建立世界 world = new b2World(gravity); //開啟除錯 openDebugDraw(); //允許物體是否休眠 world->SetAllowSleeping(true); //開啟連續物理測試 world->SetContinuousPhysics(true
); //地面物體定義 b2BodyDef groundBodyDef; //左下角 groundBodyDef.position.Set(0, 0); //建立地面物體 b2Body* groundBody = world->CreateBody(&groundBodyDef); //定義一個有邊的形狀 b2EdgeShape groundBox; //底部 groundBox.Set(b2Vec2(0, 0), b2Vec2(s.width / PTM_RATIO, 0)); //使用夾具固定形狀到物體上 groundBody->CreateFixture(&groundBox, 0); //頂部 groundBox.Set(b2Vec2(0, s.height / PTM_RATIO), b2Vec2(s.width / PTM_RATIO, s.height / PTM_RATIO)); groundBody->CreateFixture(&groundBox, 0); //左邊 groundBox.Set(b2Vec2(0, s.height / PTM_RATIO), b2Vec2(0, 0)); groundBody->CreateFixture(&groundBox, 0); //右邊 groundBox.Set(b2Vec2(s.width / PTM_RATIO, s.height / PTM_RATIO), b2Vec2(s.width / PTM_RATIO, 0)); groundBody->CreateFixture(&groundBox, 0); return true; }

6、載入物體

//例如:建立木頭
//獲得木頭,從tiled中獲得木頭的位置等屬性,然後將建立木頭圖片,並且繫結物理屬性
    //獲得木頭
    auto groupWood = map->getObjectGroup("wood");
    auto& objectsWood = groupWood->getObjects();

    for (auto& obj : objectsWood)
    {
        ValueMap& dict = obj.asValueMap();

        float x = dict["x"].asFloat();
        float y = dict["y"].asFloat();
        float width = dict["width"].asFloat();
        float height = dict["height"].asFloat();
        float rotate = dict["rotation"].asFloat();
        //float index = dict["index"].asInt();

        log("rotate = %f", rotate);


        auto sp = Sprite::create();
        sp->setPosition(x, y);
        sp->setScale(0.3f);
        this->addChild(sp, -1);

        sp->initWithFile("aaa/wood.png");
        sp->setRotation(rotate);
        phyObjList.push_back(sp);

        //物體定義  
        b2BodyDef bodyDef;
        bodyDef.type = b2_dynamicBody;
        bodyDef.position.Set(x / PTM_RATIO, y / PTM_RATIO);
        b2Body *body = world->CreateBody(&bodyDef);
        body->SetUserData(sp);
        body->SetTransform(body->GetPosition(), CC_DEGREES_TO_RADIANS(sp->getRotation()));

        b2PolygonShape dynamicBox;
        dynamicBox.SetAsBox(sp->getContentSize().width * 0.3f / 2 / PTM_RATIO, sp->getContentSize().height * 0.3f / 2 / PTM_RATIO);

        // 夾具定義  
        b2FixtureDef fixtureDef;
        //設定夾具的形狀  
        fixtureDef.shape = &dynamicBox;
        //設定密度  
        fixtureDef.density = 1.0f;
        //設定摩擦係數  
        fixtureDef.friction = 0.5f;
        //使用夾具固定形狀到物體上    
        body->CreateFixture(&fixtureDef);
    }

其他元素載入方法類似。全部載入完成之後就可以體驗box2d的物理小遊戲了。

7、下載地址

小球原始碼