当たり判定を厳密にする
options.bounds: Boolean – hit test the corners and side-centers of the bounding rectangle of items (item.bounds).
hitTestの使い方を調べていると、オプションとしてboundsを設定できることがわかりました。これを設定すると、四隅、辺の中点の当たり判定をしてくれるみたいです。デモでちゃんと動いているのかいまいち不安ですが・・・笑。
・ドキュメント
http://paperjs.org/reference/item/#hittest-point
hitOptionsを定義
options: Object — optional, default: { fill: true, stroke: true, segments: true, tolerance: 2 }
デフォルトの設定が上のようになっています。ですのでこれに書き加える形にしました。
var hitOptions = { segments: true, stroke: true, fill: true, tolerance: 2, bounds:true//追加 };
boundsを追加しました。
var hitResult = player.hitTest(bullets[j].path.bounds.bottomLeft,hitOptions) || player.hitTest(bullets[j].path.bounds.bottomCenter,hitOptions) || player.hitTest(bullets[j].path.bounds.bottomRight,hitOptions) || player.hitTest(bullets[j].path.bounds.topLeft,hitOptions) || player.hitTest(bullets[j].path.bounds.topCenter,hitOptions) || player.hitTest(bullets[j].path.bounds.topRight,hitOptions);
hitOptionsのboundsにより、playerの当たり判定が厳密になりました。さらにplayerに対する弾丸の当たり判定も厳密にしなければなりません。これはここに設定する必要があります。めんどくさいですが、四隅と辺の中点を設定しました。
弾丸を複数生成する
弾丸を複数生成しました。シンボルで生成していましたが、個々の弾丸の速度を定義するのが大変だったので、オブジェクトを定義しました。オブジェクトって言えばいいのか、クラスっぽいものと言えばいいのか、よくわかりませんが・・・。
//弾丸を生成 for(var i = 0;i < 7;i++){ bullets.push(new Bullet(i)); } function Bullet(i){ this.vx = getRandomNum(vMin,vMax); this.vy = getRandomNum(vMin,vMax); this.path = new Path.Circle({ center:[50 + i * bulletRadius * 3,view.size.height - 50], radius:bulletRadius, fillColor:"#f39c12" }); }
弾丸同士の衝突
//弾丸同士当たり判定 for(var k = 0;k < bullets.length;k++){ var hitResult3 = bullets[j].path.hitTest(bullets[k].path.position,hitOptions); if(hitResult3){ //質量が同じ物体同士の完全弾性衝突 //速度が入れ替わる var tmp = bullets[j].vx; bullets[j].vx = bullets[k].vx; bullets[k].vx = tmp; tmp = bullets[j].vy; bullets[j].vy = bullets[k].vy; bullets[k].vy = tmp; } }
質量が同じ物体同士の完全弾性衝突なので、速度が入れ替わります。物理でやりましたね。懐かしい!!
http://www.wakariyasui.sakura.ne.jp/b2/52/5232nibuttai.html
反省
シンボルをやめて弾丸を作った結果、描画が遅くなりました。やっぱりシンボルのまま作って、速度だけ専用の配列を用意すれば良かったかもしれません。