2012-01-13 13 views
2

朝、私はHTML5のCanvas APIをいじってきたし、そうすることの楽しみのかなり多くを持っていた過去数ヶ月にわたりHTML5キャンバス衝突検出「globalCompositeOperation」パフォーマンス

私は徐々に自分自身にゲーム開発のやりとりを教えるためのいくつかの小さなゲームを作成しました。私は基本的な衝突の検出、つまりサークルとプラットフォームの衝突を実行できるようになっています(そこではかなり単純ですが、最初に作業を開始したときにはかなりの成果を得ていました。実際に起こっている)。私は、多くのシナリオでは、上記の方法で十分に良い結果を得ることができ、この方法は明らかにリソースが非常に高価であるため、ピクセル衝突検出はすべてのゲームではないことがわかります。

しかし、私はただ脳波を持っていました(これは他の誰かがこれを考えていた可能性があり、私はフィールドを下っていますが、私はそれを探知して何も見つけませんでした)。

キャンバスの「globalCompositeOperation」機能を使用/使用することは可能でしょうか?私の最初の考えは、そのメソッドを "xor"に設定してキャンバス上のすべてのピクセルを透明にすることでした。ピクセルが見つかると、衝突が発生するはずです。右?明らかにこの時点で、問題のピクセルがどのオブジェクトによって占有されているか、どのように対処するかを検討する必要がありますが、他の手法ではこれを行う必要があります。

シェイプがオーバーラップしているときに動作するように、すでにこの衝突検出をキャンバスで行っています。これを拡張することは可能でしょうか?

アイデア?

ゲイリー

答えて

2

キャンバスが(それはまだ始まったばかりであり、おそらくB/C)、これを自動的に行いません。 easeljsは、マウスの出入りイベントに対してこの手法を採用しており、が極端にで非効率的です。私は境界を決定するアルゴリズム的なアプローチを使用しています。私はそれを使用して、マウスが形状の内側か外側かを確認します。理論的には、このようにヒット検出を実装するには、両方の図形のすべての点を取って、それらが他の形になっているかどうかを確認するだけです。私のコードのいくつかを見たい場合は、私に知らせてください

しかし、あなたの方法は非常に非効率的ですが、どの形状にも適用可能です。

+0

こんにちは@puk、ご返信ありがとうございます。あなたはそれが自動的にそれをしないと言うとき...私は、キャンバスが何かが起こっていることを知っている必要があります重なり合っているときにピクセルを透明にするために自動検出が実行されていないことを知っています。私はまた、最初に私に当たったときのパフォーマンスを疑ったが、それについて考えてみると...円形の衝突検出を備えた単純な小惑星ゲームでは、すべてのエンティティを互いに比較し、それぞれの間で3〜マウントする。私はあなたを信じていますが、テストするためにデモを打つことができるかどうかを試してみることがあります。 – Gary

+0

@Gary彼らはeaseljsでそれを使用していましたが、それはちょっと遅かったです。http://stackoverflow.com/questions/2573212/why-is-setting-html5s-canvaspixelarray-values-ridiculously-slow-and-how-can-id – puk

+0

@ゲイリー私はそれがどのように行くのか覚えていないが、これは次のようなものです:一時的なキャンバスに図形を描画し、ポイントが色を持っているかどうかを確認するか、透明かどうかを確認します。それはポイントが内部にあるかどうかをチェックする方法です。その後、衝突検出に使用します – puk

1

あなたが言及したようにglobalCompositeOperationxorに設定されたオフスクリーンキャンバスを使用して衝突検出を行うコードフェンでデモを行いました。コードは簡潔でシンプルなので、小さな「衝突のキャンバス」でOKのパフォーマンスが得られるはずです。

http://codepen.io/sakri/pen/nIiBq

1

あなたは、XORモードフルスクリーンを使用している場合、第二段階は、高コストの段階で画面のgetImageDataにあり、次のステップは、衝突に関与されたオブジェクトを見つけることです。
ベンチマークする必要はありません。遅すぎるでしょう。

「クラシック」バウンディングボックステストを使用してから、オブジェクトの内側BBOxesをテストし、ピクセルをローカルに移動した後にのみテストすることをお勧めします。
内側のバウンディングボックスでは、私はあなたがオブジェクトの内部に完全であることが確信しているそのため、矩形、この例では、赤みを帯びた部分を意味:

enter image description here

だから、この混合戦略を使用します。
- DOをあなたのオブジェクトのバウンディングボックスのテスト。
- 2つのBBoxの間に衝突がある場合は、内部境界ボックステストを実行します。スプライトの内側のボックスが重なっている場合、衝突が発生している可能性があります。
- 本当に問題のある場合のみピクセル完全テストを行い、より大きなスプライトのサイズを持つ一時キャンバスに両方のスプライトを描画するだけでよいのです。はるかに高速なgetImageDataを実行できます。このステップでは、どのオブジェクトが衝突に関係しているかを知っています。

enter image description here

あなたは低解像度のコストでより速くgetImageDataを取得するには、小さなキャンバスの上に、規模とスプライトを描画することができます注意してください。
スムージングを無効にすることを忘れないでください。私はすでに8X8キャンバスで十分であるはずです(スプライトの平均速度によりますが、スプライトが遅い場合は解像度を上げてください)。
このようにデータは8 X 8 X 4 = 256バイトと大きく、良いフレームレートを維持できます。

また、内部のBBoxの計算方法を決めるときには、内部のBBoxに一定の数の空のピクセルを入れることができます。