読者です 読者をやめる 読者になる 読者になる

フニゲの開発日記

Electronとか...

せっかくだからBox2Dも試しておこう

cocos2d-html5 Box2D


起動時の「box2d:false」をtrueにすればすぐ使えるようになるかと思ったのだが、そうでもなかった。何か手順が悪いのかも知れないが、Box2dWebを自分で拾ってきて読み込んでいます。

// boot-html5.js
(function () {
    var d = document;
    var c = {
        COCOS2D_DEBUG:2,
        box2d:true, // じゃあこれは結局なんなのだ
        chipmunk:false,
        showFPS:true,
        frameRate:60,
        loadExtension:true,
        tag:'gameCanvas', 
 
        //engineDir:'./Platform/HTML5/cocos2d/',
        SingleEngineFile:'cocos2d-html5.min.js',
        appFiles:[
            './Box2dWeb-2.1.a.3.min.js', // <- 追加
            './Src/resource.js',
            './Src/game.js'
        ]
    };
    ...

game本体の方は、samples/tests/Box2dTest/Box2dTest.jsを参考に。

var Game = cc.Layer.extend({
    world:null,

    ctor:function () {
        this._super();

        var b2Vec2 = Box2D.Common.Math.b2Vec2
          , b2BodyDef = Box2D.Dynamics.b2BodyDef
          , b2Body = Box2D.Dynamics.b2Body
          , b2FixtureDef = Box2D.Dynamics.b2FixtureDef
          , b2World = Box2D.Dynamics.b2World
          , b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape;

        var screenSize = cc.Director.getInstance().getWinSize();

        this.world = new b2World(new b2Vec2(0, -10), true);
        this.world.SetContinuousPhysics(true);

        var fixDef = new b2FixtureDef;
        fixDef.density = 1.0;
        fixDef.friction = 0.5;
        fixDef.restitution = 0.2;

        var bodyDef = new b2BodyDef;
        bodyDef.type = b2Body.b2_staticBody;
        fixDef.shape = new b2PolygonShape;

        // 上下の壁
        fixDef.shape.SetAsBox(20, 2);
        bodyDef.position.Set(10, screenSize.height / PTM_RATIO + 1.8);
        this.world.CreateBody(bodyDef).CreateFixture(fixDef);
        bodyDef.position.Set(10, -1.8);
        this.world.CreateBody(bodyDef).CreateFixture(fixDef);

        // 左右の壁
        fixDef.shape.SetAsBox(2, 14);
        bodyDef.position.Set(-1.8, 13);
        this.world.CreateBody(bodyDef).CreateFixture(fixDef);
        bodyDef.position.Set(26.8, 13);
        this.world.CreateBody(bodyDef).CreateFixture(fixDef);

        this.scheduleUpdate();
    },
    onEnter:function () {
        this._super();
        this.setMouseEnabled(true); // なんかここで設定しないと動かなかった
    },
    addNewSpriteWithCoords:function (p) {
        var sprite = cc.Sprite.create("Art/block.png") // 32x32の何か
        sprite.setPosition(cc.p(p.x, p.y));
        this.addChild(sprite);

        var b2BodyDef = Box2D.Dynamics.b2BodyDef
          , b2Body = Box2D.Dynamics.b2Body
          , b2FixtureDef = Box2D.Dynamics.b2FixtureDef
          , b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape;

        var bodyDef = new b2BodyDef();
        bodyDef.type = b2Body.b2_dynamicBody;
        bodyDef.position.Set(p.x / PTM_RATIO, p.y / PTM_RATIO);
        bodyDef.userData = sprite;
        var body = this.world.CreateBody(bodyDef);

        var dynamicBox = new b2PolygonShape();
        dynamicBox.SetAsBox(0.5, 0.5);

        var fixtureDef = new b2FixtureDef();
        fixtureDef.shape = dynamicBox;
        fixtureDef.density = 1.0;
        fixtureDef.friction = 0.3;
        body.CreateFixture(fixtureDef);
    },
    update:function (dt) {
        this.world.Step(dt, 8, 1); // 動きが不自然なときはここを調整する

        for (var b = this.world.GetBodyList(); b; b = b.GetNext()) {
            if (b.GetUserData() != null) {
                var actor = b.GetUserData();
                actor.setPosition(cc.pMult(b.GetPosition(), PTM_RATIO));
                actor.setRotation(-1 * cc.RADIANS_TO_DEGREES(b.GetAngle()));
            }
        }
    },
    onMouseUp:function (event) {
        var location = event.getLocation();
        this.addNewSpriteWithCoords(location);
    }
});

Game.create = function () {
    var layer = new Game();
    return (layer && layer.init()) ? layer : null;
};

Game.scene = function () {
    var scene = cc.Scene.create();
    var layer = Game.create();
    scene.addChild(layer);
    return scene;
};
広告を非表示にする