質問: tmlib.jsを用いたブロック崩しゲームで次のようにコリジョンを設定しています。 ボールに`this.setBoundingType("circle");` パドルに`this.setBoundingType("rect");` コリジョン判定で次のように判定しているのですが、`circle`同士のコリジョンと判定されているようです。 ``` if (this.isHitElement(paddle)) (thisはボール) ``` 具体的なソースコードはこちらです(runstantサイトで作成)。 次の『11.ボールとパドルの当たり判定』のコードを引用させていただいています。 『tmlib.jsでゲームをつくってみよう!』 分かりやすいようにfps値、ボールとパドルのサイズ、パドルの位置を変更し、ぶつかった時のボール位置調整をカットています。 `tmlib.js`本体のソース(`tm.app.Object2D.js`の`isHitElement`)を確認すると確かに`circle`と`rect`では 取れないようです。何かうまく判定する方法はないでしょうか?
回答: tmlib.js の内部挙動としては isHitElement を呼び出す側, つまり今回でいう this の boundingType が優先される実装になっています. circle と rect の衝突判定は円x円, 矩形x矩形と比べて負荷が大きいため そのような実装になっています. どうしても必要ということであれば別途メソッドとして作ります!! 一旦仮で circle と rect の衝突判定を作ってみました. runstant -> code ``` var testCircleRect = function(circle, rect) { // まずは大きな矩形で判定(高速化) var bigRect = tm.geom.Rect(rect.left-circle.radius, rect.top-circle.radius, rect.width+circle.radius*2, rect.height+circle.radius*2); if (bigRect.contains(circle.x, circle.y) == false) { return false; } // 2種類の矩形と衝突判定 var r = tm.geom.Rect(rect.left-circle.radius, rect.top, rect.width+circle.radius*2, rect.height); if (r.contains(circle.x, circle.y)) { return true; } r.set(rect.left, rect.top-circle.radius, rect.width, rect.height+circle.radius*2); if (r.contains(circle.x, circle.y)) { return true; } // 円と矩形の4点の判定 var c = tm.geom.Circle(circle.x, circle.y, circle.radius); // left top if (c.contains(rect.left, rect.top)) { return true; } // right top if (c.contains(rect.right, rect.top)) { return true; } // right bottom if (c.contains(rect.right, rect.bottom)) { return true; } // left bottom if (c.contains(rect.left, rect.bottom)) { return true; } return false; }; ``` やっぱりかなりコードは長くなっちゃいますね. ただ頭でかなりの頻度で弾けるので入れちゃっても良いかもと思います. 再度検討してみます.