5

私はゲーム小惑星を作ろうとしています。私が今抱えている問題は、上矢印キーを押すと、「船」が10ピクセル上に移動することです。そして、左矢印キーを押すと、「船」が左に5度回転します。これは、左または右に曲がったときに発生する問題です。そして、上に移動してみてください。回転方向には動きません。回転した「船」をY方向に10度動かすだけです。

私が考えているのは、方向と呼ばれる変数を持つことです。この変数を360度の円と考えてください。私がやろうとしているのは、左矢印を押すたびに、方向から5を引くことです。これは、0から始まり、360から逆方向に進み、355に設定されます。次に、355を10で割ると、35.5になります。次に、10を35.5で割ると、.355になります。次に、10から.355を引きます(Yを上に移動します)。そしてそれを0から引きます(Xを左に移動します)。したがって、Yで9.645を上に移動し、Xで0.355を左に移動します。

私が抱えている問題は、私が持っている小惑星の「船」です。Graphics.FillPieは、開始角度と後退角度として使用するためにIntを必要としますが、ご覧のとおり、ダブルまたはフロートで作業する必要があります。私はこれを複雑にしすぎていると確信しており、100倍単純なものがあると確信しています。ブレゼンハムの線形アルゴリズムに沿って何かを考えています。誰かがもっと簡単なことや私の問題の修正を提案することで助けてくれるなら、それは大いにありがたいです。前もって感謝します。

4

5 に答える 5

14

ラジアンでの現在の向きに基づいて、船の船首方位ベクトルを計算する必要があるようです。例えば:

double xVector = Math.Sin(orientationInRadians);
double yVector = Math.Cos(orientationInRadians);

次に、左右の矢印を使用して、船の現在の向きを制御します。ベクトルを取得したら、船首方位ベクトルに沿った現在の位置から10単位離れた船の位置を計算できます。まず、ベクトルを単位(長さ1)のベクトルにスケーリングする必要があります。

double magnitude = sqrt(xVector*xVector + yVector*yVector);
double unitVectorX = xVector/magnitude;
double unitVectorY = yVector/magnitude;

これで、1単位の長さのベクトルができましたが、それでも船の現在の方向を指しています。次に、positionXとpositionYを現在の座標として船を移動します。

double distanceToTravel = 10;
double newPositionX = positionX + unitVectorX*distanceToTravel;
double newPositionY = positionY + unitVectorY*distanceToTravel;

intのみを許可するシステムでレンダリングすることになった場合でも、船の位置と向きをダブルまたはフロートで追跡することをお勧めします。レンダリングエンジンの精度を使用して現在の位置と方向を保存しないでください。保存すると、移動したり回転したりするときに奇妙なジャンプや一時停止が見られるようになります。また、上記を使用すると、distanceToTravelを非一定にすることができます(キーを押してから一定の距離を移動する代わりに、キーを押している間に加速することを想像してください)。

于 2010-09-03T19:38:14.300 に答える
2

難しく考えすぎだよ。;>マトリックス変換を使用して、船を回転および移動します。船が「北西」を指し、ユーザーがUPキーを押すと、船のY軸で船の変換行列が10単位調整されます。回転と平行移動のマトリックスを適用して、船の座標系を画面の座標系に変換します。操作の順序は重要です。回転する前に平行移動を適用すると、船は、船の原点を中心に回転してから新しい「前方」方向に平行移動するのではなく、中心点を中心にスイングします。

描画に同じ行列変換を使用できるため、ローカル座標系に対して同じ固定方向(機首が正のY軸を「上」に向ける)で船を描画できます。画像の回転は、行列変換によって処理されます。

于 2010-09-03T19:37:33.110 に答える
1

私はあなたの楽しみを奪いたくありませんが、いつでも誰か他の人のコードをダウンロードしてそれを見て、自分でそれを行う方法を理解することができます。ここで1つの実装を取得できます:http ://www.c-sharpcorner.com/UploadFile/dannaboneheart/Asteroids11292005064500AM/Asteroids.aspx

ここに回答:http://www.codeproject.com/KB/game/hucsharpasteroids.aspx

于 2010-09-03T19:31:48.327 に答える
1

floatを内部で使用し、そのように使用する必要がある場合はintに変換することに問題はありません。

double angle = ...;
int angleAsInt = (int)Math.Round(angle);

速度と加速度のX成分とY成分を決定するために、のsinような三角関数を使用することを検討することをお勧めします。cos

于 2010-09-03T19:36:04.113 に答える
1

まだ言及していないことの1つは、Asteroids(R)ブランドのアーケードマシンとそれから派生したビデオゲームでは、プレイヤーの船に慣性があるということです。したがって、船の速度を追跡する必要があります。各フレームでは、次のようなことを行う必要があります。

if (thrusting)
{
  XVelocity += (XVelocity - Math.Cos(Heading)*MAX_SPEED) * (1/INERTIA_CONSTANT);
  YVelocity += (YVelocity - Math.Sin(Heading)*MAX_SPEED) * (1/INERTIA_CONSTANT);
}
else
{
  XVelocity -= XVelocity * (1/FRICTION_CONSTANT);
  YVelocity -= YVelocity * (1/FRICTION_CONSTANT);
}

XPosition += XVelocity; // Do twice--once before and once after speed adjust
YPosition += YVelocity;

一部のゲームでは、速度にコサイン/サインの定数倍を追加するだけであることに注意してください。これを行うと、プレイヤーが自分の船をある方向に向けて継続的に突進し始めると、各フレームで船が移動する距離が途方もない限界に達する可能性があるという不幸な結果になります。示されているコードは、船の速度が漸近的に最大に近づくにつれて、加速度を減少させます。

于 2013-03-14T18:21:51.407 に答える