9

私は、破壊可能な地形 (ゲームのワームやスコーチド アースなど) を持ち、マスクを介してピクセル パーフェクトな衝突検出を使用するゲームに取り組んでいます。

レベルは単一のサーフェスであり、現在どのように機能するかというと、フレームごとにコピーを作成し、描画が必要なすべてのスプライトを描画してから、可視領域をディスプレイ サーフェスにブリットします。

フレームごとにレベル サーフェス全体をコピーせずに、pygame にあるピクセル パーフェクトなコリジョン ツールを使用できる方法はありますか?

最初にレベル サーフェスをブリットしてから、画面上のすべてのスプライトをブリットしてみました (座標が静的なプレイヤー キャラクターを除いて、ブリット座標はカメラによって調整されます)。それを修正することはできないようです。

アップデート

私は次の方法でそれを機能させることができました。レベルの可視領域)。

衝突検出フェーズでは、水平面に対して配置された座標と境界ボックスを使用します。上記のように。問題は、カメラの位置がプレイヤーの位置にバインドされていることです。これは静的な値ではなく、そうであってはなりません (どうやってそれを長い間認識できなかったのか、本当にわかりません)。

これで問題は解決しますが、以下の回答は、このような状況でパフォーマンスを改善する方法についてのより包括的な見方です。また、試練をより簡単または迅速にする他のライブラリを使用するための提案も受け付けています。pyglet と rabbyt について考えてみましたが、同じ問題が存在するようです。

4

1 に答える 1

6

これは、コンピュータが遅かったグラフィック アクセラレータが登場する前の時代によく発生した問題です。基本的に、画面を更新するために必要な作業を最小限に抑えたいと考えています。あなたは正しい道を進んでいますが、次のことをお勧めします。

  1. 現在行っているように、バックグラウンドのコピーをオフスクリーンで使用できるようにします。

  2. 画面と同じサイズの作業ビットマップを割り当てます。

  3. スプライトごとに、新しい位置と古い位置の境界四角形 (境界ボックス) を計算します。

  4. 新しいバウンディング ボックスと古いバウンディング ボックスが重なっている場合は、それらを 1 つの大きなボックスに結合します。重ならない場合は、別々に扱ってください。

  5. すべての境界ボックスを重複するセットにグループ化します。それらはすべて 1 つのセットになる場合があります (スプライトが互いに近い場合)。または、各バウンディング ボックスが単独でセットになる場合もあります (スプライトが離れている場合)。

  6. 各バウンディング ボックス セットに対応する作業ビットマップの領域に背景をコピーします。

  7. 各セットのスプライトを作業中のビットマップの新しい位置にコピーします (もちろん、正しい z オーダーで!)。

  8. 最後に、完成したオフスクリーン ビットマップをディスプレイ サーフェイスにコピーし、バウンディング ボックスを設定してバウンディング ボックスを設定します。

このアプローチにより、バックグラウンドとスプライトの両方で行う必要のあるコピーの量が最小限に抑えられます。スプライトが表示領域に対して小さい場合、大幅な節約になります。最悪のケースは、スプライトがすべて対角線上に配置され、互いにかろうじて重なっている場合です。この場合、ボックスよりも一般化されたバウンディング シェイプに切り替えることができます。例については、QuickDraw Regions をご覧ください: Wikipedia ディスカッション 特許 ソース

バウンディング ボックスをセットにグループ化する作業は O(n^2) 操作だと考えているかもしれませんが、その通りです。ただし、スプライトの数の 2 乗でしか成長しません。16 個のスプライトは 256 回の比較を意味します。これはおそらく、単一のスプライト ブリットよりも手間がかかりません。

ピクセルコピー作業を最小限に抑えることに重点を置きました。私はあなたの衝突検出ライブラリの詳細に精通していない管理者でなければなりませんが、私はその考えを理解しています. うまくいけば、それは私が提案したアルゴリズムと互換性があります。

幸運を。ゲームを終了してオンラインに投稿する場合は、質問またはコメントにリンクを追加してください。

于 2012-05-10T07:41:52.197 に答える