0

トップダウン ビューの RPG ゲームに取り組んでいます。キャラクターが歩いている背景に画像をロードしたいのですが、これまでのところ、「スクロール」するように背景を正しく再描画する方法がわかりません。私が見つけた例のほとんどは自動スクロールです。

背景画像が境界に達するまで、カメラをキャラクターの中心に置いておきたいと思います。その後、別の位置に画像を再描画することなく、キャラクターが移動します。

4

2 に答える 2

2

あなたの質問は少し不明確ですが、私はそれの要点を理解していると思います。あなたの要件を見てみましょう。

  1. 2 次元平面を直接見下ろしているオーバーヘッド カメラがあります。これは、カメラが見ている平面上の点に対応する単純な {x, y} 座標ペアとして表すことができます。
  2. カメラは、オブジェクト (おそらくプレイヤー) の動きを追跡できますが、より一般的にはゲーム ワールド内のあらゆるものを追跡できます。
  3. カメラは、ゲーム ワールドの有限境界内に留まる必要があります。

これは実装するのに十分簡単です。大まかに言えば、Update()メソッド内のどこかで、これらの各要件を満たすための手順を実行する必要があります。

if (cameraTarget != null)
{
    camera.Position = cameraTarget.Position;
    ClampCameraToWorldBounds();
}

言い換えれば、ターゲット オブジェクトがある場合、位置をその位置にロックします。ただし、範囲外にならないように注意してください。

ClampCameraToBounds()実装も簡単です。世界の範囲をピクセル単位で表すプロパティworldを含むオブジェクト があると仮定します。Bounds

private void ClampCameraToWorldBounds()
{
    var screenWidth = graphicsDevice.PresentationParameters.BackBufferWidth;
    var screenHeight = graphicsDevice.PresentationParameters.BackBufferHeight;

    var minimumX = (screenWidth / 2);
    var minimumY = (screnHeight / 2);

    var maximumX = world.Bounds.Width - (screenWidth / 2);
    var maximumY = world.Bounds.Height - (screenHeight / 2);
    var maximumPos = new Vector2(maximumX, maximumY);

    camera.Position = Vector2.Clamp(camera.Position, minimumPos, maximumPos);
}

これにより、カメラが世界の端に画面の半分よりも近づくことはありません。なぜ半分の画面?カメラの {x, y} をカメラが見ているポイントとして定義したため、常に画面の中央に配置する必要があります。

これにより、質問で指定した動作のカメラが得られるはずです。ここからは、カメラ オブジェクトによって指定された {x, y} 座標を基準にして背景が描画されるように、地形レンダラーを実装するだけです。

ゲーム ワールド座標でのオブジェクトの位置を指定すると、その位置をカメラ空間に変換できます。

var worldPosition = new Vector2(x, y);
var cameraSpace = camera.Position - world.Postion;

そして、カメラ スペースからスクリーン スペースへ:

var screenSpaceX = (screenWidth / 2) - cameraSpace.X;
var screenSpaceY = (screenHeight / 2) - cameraSpace.Y;

その後、オブジェクトの画面空間座標を使用してレンダリングできます。

于 2012-08-28T14:46:59.393 に答える
0

シンプルな Vector2 で位置を表し、任意のエンティティに向かって移動できます。 public Vector2 cameraPosition;

レベルをロードするとき、カメラの位置をプレーヤー (または、あるべきオブジェクト) に設定する必要があります。

以下のコードに示すように、マトリックスとその他のものが必要になります。コメントで説明されています。このようにすると、描画するすべてのものに cameraPosition を追加する必要がなくなります。

    //This will move our camera
    ScrollCamera(spriteBatch.GraphicsDevice.Viewport);

    //We now must get the center of the screen
    Vector2 Origin = new Vector2(spriteBatch.GraphicsDevice.Viewport.Width / 2.0f, spriteBatch.GraphicsDevice.Viewport.Height / 2.0f);

    //Now the matrix, It will hold the position, and Rotation/Zoom for advanced features
    Matrix cameraTransform = Matrix.CreateTranslation(new Vector3(-cameraPosition, 0.0f)) *
       Matrix.CreateTranslation(new Vector3(-Origin, 0.0f)) *
       Matrix.CreateRotationZ(rot) * //Add Rotation
       Matrix.CreateScale(zoom, zoom, 1) * //Add Zoom
       Matrix.CreateTranslation(new Vector3(Origin, 0.0f)); //Add Origin

      //Now we can start to draw with our camera, using the Matrix overload
    spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default,
                             RasterizerState.CullCounterClockwise, null, cameraTransform);


    DrawTiles(spriteBatch); //Or whatever method you have for drawing tiles

    spriteBatch.End(); //End the camera spritebatch
    // After this you can make another spritebatch without a camera to draw UI and things that will not move

何か派手なものを追加したい場合は、ズームと回転を追加しました。変数を置き換えるだけです。

これで始められるはずです。

ただし、カメラが境界内にあることを確認し、追従させたいと思うでしょう。

スムーズなスクロールを追加する方法を紹介しますが、単純なスクロールが必要な場合は、このサンプルを参照してください。

   private void ScrollCamera(Viewport viewport)
        {
            //Add to the camera positon, So we can see the origin
            cameraPosition.X = cameraPosition.X + (viewport.Width / 2);
            cameraPosition.Y = cameraPosition.Y + (viewport.Height / 2);

            //Smoothly move the camera towards the player
            cameraPosition.X = MathHelper.Lerp(cameraPosition.X , Player.Position.X, 0.1f);
            cameraPosition.Y = MathHelper.Lerp(cameraPosition.Y, Player.Position.Y, 0.1f);
            //Undo the origin because it will be calculated with the Matrix (I know this isnt the best way but its what I had real quick)
            cameraPosition.X = cameraPosition.X -( viewport.Width / 2);
            cameraPosition.Y = cameraPosition.Y - (viewport.Height / 2);

            //Shake the camera, Use the mouse to scroll or anything like that, add it here (Ex, Earthquakes)

            //Round it, So it dosent try to draw in between 2 pixels
            cameraPosition.Y= (float)Math.Round(cameraPosition.Y);
            cameraPosition.X = (float)Math.Round(cameraPosition.X);


            //Clamp it off, So it stops scrolling near the edges
            cameraPosition.X = MathHelper.Clamp(cameraPosition.X, 1f, Width * Tile.Width);
            cameraPosition.Y = MathHelper.Clamp(cameraPosition.Y, 1f, Height * Tile.Height);

        }

お役に立てれば!

于 2012-08-28T21:02:03.470 に答える