今よりもかなり多くのものが必要です。
まず、すでにお気づきのように、位置を直接設定するのは簡単です。ソリューション?
速度
を直接設定する代わりに、次のようPosition
に設定しますvelocity
。
Vector2 velocity = Vector2.Zero;
また、何らかの移動速度を定義します。
const float speed = 10.0f;
キープレスで代わりに変更velocity
します。
if (aCurrentKeyboardState.IsKeyDown(Keys.Right) == true && mPreviousKeyboardState != aCurrentKeyboardState)
{
velocity.X = new Vector2(speed, 0.0f);
}
else if (aCurrentKeyboardState.IsKeyDown(Keys.Left) == true && mPreviousKeyboardState != aCurrentKeyboardState)
{
velocity.X = new Vector2(-speed, 0.0f);
}
else if (aCurrentKeyboardState.IsKeyDown(Keys.Up) == true && mPreviousKeyboardState != aCurrentKeyboardState)
{
velocity.Y = new Vector2(0.0f, -speed);
}
else if (aCurrentKeyboardState.IsKeyDown(Keys.Down) == true && mPreviousKeyboardState != aCurrentKeyboardState)
{
velocity.Y = new Vector2(0.0f, speed);
}
次に、すべてのフレームを更新Position
して、速度がアクティブに機能するようにします。
//assuming you're using GameTime gameTime for the timing values
Position += velocity * (float)gameTime.ElapsedGameTime.TotalSeconds;
(固定のゲーム時間を使用している場合、実際には経過時間を乗算する必要はありませんが、1 秒あたりの単位で測定することを好むので、通常はそこに入れます。)
タイルモーション
これは、「滑らかな」モーションとはまったく別の問題です。基本的な速度が得られたので、タイルを 1 つ動かしたら停止するだけです。これを解決するには多くの方法がありますが、ここでは簡単な方法をスケッチします。
方向/軸とは関係なく、キャラクターがモーションでどれだけ遠くまで移動したかを表す「距離」変数を保持します。
float distance = 0.0f;
変更に合わせてインクリメントしPosition
、次の直後に「十分に移動した」テストを実行します。
//assuming you're using GameTime gameTime for the timing values
Position += velocity * (float)gameTime.ElapsedGameTime.TotalSeconds;
//increment total distance indepedent of direction/axis
distance += Math.Abs(velocity.X) + Math.Abs(velocity.Y);
//test if we've travelled far enough
if (distance >= tileSize)
{
//reset distance
distance = 0.0f;
//stop
velocity = Vector2.Zero;
//TODO: SNAP TO TILE
}
これは良い出発点ですが、さらに 2 つのことを行う必要があります。
移動が完了したら、最も近いタイル (移動したばかりのタイル) にスナップします。そうしないと、キャラクターがタイル グリッドから非常にゆっくりと「外れ」始めます。これを行うには、キャラクターの中心座標(座標 + タイル サイズ / 2) を取得してタイル座標に変換し、それを「実際の」座標フロートに戻すことをお勧めします。これには他にも多くの方法があります。
動作中はキープレスが無効になっていることを確認してください。そうしないと、進行中のモーションを中断することで、キャラクターがタイル グリッドから自由に移動できます。ブール値を保持するinMotion
か、より簡潔に言えば、そうvelocity
でないかどうかをテストVector2.Zero
できます (そうすれば、動いていることがわかります)。
途中でモーションの中断を許可し、グリッドとの同期を維持したい場合は、もう少し高度になりますが、これで良いスタートが切れるはずです。