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

フニゲの開発日記

Electronとか...

MouseJointのテスト

Box2D cocos2d-html5


Box2DではQueryAABB()というのを呼ぶとマウスの下にあるbodyを見つけることができるらしい。
サンプルローダーのtestbed.jsを見るとコールバックの書き方が2種類あるみたいなんだけど、そのへんは深入りせずに簡単に書けるものは簡単に書く。

// game.js
var Game = cc.Layer.extend({
    ctor:function () {
        this._super();
        this.world = loadWorldFromRUBE(carJSON);
        this.mouseJointGroundBody = this.world.CreateBody(new b2BodyDef()); // <- 追加
        
        this.setBod2dDebug();
        this.scheduleUpdate();
    },

    ...

    startMouseJoint:function (pos) {
        if (this.mouseJoint != null) return;

        var aabb = new b2AABB();
        aabb.lowerBound.Set(pos.x - 0.001, pos.y - 0.001);
        aabb.upperBound.Set(pos.x + 0.001, pos.y + 0.001);

        var selectedBody = null;
        var callback = function (fixture) {
            if (fixture.GetBody().GetType() != b2_staticBody) {
                var transform = fixture.GetBody().GetTransform();
                if (fixture.GetShape().TestPoint(transform, pos)) {
                    selectedBody = fixture.GetBody();
                    return false;
                }
            }
            return true;
        };

        this.world.QueryAABB(callback, aabb);
        if (selectedBody) {
            var md = new b2MouseJointDef();
            md.bodyA = this.mouseJointGroundBody;
            md.bodyB = selectedBody;
            md.target.Set(pos.x, pos.y);
            md.maxForce = 1000 * selectedBody.GetMass();
            md.collideConnected = true;

            this.mouseJoint = this.world.CreateJoint(md);
            selectedBody.SetAwake(true);
        }
    },

で、これをマウスイベントから呼び出す。

    ...

    onMouseDown:function (event) {
        var pos = cc.pMult(event.getLocation(), 1.0 / PTM_RATIO);
        this.startMouseJoint(pos);
    },

    onMouseDragged:function (event) {
        if (this.mouseJoint != null) {
            var pos = cc.pMult(event.getLocation(), 1.0 / PTM_RATIO);
            this.mouseJoint.SetTarget(new b2Vec2(pos.x, pos.y));
        }
    },

    onMouseUp:function (event) {
        if (this.mouseJoint != null) {
            this.world.DestroyJoint(this.mouseJoint);
            this.mouseJoint = null;
        }
        ...
    },

MouseJointというとテストとかサンプル専用の特別な物という気がしていたんだけど、どうも他の普通のジョイントと大差ないようだ。マウスと一緒に使わなければいけないという決まりもない。
ゲームの実装にどしどし使おうと思う。

広告を非表示にする