「実際の単位」をピクセルにスケーリングする一般的なパターンは?


10

これは、これに対するもう1つの質問です。

描画領域(現在は800x600ピクセル)に合わせるために、世界の表現(現在は160Kmx160Km)スケーリングするための一般的/典型的/最良のパターンがあるどうかを知りたいです

私は少なくとも4つの異なるアプローチを考えることができます。

ナイーブ(これまでのやり方)sc(vector)渡されたベクトルの縮小されたコピーを返すだけのグローバル関数を実装しました。もちろんこれは機能しますが、次のようなコードを書く必要があります。

drawCircle(sc(radius), sc(position))

ラッピング関数。私はいくつかの関数を定義でき、それぞれが元のミドルウェアの関数をラップしています。たとえば、myDrawCircle最初にスケーリングが必要な引数をスケーリングし、次にdrawCircle後者を呼び出すように定義できます。これにより、コードが読みやすくなり、メンテナンスが容易になりますが、馬鹿げているように思える多くのラッピング関数を作成する必要があります。

関数デコレータ。既存のミドルウェア関数を装飾して、クラスのインスタンス化であるすべてのパラメーターに自動スケーリングを提供することもできますVector3Dが、問題はこれらの関数も同じパラメーターで動作listするVector2Dことであり、デコレーターは知る方法がありません。スケーリングする必要があるリスト(半径など)とスケーリングしないリスト(RGB値)。

表面の初期化。描画する表面を定義するときに、倍率を定義できます(そのため、パラメーターとしてピクセルではなくメートルを使用します)。これは私にとって透過的に機能し、私の選択するソリューションになりますが、もちろんミドルウェアに実装する必要があるため、実際のオプションではありません。

...とにかく、これは非常に一般的な問題なので、見つけられなかったこの問題をエレガントに解決する確立されたパターンがあるのだろうか。

PS:このプロジェクトではpython(pygameを使用)を使用していますが、python / pygame固有の回答は非常に高く評価されていますが、具体的な実装ではなく、パターンの一般的/高レベルの説明に興味があります。

あなたの時間と専門知識を事前にありがとう。

回答:


6

これを行う標準的な方法は、レンダリング中に変換を行うように変換行列を設定することです。3Dレンダリングの場合は、それを行うカメラのビュー変換行列です。

ほとんどの2D APIには、ビュー変換を2x3マトリックスとして、または個別のスケール、移動、回転として指定する方法もあります。

pygameのドキュメントをざっと見てみると、ビュー変換行列を自分で実装する必要があることがわかります。サーフェスクラスから独自のクラスを派生させて、その機能を追加できるようにしていますか?


あなたの答えはとても役に立ちます(+1)。サーフェスクラスをサブクラス化することはできますが、投稿で示されていることを達成できるかどうかを調査するには、さらに時間が必要です。私はゲームプログラミングとグラフィックスに非常に慣れていませんが、このマトリックスアプローチを説明することを推奨するリンクがありますか(または、マトリックスを使用してサーフェスをスケーリングするために必要な数学だけですか?)ありがとうございました!
Mac

1
これは2Dであり、回転は含まれないため、 @ macは基本的に関数をラップすることを言っており、これらのラッパーで単純なスケール除算を使用できます。完全なマトリックスが通常使用される理由は、ほとんどのAPIがビューポートを制御するマトリックスを持っているためですが、pygameにはないので、1レイヤー上で自分で行う必要があります。
Patrick Hughes

2

これは非常にありふれた問題なので、見つけられなかったこの問題をエレガントに解決する確立されたパターンがあるのだろうか。

通常、人々は2Dゲームでランタイムスケーリングを実行しようとしません。よくある問題だとは思いません。ミニマップやその他の固定された再スケーリングが必要な場合は、多くの場合、この目的のために新しいグラフィックセットが作成されます。2Dゲームで2つの異なるズームレベルで実行するために単一のルーチンが必要になることはまれです。

3D APIを使用する場合は、この機能を無料で入手できます。カメラ/ビューポートパラメータを変更するだけです。

PyGameは非常に古いAPIであり、残念ながら2Dにのみ適しています。さまざまなズームレベルに対して適切なスケーリングシステムを作成できたとしても、パフォーマンスは十分ではなく、外観は許容できないほど悪くなる可能性があります。

大きくズームインまたはズームアウトしたい場合は、できるだけ早く最新の3D APIに移行することをお勧めします。私はピグレットをお勧めしますが、他にもありそうです。


回答ありがとうございます(+1)。pyglets過去に3Dシミュレーションに使用しました。確かにそれはよりも機能的ですpygameが、2Dのサポートはのサポートよりもかなり低レベルですpygame。入手可能なドキュメント/サンプルもあまり詳細ではありません。これは私がゲーム開発の初心者であり、最も一般的に実行される操作の基礎を本当に理解する必要があるので、私にとってはつまらないものです。:) pygameの「年齢」に関しては、あなたは正しいです。近代化は、しかし、進行中です!:)
mac

「2つの異なるズームレベルで実行するために単一のルーチンが必要になることはめったにありません」...ウィンドウのサイズやフルスクリーンゲームの解像度を変更するときに使用する方法だと思いました。あなたのコメントから私はそれが理解できないことを理解しました:代わりに「一般的」であるものへのポインタ?
mac

pygletがpygameよりも低レベルである場合、どの2D操作を実行していますか?どちらも1行のコードでスプライトを描画できます。2Dゲームのウィンドウサイズを変更しても、ピクセルとワールド単位の比率はほぼ常に一定です。つまり、スプライトをさらに描画することになります。異なる方法で描画することはありません。
カイロタン

物事の低レベルの側面:私は本当に2つのlibsのどちらかに関する専門家ではありませんが、pygletでは、(pygame.sprite.LayeredUpdatesたとえば)pygameによって提供されるグループレンダリング動作をそのままでは複製できませんでした。不変の比率については、私はあなたが何を意味するかを理解しました。あなたが説明する行動は、私が再現したいものではありませんが、明確化に感謝して、あなたの意味を理解しました!:)
mac

pygletにはOrderedGroupオブジェクトがあります-あなたまたは他の誰かが興味がある場合は、ドキュメントがここにあります:pyglet.org/doc/programming_guide/displaying_images.html#sprites
Kylotan
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.