2Dタイルベースのゲームで、スクロールに適した方法は何ですか?


9

D3DXSPRITEラッパーでDirect3Dを使用して、タイルを画面に描画しています。衝突やタイルタイプなどのメンバーを含むタイルクラスがあり、次にタイルの配列があります。

タイルグリッド[256] [256];

どちらがより良い方法でしょうか?

-画面の中央にプレーヤーを描画し、マップが描画する場所をオフセットします。

・以下のカメラでプレイヤーを移動します。

最初の方法を使用していましたが、マップの左上端に到達したとき、および他のプレイヤー/敵がマップ上にいて同時に移動しているときは、非常に複雑になります

カメラをプレーヤーに追従させる場合、画面に収まる数が少ない場合でも、グリッドタイルごとにspriteBatch-> Draw(...)を呼び出す必要がありますか?

回答:


4

すべての更新と計算を「実際の」ワールド単位で行い、カメラを移動するのがおそらく最善です。spriteBatch自体がカリングを実行する可能性がありますが、遅すぎる場合は、画面に表示する必要のあるタイルを特定し、それらを描画することのみを試みることができます。


特にグリッドのサイズを大きくする必要がある場合は、表示されているスプライトのみを描画するコードを記述したいと思うでしょう。

2

世界座標でカメラを動かし、キャラクターを世界中で動かすことは、この問題に取り組む最も簡単な方法です。世界座標で作業することは、他のすべてのシステムで機能する必要がある場合、余分な計算を行う必要がないことを意味します。相対座標系およびそれらが世界座標のどこにあるかも理解します。

2Dで作業しているため、仮想パーティションのグリッドシステムを作成する最も簡単な方法は、空間分割を行うことです。これにより、スプライトやその他のリソースをタイルごとに関連付けることで、各タイルを個別に管理できるため、本質的には、プロセスは次のようになります。

  • タイルの境界座標と、特定のタイルに必要なリソース(スプライト、敵など)を保持できるタイルクラスを作成します。

  • 世界のサイズを決定し、関連するすべてのリソースで世界のビットを表すタイルの2D配列を作成します(1次元を使用して2Dとしてアクセスできます)。

  • プレイヤーがいるタイルとその隣のタイルからのみリソースを引き出します。

グリッドを使用すると、グリッドの開始点に対するプレーヤーの位置に基づいて、プレーヤーがどのタイルにいるかを簡単に見つけることができます。

カメラについて述べた問題を回避するには、プレーヤーとカメラを2つの独立したシステムにして、カメラがエッジタイルの中心よりも先に移動しないようにする必要があります。これにより、プレーヤーがそのタイルに移動しても、プレイヤーはタイル全体を移動できます。世界座標に拘束されている(つまり、画面の中央に配置されていない)タイル全体。ただし、カメラはロックされています。


0

表面を使用しています。オフスクリーンサーフェス上に全世界を作成し、x座標とy座標を維持します。プレイヤーが移動するときにこれらを変更し、各フレームがxとyを使用してサーフェスからバックバッファーに1028 x 768の長方形を描画します。

他の人々については、xとyを与えて、好きなように世界中を動かせるようにします。描画するときに、xとyが1028 x 768の長方形にあるかどうかを確認し、ある場合はそれらを描きます(私は人々にテクスチャを使用しています)。 。

画面の中央にプレーヤーがいて、世界の端が画面の端に達しているかどうかを確認します。この状況では、プレーヤーは画面の周りを世界の端に移動し、中心に戻ってから、世界が再び動き始めます。難しいようで少し時間がかかりましたが、悪くはありません。

私は64 x 64タイルを使用しており、これまでに使用した最大の世界は50 x 60タイルです。

これはすべてc ++の直接xで行われます


1
これは巨大なメモリの独り占めのようです。ワールド全体をサーフェスのオフスクリーンに描画したままにしておくと、ワールドに複数の(アニメーション化された)レイヤーを作成し、現在のレイヤーよりもさらに拡大したい場合など、メモリの問題に直面することになります。世界に関する情報を保持し、描画する必要があるときに描画する必要があるパーツ/オブジェクトのみを描画する方がはるかに良いでしょう。ちょうど私の2セント。:)
Richard Marskell-Drackir、2011年

@ドラッカー私はあなたが誤解していると思います。世界だけが画面から描画されます。他の人々のようなものが追跡され、必要なときにバッカーバッファーに描画されます。また、70 x 70の世界を超えて自分を見ているとは思いません。「世界」とは、エリアを意味します。これは、ダンジョンの町か、家の中かを示します。プレイヤーがそれらの間を移動すると、画面外の表面が再構築されます。はい、それはメモリを必要としますが、現代のテラバイトドライブの2Dタイルはそれを無視できるようにし、数秒のロードはスムーズなスクロールとアニメーションのために支払うための小さな代償です。しかし、はい、より良い方法と難しい方法があります:)
Skeith '17年

表面は、ハードドライブではなく、GFXカードのメモリに保存する必要があります。ただし、GFXカードのメモリが大きすぎると、サーフェスがHDに移動し、速度がかなり遅くなると思います。確かに、私はそれを扱ってからしばらく経っていたので、それがどのように機能したか正確には覚えていませんが、あまりにも大きな世界を描いていない限り、大丈夫だと思います。:)
Richard Marskell-Drackir、2011年

@Drackir知っておくと面白いですね。この方法でスクロールがスムーズになることを発見しました。動的に新しいタイルを描いた場合、それはうまくいくと思いますが、詳しく調べる必要があります。
Skeith、

私は31x31のマップを持っているゲームに取り組んでいましたが、それらは並べて接続されていました。私は他の誰かのエンジンを使って作業してみましたが、彼らはプレイヤーがいる地図を取り巻くすべての地図を描きました。合計で9つのマップです。各マップにはいくつか(6つと思います)のレイヤーがありました。したがって、ユーザーがマップを切り替えるたびに、31x31x9x6 = 51894のタイルが描画されます(もちろん、最大で、すべてのタイルが一杯ではありませんでした)。これは私にとって非常に遅くなったため、描画ルーチンを書き直して、プレーヤーの周囲のタイルのみを画面の端から1タイルまで描画します(移動中に一部のタイルを処理するため)。
リチャードマースケル-Drackir、2011年

0

どのタイルを描画するかを検討し、同時にカメラが「オフワールド」にならないようにするときに、コードがタイル張りの世界の隅で少し面倒になるのはごく普通のことです。これらのエッジケースは、基本的に、画面解像度よりも大きい2Dタイルベースの世界を実装する上で最も重要なことです。ズームインとズームツーカーソルをサポートしている場合は、はるかに複雑になります。D

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.