3

あまりわかりやすいタイトルではないかもしれませんが、頑張っています。StackOverflow に投稿するのは初めてで、C# でのプログラミングには比較的慣れていません (最初は約 1 年前に Unity を使用して開始し、数日前に XNA にアップグレードすることにしました)。そうは言っても、私に親切にしてください。

私は設計中の 2D ゲームの仕組みを計画しています。XNA で遊んだ後はほとんどが簡単に思えますが、満足のいく答えがまだ出ていない 1 つの問題に何度も戻ってきます。為に。この問題には、スプライトを複合/複雑なスプライトにレイヤー化することが含まれます。たとえば、ゲーム内のキャラクターは、任意の数の武器のうちの 1 つまたは 2 つを使用している可能性があります。このトピックについて少し調査したところ、RenderTarget クラスを使用して一連のスプライトを 1 つに描画することを推奨する人もいれば、Draw() 中にスプライトを重ねて描画することを推奨する人もいます。ただし、これらのトピックは主に、ゲーム内に 1 人のキャラクターがいるという比較的単純なケースに焦点を当てていました。

私の場合、ゲームには、まったく異なる姿勢/アニメーションを持つ多数のスプライト ベースのキャラクターが含まれます。現在は約 10 個あり、開発中にさらに追加される可能性があります。同様に、キャラクターに合成される多数の武器 (おそらく最初は約 20) があります。それくらい気が楽です。ただし、問題は、キャラクターのアニメーションの各フレームで、各キャラクターの武器スプライトを異なる場所に異なる回転で描画する必要があることです。

これを実現する方法についていくつかのアプローチを検討しましたが、いずれもかなり大きな欠点があります。
1 つ目は、各キャラクターの各武器のスプライトシートを単純に描画することでした。これは、適切なキャラクターと同じサイズになります。このアプローチの利点は、計算を行うことなく、ベース キャラクターの上に追加のスプライトを描画するための呼び出しを追加するだけで簡単になることです。欠点は、余分なスプライト シートが大量に作成されることです (10 キャラクター x 20 武器に対して 200 枚の余分なシート)。

2 つ目は、武器のスプライトを処理するクラスを作成することでした。WeaponSprite クラスは、武器ごとに 1 つのテクスチャにアタッチされ、アタッチされているキャラクターに基づいて、描画時に使用するオフセット/回転に関する情報を格納します。これに関する問題は、フレームごとにオフセット/回転を整理するのは非常に面倒であり、必要なフレームに基づいて情報を取得する簡単な方法が思いつかないことです。(各キャラクターのアニメーション名、向き、フレーム番号を追跡する AnimationFrame クラスを作成し、武器クラスの辞書を使用して、現在のフレームの名前に基づいて適切なデータをロードするというアイデアがありました。しかし、そのアイデアについての何かが本当に考えが間違っているように見えました)。この方法には、プルオフするために比較的大量のメモリが必要になるという欠点もあります (Vector2 が 8 バイトで float が 4 であると仮定すると、10 のキャラクターと 20 の武器がある場合、現在使用されているフレーム数を考えると 192 KB のメモリが必要になります。より多くの武器が追加されるにつれて、これは大きくなるだけです)。私は、予約されたアルファ値ピクセルを使用して各武器のオフセットと「原点」をリンクし、実行時に位置を計算し、次に前述のディクショナリに回転フロートを格納するだけです。より多くの武器が追加されるにつれて、これは大きくなるだけです)。私は、予約されたアルファ値ピクセルを使用して各武器のオフセットと「原点」をリンクし、実行時に位置を計算し、次に前述のディクショナリに回転フロートを格納するだけです。より多くの武器が追加されるにつれて、これは大きくなるだけです)。私は、予約されたアルファ値ピクセルを使用して各武器のオフセットと「原点」をリンクし、実行時に位置を計算し、次に前述のディクショナリに回転フロートを格納するだけです。

私は XNA を初めて使用するので (そして C# についてはまだかなり未熟です)、投稿して専門家の意見を取り入れようと考えました。私の方法は正しい方向に進んでいますか? ご協力いただきありがとうございます。追加情報が必要な場合はお知らせください。

4

1 に答える 1

2

うわー、大きな質問。これを実装する方法を正確に説明することはできません。しかし、私はあなたにいくつかの役立つアドバイスを与えることができます:

アドバイス#0:何らかの合成の問題が発生するたびに、人々は木工品から出てきて、ある種の合成の万能薬として「レンダリングターゲット」を推奨します。彼らは通常間違っています。可能であれば、レンダーターゲットの使用は避けてください。これらは、最終的な合成画像(ブレンド、ブラーなど)にエフェクトを適用する場合にのみ必要です。それ以外の場合は、スプライトを互いの上に直接バックバッファに描画します。

アドバイス#1:可能であれば、すべてのスプライトを1つのスプライトシートにパックします。テクスチャサイズの制限を超える場合は、スプライトをシート間でどのように分割するかを慎重に検討する必要があります。その理由はパフォーマンスです-テクスチャスワップの数を制限したい-詳細については、この回答を参照してください

XNA用の既存のスプライトパッカーを使用できる場合があります。適切なものが見つかったら、それを使用することをお勧めします。良いものを使用すると、を呼び出すときにテクスチャを処理するのと同じように、パックされたスプライトを処理できますSpriteBatch.Draw

アドバイス#2:実行時にポジショニングデータがどれだけのスペースを占めるかについて心配する必要はありません。192kbはほとんど何もありません-小さなテクスチャのサイズ。

これの結果、そして#1は、ポジショニングメタデータに可能な限り多くを保存し、テクスチャの重複を避けることです。

メタデータをどのように保存するかはほとんど問題ではありません。

アドバイス#3:ストレージ要件とコンテンツ作成ストーリーの両方をn×mの問題からn + mの問題(n個のキャラクターとm個の武器)に変更できます。武器は「オリジン」のみで保管し、キャラクターは「オリジン」と「手の位置と回転」で保管するだけです。武器の原点がキャラクターの手と揃うようにレンダリングするだけです(計算は非常に簡単です)。

そうすれば、どの武器が存在するかを気にせずにキャラクターを追加したり、どのキャラクターが存在するかを気にせずに武器を追加したりできます。

これに必要なスペースの例を次に示します。10文字×20バイト+20武器×8バイト=360バイト。素敵で小さい!(おそらく、もっと多くのアタッチメントポイント(武器や帽子などごとに異なる種類)が必要になるでしょう。編集:おっと、アニメーションフレームは含めませんでしたが、それでも比較的少量のデータです。)

アドバイス#4:投稿でほのめかしているように、最も難しい部分はコンテンツの作成です。

ほのめかすように、理想的には、画像エディタでアタッチメントポイントを直接編集できるようにする必要があります。これは説得力のあるアイデアです。特別なアルファ値は、スプライトにアンチエイリアシングがない場合にのみ適切です。理論的には、レイヤーと異なる色で何かを行うことができます。最も難しい部分は、回転をエンコードする方法を理解することです。

XNAコンテンツパイプラインプロセッサを使用して、ビルド時にイメージからデータを抽出できます。ただし、これを実装するには非常にコストがかかります(特に、これまでに実装したことがない場合は、コンテンツパイプラインのドキュメントが大幅に不足しています)。アートの要件が本当に膨大でない限り、コンテンツパイプラインを拡張するために必要な追加の開発時間の価値はほとんどありません。完了するまでに、測位データを数回手作業でコーディングすることができます。

したがって、私の推奨事項は、追加のデータを編集しやすいXMLファイルに保存することです。XNAのXMLコンテンツインポーターを使用することをお勧めします。最初にフォーマットのコツをつかむのは難しい場合があり、適切なアセンブリ参照を含めることを忘れないでください。ただし、使用方法がわかれば、構造化データをXNAにすばやく取り込むための最も簡単な方法です。

于 2012-09-26T08:30:20.833 に答える