最初に、描画の問題が何であるかを正確に知っており、それを解決する方法についてさまざまなアイデアを持っています。等尺性の「錯視」が維持されるように、どのフレームを描画するかを調整する方法を見つけ出します。
私は宇宙で行われる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赤い線は常に船とまったく同じ方向に向ける必要がありますが、ご覧のとおり、投影の問題が問題を引き起こしています。この問題を十分に説明していることを願っています。
編集: 赤い線はスクリーン平面上で回転しますが、宇宙船は「船平面」上で回転します。したがって、船の角度と描かれたときのスクリーン角度の大きな違いがあります。 編集を終了
この船が一方向に外れたターゲットにレーザービームを発射しているとき、それがまっすぐ前方に発射されるべきであるとき、それはかなり奇妙に見えます。
だから...私が思いついた解決策は次のとおりです:
- 等角図を偽造するのをやめる、大きくなる、または家に帰る。すでに私の世界を回転させます。(PS:これで問題が解決しますよね?)
- スプライトシートを(なんとかして)変更して、モデルが表示される「スクリーンアングル」を表すフレームを作成します。したがって、45度の画像を要求すると、実際には画面上で45度の方向を向いているように見えます。
- スプライトレンダリングシステムを変更して、スプライトシートとは異なるフレームを(なんとかして)取得します。「通常の」フレームを取得すると面白いように見えることを知っています。そのため、45度のフレームを取得する代わりに... 33度のフレーム(推測のみ)を取得して、ユーザーに正しく見えるようにします。
- 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つの方法を変更すると、他のすべてに影響しました。私が見ていたこと、オブジェクトが描かれた場所、クリックした場所、すべて。私の宇宙船は今、それが撃っているターゲットを直接見て、すべてが適切に落ちています。正射投影法を試して、すべてがより「リアル」に見えるかどうかを確認します。