Skip to content

エンティティ同士の当たり判定を調べる

エンティティ同士の当たり判定を調べるには g.Collision#intersectEntities()g.Collision#intersectAreas(), g.Collision#withinAreas() を利用します。

凡例

javascript
var rect1 = new g.FilledRect({ ... });
var rect2 = new g.FilledRect({ ... });

g.Collision.intersectEntities(rect1, rect2); // rect1 と rect2 が衝突している場合は真を返す

// 親が同じエンティティで回転・拡大を行わない場合や中心座標同士の距離だけで判定してよい場合は
// より軽量な intersectAreas(),  withinAreas() が利用できます。

// 親が同じエンティティで回転・拡大を行わないエンティティ同士の場合
g.Collision.intersectAreas(rect1, rect2);

// 親が同じで中心座標同士の距離だけで判定してよい場合
g.Collision.withinAreas(rect1, rect2, 2); // 中心座標同士の距離が 2 以下なら真を返す

利用例

次のコンテンツは、青の矩形をドラッグ/スワイプし黒の矩形と衝突すると青の矩形の色が赤に変わります。

詳細

二つのエンティティの当たり判定を行うには、g.Collision.intersectEntities() を利用します。

g.Collision.intersectEntities() は回転・拡大されたエンティティや、親の異なるエンティティ同士も扱えます。ただし、計算量が多いので大量のエンティティ間のすべての衝突を確認するような状況では利用を避けるべきです。

親が同じで回転・拡大を行わないエンティティ同士の場合は、より軽量な g.Collision.intersectAreas() を利用できます。

javascript
function main() {
  var scene = new g.Scene({ game: g.game });
  scene.onLoad.add(function () {
    var rect1 = createRect(scene, 50, 50, 0, 0, "blue", true);
    var rect2 = createRect(scene, 100, 100, 150, 150, "black", false);
    scene.append(rect2);
    scene.append(rect1);

    rect1.onPointMove.add(function (ev) {
      rect1.x += ev.prevDelta.x;
      rect1.y += ev.prevDelta.y;
      rect1.modified();
    });
    rect1.onUpdate.add(function () {
      // rect1 と rect2 が衝突している場合は真が返る
      var ret = g.Collision.intersectAreas(rect1, rect2);
      if (ret) {
        // 衝突している場合
      } else {
        // 衝突しなかった場合
      }
    });
  });
  g.game.pushScene(scene);
}

function createRect(scene, width, height, x, y, color, isTouchble) {
  return new g.FilledRect({
    scene: scene,
    width: width,
    height: height,
    x: x,
    y: y,
    cssColor: color,
    touchable: isTouchble
  });
}

親が同じで中心座標同士の距離だけで判定してよい場合は、より軽量な g.Collision.withinAreas() を利用できます。2 つの矩形の中心座標間距離による衝突判定を行いその結果を返します。 第三引数は衝突判定の閾値(中心座標間の距離)となり省略時は 1 となります。

javascript
var distance = rect2.width / 2 + rect1.width / 2; // 衝突判定の閾値
rect1.onUpdate.add(function () {
  // rect1 と rect2 の中心座標の距離が distance 以下の場合は真が返る
  var ret = g.Collision.withinAreas(rect1, rect2, distance);
  if (ret) {
    // 衝突している場合
  } else {
    // 衝突しなかった場合
  }
});

注意する点として、対象のエンティティの座標や大きさなどを変更した場合は、これらの関数を呼び出す前にそのエンティティの modified() を呼び出しておく必要があります。

関連情報