LoginSignup
0
1

More than 5 years have passed since last update.

Cocos2d-JSでchipmunk使う備忘録

Last updated at Posted at 2017-03-08

はじめに

久しぶりにCocos2d-JS + chipmunkを使ったプロトタイプを作ろうとした時に、
いろいろ忘れてたので、自分用の備忘として残しておきます。

chipmunkとは

物理演算をシュミレートするための2D物理演算のエンジン。
モンストや蹴り姫みたいなゲームが作れますというと一番伝わる気がします(笑)。

Chipmunk vs Box2D

よく話題に出るのがこの2つの物理エンジンです。
細かいことはさておき、Chipmunkの方が先にCocos2dに組み込まれたっぽい記述がありましたが、
Cocos2dの3.0以上であれば、どちらもコアライブラリに機能として組み込まれているので、どちらを使っても良さそうです。今回はchipmunk使います。

オブジェクトの作り方

1つのオブジェクトに対して、こんな流れになります。
1.sprite作る->2.body作る->3.Shape作る

1のspriteは通常のspriteと同じで、絵などを貼り付けたりなど描画する部分について。
2のbodyは位置や、動的/静的などを指定できたり、貼り付けるspriteを指定するなど。
3.のshapeはもっと細かな、形や密度、摩擦係数、反発係数などを指定し、
1~3を合体することで、1つの物理演算ルールに則ったオブジェクトを作成できます^^

shapeのいろいろ

自作ゲームの中ではbox型地のshapeしか作ったことがなかったのですが、
いろいろ用意されているようです。

cp.CircleShape(Body, 半径, オフセット)
cp.SegmentShape(Body, 始点, 終点, 線の太さ)
cp.PolyShape(Body, ポリゴンの頂点の配列, オフセット)
cp.BoxShape(Body, , 高さ)

実際の書き方

何はともあれ、project.jsonで読み込んでおきます。

    "modules" : ["cocos2d","chipmunk"],

物理演算を行うspaceをinitの中で作成します。

    initSpace: function() { 
        //物理演算する空間を作る
        this.space = new cp.Space();

        //重力がある場合はgravityを設定する
        //this.space.gravity = cp.v(0, -980);

        //shapeを可視化する(デバッグ用)
        this.addChild(new cc.PhysicsDebugNode(this.space));

        this.scheduleUpdate();
    },

次にupdateでは下記のように指定します。

    update: function(dt) {
        // 物理エンジンの更新
        this.space.step(dt);
    },

いよいよオブジェクトの作成はこのような感じ。先に説明した通りに、1.sprite作る->2.body作る->3.Shape作るの順番で作っていきます。


    addTank:function(posX,posY){
        // 物理スプライト
        this.tankSprite = new cc.PhysicsSprite("res/tank.png");  
        // 質量、慣性モーメントを設定
        this.weight = 100;
        this.tankBody = new cp.Body(this.weight, cp.momentForBox(this.weight, this.tankSprite.getContentSize().width, this.tankSprite.getContentSize().height));
        this.space.addBody(this.tankBody);
        // 形状、摩擦係数、反発係数を設定
        this.tankShape = new cp.BoxShape(this.tankBody, this.tankSprite.getContentSize().width, this.tankSprite.getContentSize().height);
        this.tankShape.setFriction(1);//摩擦係数
        this.tankShape.setElasticity(0.5); //弾性係数を設定
        this.space.addShape(this.tankShape);
        this.tankSprite.setBody(this.tankBody);
        this.tankSprite.setPosition(posX, posY);
        this.addChild(this.tankSprite);
    },

このまま実行すると、重力の設定などによっては画面外に飛び出しちゃうので、
とりあえず床などを作っておきます。


createFloor: function() {
        // 床を静的剛体として作る
        var floorThickness = 10;

        var bottomBar = new cp.SegmentShape(this.space.staticBody, cp.v(0, 50), cp.v(640,50), floorThickness);
        bottomBar.setFriction(1); //摩擦係数
        bottomBar.setElasticity(0.3); //弾性
        this.space.addShape(bottomBar);

        var topBar = new cp.SegmentShape(this.space.staticBody, cp.v(0,1100), cp.v(640,1100), floorThickness);
        topBar.setFriction(1);
        topBar.setElasticity(0.3);
        this.space.addShape(topBar);

        var leftBar = new cp.SegmentShape(this.space.staticBody, cp.v(0,1100), cp.v(0,50), floorThickness);
        leftBar.setFriction(1);
        leftBar.setElasticity(0.3);
        this.space.addShape(leftBar);

        var rightBar = new cp.SegmentShape(this.space.staticBody, cp.v(640,1100), cp.v(640,50), floorThickness);
        rightBar.setFriction(1);
        rightBar.setElasticity(0.3);
        this.space.addShape(rightBar);
    },

初速を与えたい場合..

作ったオブジェクトに対して、初速を与えたい場合は(例えば、ピンボールの玉のような感じ)下記のようにして初速を与えることができます。

        this.bulletBody.applyImpulse(cp.v(this.weight * 150, 0), cp.v(0, 0)); // 右向き
        this.bulletBody.applyImpulse(cp.v(0, this.weight * 1500), cp.v(0, 0)); // 上向き

おしまい

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1