落ちてゆくクマ 〜衝突判定の例〜

twitterのTLで「落ちてきたオブジェクトが床にめり込まないようにするにはどうするか」というお題を見かけました。せっかくなので「Swipe Action !」でやったやり方を書いておきます。

まぁロジックとしては、0から1フレームあたりの最大落下距離まで、何かに当たらないかチェックしてゆくという原始的な方法。それ以外浮かびませんでした。

       // 落下物
      sprite = new Sprite(32, 32);
      sprite.image = game.assets['chara1.gif'];
      game.rootScene.addChild(sprite);
      // チェック用Entity
      entity = new Entity();
      entity.width = sprite.width;
      entity.height = sprite.height;
      game.rootScene.addChild(entity);
      // 床
      floor = new Sprite(320, 32);
      floor.image = new Surface(320, 32);
      floor.image.context.beginPath();
      floor.image.context.fillRect(0, 0, 320, 32);
      floor.y = 320 - floor.height;
      game.rootScene.addChild(floor);
      // 最大落下距離
      MAX_MOVE = 6;
      game.rootScene.onenterframe = function(e) {
          for (var i = 0; i < MAX_MOVE; i++) {
              entity.y++;
              if (floor.intersect(entity)) {
                  entity.y--;
                  break;
              }
          }
          sprite.y = entity.y;
      };

Swipe Action !」ではMapを使用していたため、チェック用Entityは用意していません。またチェック関数はMap.hitTestを使用した独自の関数です。ただ、ロジックは上のソースと何ら変わりありません。

しかしEntityは本当に便利。実体は持ちながらも、それだけではユーザから見えることがない。さながら透明人間のようなオブジェクト。今回のように、何かを事前チェックしたいという場合は、ひとつ裏で用意しておくと使い勝手がいいと思います。