2D空間ゲームでの等尺性グラフィックスの偽造


15

最初に、描画の問題が何であるかを正確に知っており、それを解決する方法についてさまざまなアイデアを持っています。等尺性の「錯視」が維持されるように、どのフレームを描画するかを調整する方法を見つけ出します。

私は宇宙で行われる2D鳥瞰図ゲームを書いています。Up is Northの世界でアイソメグラフィックを使用しようとしています。従来のアイソメゲームのようなゲーム世界の回転はありません(ゲームは空間で行われ、地形はありません)。ここでは例のスプライトは、私が使用しようとしていますされていますhttp://cell.stat-life.com/images/stories/AsteroidOutpost/Spaceship64.pngそれは別名(35度の視野角と自身の垂直軸を中心に回転だ64回、 iso)。画像が生成されたため、これ変更できます。

わかりやすくするために、北(上)が0度、東(右)が90度になるように指示しました。

私の問題は、使用する3Dプレーンの違いが原因で、スプライトが常に、ゲームが考えるところに直面しているように見えないことです。用語を正しく使用しているかどうかはわかりませんが、私の宇宙船は1つの平面上で回転しており、ビュー平面は物がそれ自身の平面上で回転することを期待しています。問題の描写は次のとおりです。

http://cell.stat-life.com/images/stories/AsteroidOutpost/ProjectionIssue.png 左側にはサイドビューがあり、右側にはトップダウンビューがあります。上部には、世界の宇宙船/スプライトシートビューがあります。一番下には、画面に描画されたときのスプライトの外観があります。

右上には、宇宙船がどのように回転したかを簡略化したバージョンがあります(各フレーム間が均等に分離されています)。右下には、特定の角度が画面に描かれたときにスプライト向いているように見える角度です。問題は約45度で最も顕著です。これは、船が向いているはずの方向に向けられた「スクリーンプレーン」ラインでオーバーレイされた画像です。http : //cell.stat-life.com/images/stories/AsteroidOutpost/Spaceship64RedLine.png赤い線は常に船とまったく同じ方向に向ける必要がありますが、ご覧のとおり、投影の問題が問題を引き起こしています。この問題を十分に説明していることを願っています。

編集: 赤い線はスクリーン平面上で回転しますが、宇宙船は「船平面」上で回転します。したがって、船の角度と描かれたときのスクリーン角度の大きな違いがあります。 編集を終了

この船が一方向に外れたターゲットにレーザービームを発射しているとき、それがまっすぐ前方に発射されるべきであるとき、それはかなり奇妙に見えます。

だから...私が思いついた解決策は次のとおりです:

  1. 等角図を偽造するのをやめる、大きくなる、または家に帰る。すでに私の世界を回転させます。(PS:これで問題が解決しますよね?)
  2. スプライトシートを(なんとかして)変更して、モデルが表示される「スクリーンアングル」を表すフレームを作成します。したがって、45度の画像を要求すると、実際には画面上で45度の方向を向いているように見えます。
  3. スプライトレンダリングシステムを変更して、スプライトシートとは異なるフレームを(なんとかして)取得します。「通常の」フレームを取得すると面白いように見えることを知っています。そのため、45度のフレームを取得する代わりに... 33度のフレーム(推測のみ)を取得して、ユーザーに正しく見えるようにします。
  4. 3Dを使用するだけです!とても簡単です

1つ:どのソリューションをお勧めしますか?私はそれが間違っていることを知っているにもかかわらず、2に傾いています。私はスプライト生成ツールに完全にアクセスできることを忘れないでください。方法3は2番目の選択肢です。どちらの方法でも、目的の結果を得るには、角度に数学を適用するだけです。ところで、私はそこに#4を冗談として追加しました。3Dに移行したくありません。

2つの場合:方法2または3を使用して、入力または出力角度を調整するにはどうすればよいですか?3Dプロジェクション、3Dマトリックス(2Dマトリックスは言うまでもありません)、および他の数学を使用して望みの結果を得るには、それほど得意ではありません。

ここで大声で考えてみましょう:船が見たい方向に向いている単位ベクトルを(スクリーンプレーンで)取得し、それを船のプレーンに投影し、その投影されたラインと飛行機の角度北は、表示したい船のグラフィックの角度が必要です。正しい?(#3の解決策?)男...私はそれを解決できません。

編集:

私は問題を静的な画像で視覚化するのが難しいことを知っているので、Sprite Library Visual Testerをコンパイルして問題を表示しました:http : //cell.stat-life.com/downloads/SpriteLibVisualTest.zip XNA 4.0が必要ですこのアプリケーションは単純にスプライトを回転させ、その中心点から船が向いているとゲームが考える角度で外側に線を引きます。

9月8日編集

「大声で考える」パラグラフの続き:プロジェクションを使用する代わりに(ハードに見えるため)北向きの単位ベクトル(0x、1y、0z)を取り、マトリックスを使用して角度に回転できると考えていますスプライトは実際に向いているので、X軸を中心に「ビューイングプレーン」から「スプライトプレーン」まで外側に回転させてから、...平らにしますか?XおよびYのみを使用して(Zを無視して)ベクトルを(本質的に投影して)表示面に戻します。次に、その新しい平坦化されたベクトルを使用して、その角度を決定し、それを使用して...何かをすることができました。後でもっと考えます。

9月8日編集(2)

私はいくつかの成功を収めて上から私のアイデアをフォローしようとしました!だから...赤い線を宇宙船からまっすぐに出ているように見せるために(テスト目的のみ)、私は次のことをしました:

Vector3 vect = new Vector3(0, 1, 0);
vect = Vector3.Transform(vect, Matrix.CreateRotationZ(rotation));
vect = Vector3.Transform(vect, Matrix.CreateRotationY((float)((Math.PI / 2) - MathHelper.ToRadians(AngleFromHorizon))));
Vector2 flattenedVect = new Vector2(vect.X, vect.Y);

float adjustedRotation = (float)(getAngle(flattenedVect.X, flattenedVect.Y));

rotationスクリーンアングルはどこにあり、adjustedRotation今ではそのスクリーンアングルはスプライトプレーンに見えます。なぜXではなくYを回転させる必要があるのか​​はわかりませんが、おそらく3Dと関係があるのでしょうか。

それで、私は追加の情報を手に入れましたが、これを使用してより適切なフレームを選択するにはどうすればよいですか?おそらく、ビュープレーンからスプライトプレーンに回転してから投影するのではなく、逆方向にそれを行う必要があります。調整された赤い線が付いた私のスプライトがありますが、私が本当にやりたいのは、線ではなくモデルを調整することです:http : //cell.stat-life.com/images/stories/AsteroidOutpost/Spaceship64RedLineCorrected.png

9月9日編集

ほら!修正されました!私はそれを修正するためにしたことを説明します:

私はeBusinessのアドバイスに従い、世界座標系(または拡張...?)によって「押しつぶされました」。これは本質的には解決策1です。ただし、スクリーン座標系に対して世界座標系を回転させる必要があるという印象を受けました。違います!Upはまだ+ yで、Rightは+ xです。WorldToScreenメソッドとScreenToWorldメソッドを変更して、ワールド座標とスクリーン座標を適切に変換しました。これらの方法は最適ではないかもしれませんが、変更しなければならなかった私のコードベースの唯一の2つの方法があります。

public Vector2 ScreenToWorld(float x, float y)
{
    float deltaX = x - (size.Width / 2f);
    float deltaY = y - (size.Height / 2f);

    deltaX = deltaX * scaleFactor / (float)Math.Sqrt(3);
    deltaY = deltaY * scaleFactor;

    return new Vector2(focusWorldPoint.X + deltaX, focusWorldPoint.Y + deltaY);
}

public Vector2 WorldToScreen(float x, float y)
{
    float deltaX = x - focusWorldPoint.X;
    float deltaY = y - focusWorldPoint.Y;

    deltaX = deltaX / scaleFactor * (float)Math.Sqrt(3);
    deltaY = deltaY / scaleFactor;

    return new Vector2(size.Width / 2f + deltaX, size.Height / 2f + deltaY);
}

それでした!これらの2つの方法を変更すると、他のすべてに影響しました。私が見ていたこと、オブジェクトが描かれた場所、クリックした場所、すべて。私の宇宙船は今、それが撃っているターゲットを直接見て、すべてが適切に落ちています。正射投影法を試して、すべてがより「リアル」に見えるかどうかを確認します。


おめでとう。何かプレイできるものを手に入れたら、私を突くのを忘れないでください。
aaaaaaaaaaaa

@eBusiness約束どおり:cell.stat-life.com/images/stories/AsteroidOutpost/… および cell.stat-life.com/images/stories/AsteroidOutpost/AOOhNoes.pngその塔を見ているように見えることに注意してください。:Dありがとう!
ジョンマクドナルド

@eBusiness、ビデオyoutube.com/watch?v=Q8pR9KDBsCoあなたが尋ねたので、ダウンロードするためのリンクもあります。
ジョンマクドナルド

回答:


4

等角投影法を選択したら、X軸とY軸の間のスケールを修正する必要があります。特定の距離がスクリーンのY軸で1に投影される場合、同じ距離がスクリーンのX軸でsqrt(3)に投影されます。したがって、画面上にフラットなものを描くと、次のようになります。

draw(object.image, object.x*sqrt(3), object.y)

非回答ノート:

  • なぜあなたはスプライトシートやものを台無しにしますか?必要に応じて、3Dレンダラーにアイソメトリックを実行させることができます。
  • スプライトシートを使用しているのに、なぜアンチエイリアス処理されないのですか?
  • 空間での等尺性、私はゲームの使用を見たことがないと思います。視覚的に参照するための明確な等尺性の基盤がないことを考えれば、どれほどうまく機能するかわかりません。

1
私は思う...これはすべてを修正することができます。簡単に修正でき、シートはそのままにしておくことができます。私はこれをできるだけ早く試して、それがどうなるかを知らせます。あなたのメモに答えるには:1)私は2Dを使用しています。それは、私が慣れ親しんでいるものであり、3Dモデルからシートを生成しているからです。2)エッジはシャープにする必要がありますが、ハードエッジの内側ではアルファチャネルを使用してアンチエイリアスを行うことができます。3)3次元(多く)をシミュレートする予定はありません。主に、トップダウンではなく、物事の側面を見ることができる2Dグラフィックスが必要です。
ジョンマクドナルド

5

回転したスプライトはどのように生成されますか?これらは回転3Dモデルのスクリーンショットですか?3Dモデリングツールのカメラのパースペクティブにより、対面角度がオフになる可能性があります。等角投影法は、3D空間の正確な表現ではありません。「カメラ」から遠く離れたものは小さくなりません。

簡単な修正が必要な場合。解決策2を正しく行うのは難しいかもしれません。解決策3は、角度が一致しないフレームを、角度によりよく適合するフレームと交換するだけで簡単に思えます。

レーザーはまだ時々オフになります。スムーズな回転をしているのではなく、特定の程度の範囲で異なるフレームを表示しているため。

編集:

問題は、生成されたスクリーンショットが等角投影ではなく、通常の3Dカメラビューであることです。

ここに画像の説明を入力してください

アイソメビューは3D空間をシミュレートしますが、正確な表現ではありません。カメラからの距離が長くなると、物事は小さくなります。これは、等角投影では行われません。スプライトにinいスケーリングアーティファクトが発生するためです。

宇宙船のスクリーンショットは、3Dカメラの視点で作成されます。それがレーザー射撃がオフになっている理由です。「等尺性」と「パースペクティブ」の赤い線を比較します。

あなたのスプライト発生器は、使用すべきMatrix.CreateOrthographic()の代わりにMatrix.CreatePerspective()を射影行列ため。


スプライトは、私が開発している3Dから2Dのツールを使用して生成されるため、問題はそのツールにある可能性が非常に高くなります。このツールは3Dモデルを読み込むだけで、Spaceship64.png(上記)を達成するために、モデルを(360/64)= 5.625度回転し、それをフレームとして保存し、すべて同じになるまで同じ量だけ回転します。 64フレーム。モデルのレンダリングに使用されるコードはこちらです:code.google.com/p/sprite-maker/source/browse/trunk/XNAWindow/… 回転は他のクラスで行われます。また、ソリューション2とソリューション3は互いに逆であると考えていました。
ジョンマクドナルド

私の答えを編集しました。上記を参照。
スティーブン

私は両方を行う必要があると思います:スプライトジェネレーターに正投影を使用させ、@ eBusinessが言っているように私の世界座標系を変更します。昨夜、正投影を試してみましたが、私の船の見た目は確かに変わりましたが、それだけでは私の経験している角度の問題は解決しませんでした。
ジョンマクドナルド

あなたの編集を見ました。修正されたスプライトは、船の中心が赤い線の中心から外れているように見えます。たぶん、赤い線の開始点よりも1ピクセルまたは2ピクセル高く船を描くだけで十分でしょう。船があなたの世界の起源から離れる間に目に見えるエラーは変わりますか?X軸をスケーリングすると、これが修正される場合があります。
スティーブン

1

ここにあるのは、単に等尺性の見た目だと思います。視覚的に言えば、90度と100度の間よりも0度と10度の間の差が大きいようです。。。しかし、アイソメトリックは本質的に1つの軸を圧縮するためです。その外観が必要ない場合は、等尺性は必要ありません。

そうは言っても、あなたが抱えている視覚的な問題は、視覚的な基準点がないことのおかげだと思います。あなたの脳はあなたがそれをトップダウンで見ていると仮定しています-ちょっと、それはスペースです、なぜあなたはそうではないでしょう-そしてそれを標準的なトップダウンビューとして解釈しています。テストのために、浮動ホログラフィック参照ポイントをいくつか追加してみてください。たとえば、45度の角度のグリッド、または宇宙船の周囲の一連の範囲円。宇宙船がレンダリングされているのと同じ等角平面上にあるかのように、それらが適切に歪んでいることを確認してください。私はあなたの脳が遠近法を理解し、それが突然正しく見えることを望んでいます。

次に、それをユーザーに伝える方法を考えます。。。それはまったく別の問題です。


この方法(問題の方法#1)を使用して錯覚を完成させるために、ワールド軸を回転させる必要もありませんか?
ジョンマクドナルド

私が知る限り、船はすでに正しくレンダリングされています-側面図は、アイソメトリックが「正しい」ように見えるべき角度で表示しています。「世界軸を回転させる」とはどういう意味かわからないと思います。
-ZorbaTHut

「世界の軸を回転させる」とは、カメラを基準にして世界を45度回転させ、「北」を真上にするのではなく、画面の右上または左上に対角線を描くようにすることです。画面の上部に向かって。
ジョンマクドナルド


それは役立つかもしれませんが、宇宙ではとにかくそれほど大きな違いを生むべきではありません。世界にグリッドを重ねて表示しない限り、それは問題ではありません。
ZorbaTHut
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.