サイドスクロールプラットフォームの2Dゲームを開発するには、移動するカメラクラスを実装する必要があります。マップ全体を移動する代わりにクラスを使用する理由は、一度に多くのオブジェクトが遅れを引き起こします。私はそれを起こさせることはできません。XNA 4.0画面上のカメラとオブジェクトの処理
カメラを操作するための素晴らしいアルゴリズムがあります。プレーヤーが画面の幅よりも大きく動き、カメラがプレーヤーの方向に移動して画面の中央に戻ってくると、数日間働いていますしかし、このアルゴリズムを動作させることは成功していません。
// Main
public class Camera
{
protected float _zoom;
protected Matrix _transform;
protected Matrix _inverseTransform;
//The zoom scalar (1.0f = 100% zoom level)
public float Zoom
{
get { return _zoom; }
set { _zoom = value; }
}
// Camera View Matrix Property
public Matrix Transform
{
get { return _transform; }
set { _transform = value; }
}
// Inverse of the view matrix,
// can be used to get
// objects screen coordinates
// from its object coordinates
public Matrix InverseTransform
{
get { return _inverseTransform; }
}
public Vector2 Pos;
// Constructor
public Camera()
{
_zoom = 2.4f;
Pos = new Vector2(0, 0);
}
// Update
public void Update(GameTime gameTime)
{
//Clamp zoom value
_zoom = MathHelper.Clamp(_zoom, 0.0f, 10.0f);
//Create view matrix
_transform = Matrix.CreateScale(new Vector3(_zoom, _zoom, 1)) *
Matrix.CreateTranslation(Pos.X, Pos.Y, 0);
//Update inverse matrix
_inverseTransform = Matrix.Invert(_transform);
}
}
これは、それが主な目的私は、画面を処理するために作られたカメラクラスださは、画面を再生する、(、私は私の画面を変更するたびにズームアウトして、より正確には、タイトル画面を画面のサイズを変更することですゲームオーバーなど) このように、カメラを移動することは非常に簡単です。
if (keyState.IsKeyDown(Keys.D))
Cam.Pos.X -= 20;
if (keyState.IsKeyDown(Keys.A))
Cam.Pos.X += 20;
if (keyState.IsKeyDown(Keys.S))
Cam.Pos.Y -= 20;
if (keyState.IsKeyDown(Keys.W))
Cam.Pos.Y += 20;
およびofc。描画方法はカメラを適用します。
spriteBatch.Begin(SpriteSortMode.Texture, BlendState.AlphaBlend, null, null, null, null, Cam.Transform);
ここでは私が止めるときに来るので、私がやりたいことは2次元の2部屋のようにしています。部屋で私は通常、物を置く場所を意味する。この "Vector2(74、63)"のように、スクリーンに固執して動かないアイテムを描画し、アルゴリズムを動作させる画面の境界を作る場所を作りたい、魔女になる常に画面上に表示され、追加として、画面「部屋」の境界線の1つが地図「部屋」の特定の座標に達しているかどうかをチェックします。 その理由は、プレイヤーが壁に到達したときにカメラを地図の外に移動させたくないからだと思います。さもなければ、プレイヤーは次の地図の一部をすでに見ているでしょう。 両方のマップを隣り合わせて描画する理由は、やはりローディング時間を短縮して、プレーヤが次のマップの再生を待つ必要がないためです。
さてさて、私は、私はので、私は、余分な情報を追加しますとプレイヤークラスで始まりますが予想よりも多くのトラブルに遭遇しました:
// Main
public class Player
{
public Texture2D AureliusTexture;
public Vector2 position;
public Vector2 velocity;
public Vector2 PosForTheCam; // Variable that holds value for moving the camera
protected Vector2 dimensions;
protected CollisionPath attachedPath;
const float GRAVITY = 18.0f;
const float WALK_VELOCITY = 120f;
const float JUMP_VELOCITY = -425.0f;
// Constructor
public Player()
{
dimensions = new Vector2(23, 46);
position = new Vector2(50, 770);
}
public void Update(float deltaSeconds, List<CollisionPath> collisionPaths)
{
#region Input handling
KeyboardState keyState = Keyboard.GetState();
if (keyState.IsKeyDown(Keys.Left))
{
velocity.X = -WALK_VELOCITY;
}
else if (keyState.IsKeyDown(Keys.Right))
{
velocity.X = WALK_VELOCITY;
}
else
{
velocity.X = 0;
}
if (attachedPath != null && keyState.IsKeyDown(Keys.Space))
{
velocity.Y = JUMP_VELOCITY;
attachedPath = null;
}
velocity.Y += GRAVITY;
#endregion
#region Region of handling the camera based on Player
PosForTheCam.X = velocity.X;
#endregion
#region Collision checking
if (velocity.Y >= 0)
{
if (attachedPath != null)
{
position.X += velocity.X * deltaSeconds;
position.Y = attachedPath.InterpolateY(position.X) - dimensions.Y/2;
velocity.Y = 0;
if (position.X < attachedPath.MinimumX || position.X > attachedPath.MaximumX)
{
attachedPath = null;
}
}
else
{
Vector2 footPosition = position + new Vector2(0, dimensions.Y/2);
Vector2 expectedFootPosition = footPosition + velocity * deltaSeconds;
CollisionPath landablePath = null;
float landablePosition = float.MaxValue;
foreach (CollisionPath path in collisionPaths)
{
if (expectedFootPosition.X >= path.MinimumX && expectedFootPosition.X <= path.MaximumX)
{
float pathOldY = path.InterpolateY(footPosition.X);
float pathNewY = path.InterpolateY(expectedFootPosition.X);
if (footPosition.Y <= pathOldY && expectedFootPosition.Y >= pathNewY && pathNewY < landablePosition)
{
landablePath = path;
landablePosition = pathNewY;
}
}
}
if (landablePath != null)
{
velocity.Y = 0;
footPosition.Y = landablePosition;
attachedPath = landablePath;
position.X += velocity.X * deltaSeconds;
position.Y = footPosition.Y - dimensions.Y/2;
}
else
{
position = position + velocity * deltaSeconds;
}
}
}
else
{
position += velocity * deltaSeconds;
attachedPath = null;
}
#endregion
}
}
だから私はそれを明確に私は私の友人に尋ねたと述べています重力と坂道を扱いたいので私はそれをUnityのように同じように動作させるために、ほとんどの作業を行います。そして、彼はそれをどうやって行うのか知っていました。 メインクラスのカメラを扱うUpdateメソッドを追加します。
MM.Update(gameTime); // Map Managher update function for map handling
Cam.Update(gameTime); // Camera update
Cam.Zoom = 2.4f; // Sets the zoom level for the title screen
// Takes the start position for camera in map and then turns off the update
// so the camera position can be changed. Else it would just keep an infinite
// loop and we couldn't change the camera.
if (StartInNewRoom)
{
Cam.Pos = MM.CameraPosition; // Applys the camera position value from the map manager class
StartInNewRoom = false;
}
私はあなたの方法を使用し、結果は多くの場合、それ自体で、そのカメラが移動してしまったか、それは全く動かないように私は、カメラを処理する方法がわからないと思います。
を次のカメラにあなたのPos.X/Y
の後ろにこれを適用する最初の問題としてではなく、それに慣れていることを見たことができます。 (私はカメラのチュートリアルを使用しました)しかし、質問の一部は未回答のままです。どのようにしてこのカメラを主人公に従わせ、キャラクターが部屋の終わりに達すると動かさないようにすることができます。 1つの画面の高さの部屋の文字で。 –
追加するのを忘れました。はい、カメラの位置はデフォルトで左上隅にあります。 –
プレーヤークラスはありますか? "camera.position"の代わりに、プレイヤーをマトリックスに配置します。私は私の答えを編集しました。他の部分については、衝突検出を読む。 – SKSK