LoginSignup
3
2

More than 5 years have passed since last update.

enchant.js クラス同士の衝突判定

Last updated at Posted at 2018-02-28

連射した弾丸と次々現れる敵といった、多対多で衝突判定をさせたい場合はよくあります。
これをリスト(配列)やグループで管理するとなかなか面倒です。
image.png
ここでは、白くまからサッカーボール(Ballクラス)を連射し、スケボーに乗ったくま(Targetクラス)に当たったかどうかを判定するとします。

1つ1つのサッカーボールはどれもBallクラスのインスタンスです。スケボーくまはTargetクラスのインスタンスです。

こういったケースでクラス対クラスの衝突判定を利用すると、とてもシンプルにプログラムが書けました。

クラス対クラスの衝突判定

    // ゲームの処理
    game.onload = function()
    {
        // (中略)

        kuma = new Sprite(32,32);
        kuma.image = game.assets['chara1.png'];
        kuma.frame = 6;
        kuma.x = 60;
        kuma.y = 230;
        game.rootScene.addChild(kuma);

        // 定期処理
        game.rootScene.addEventListener('enterframe', function()
        {
            // (中略)

            // スペースキー入力で弾発射
            if(game.input.a)
            {
                var ball = new Ball();
            }

            // 1秒に1回ターゲット出現
            if(game.frame%game.fps ===0)
            {
                var mato = new Target();
            }

            // BallクラスとTargetクラスの衝突判定
            Ball.intersect(Target).forEach(function(pair)
            {
                //pair[0]: Ballのインスタンス
                //pair[1]: Targetのインスタンス
                game.rootScene.removeChild(pair[0]);
                game.rootScene.removeChild(pair[1]);
            });

        });
    };

弾丸用Ballクラスと、ターゲット用Targetクラスがあり、それぞれが衝突したかどうかをintersectで判定しているのか下記の部分です。

// BallクラスとTargetクラスの衝突判定
Ball.intersect(Target).forEach(function(pair)
{
    //pair[0]: Ballのインスタンス
    //pair[1]: Targetのインスタンス
    game.rootScene.removeChild(pair[0]);
    game.rootScene.removeChild(pair[1]);
});

ここで便利なのが.forEach(function(pair)です。これで衝突した2つのインスタンスを取得できるため、当たったら画面から消すといった処理も行えます。

なお、Ballクラスの記述は以下の通り。

    // ボールクラス
    var Ball = Class.create(Sprite, {initialize:function(){
        Sprite.call(this,16,16);

        this.image = game.assets['icon1.png'];
        this.x = kuma.x + Math.floor(kuma.width/3);
        this.y = kuma.y + Math.floor(kuma.height/3);
        game.rootScene.addChild(this);

        // 重力
        this.ang = -5;      // 飛び出す勢い(高さ方向)
        this.grav = -10;    // 重力(下にひっぱる力) 

        // 定期処理
        this.addEventListener('enterframe', function(){
            //横に常に移動します
            this.x += 2;
            this.y = this.y + this.ang + this.grav;
            this.grav += 1;

            // 一定のエリアを出たら消す
            if(this.x > 320 || this.y > 260 || this.x < 0 || this.y < 0)
            {
                game.rootScene.removeChild(this);
            }
        });
    }});

サンプルプロジェクト

得点計算などは行っておらず、衝突判定の処理のデモだけです。
http://code.9leap.net/codes/show/143736

3
2
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
3
2