当前位置: 动力学知识库 > 问答 > 编程问答 >

c# - Updating the Y position aswell as the X position of the 2D camera

问题描述:

I'm trying to make a 2D camera that follows my player around both vertically and horizontally. The camera is only following my player horizontally atm. Ive been told to update the Y part aswell as the X part in my ScrollCamera() method, but I couldnt figure out how to do it (ended up making a big mess).

Heres the code:

private void ScrollCamera(Viewport viewport)

{

#if ZUNE

const float ViewMargin = 0.45f;

#else

const float ViewMargin = 0.5f;

#endif

// Calculate the edges of the screen.

float marginWidth = viewport.Width * ViewMargin;

float marginLeft = cameraPosition + marginWidth;

float marginRight = cameraPosition + viewport.Width - marginWidth;

// Calculate how far to scroll when the player is near the edges of the screen.

float cameraMovement = 0.0f;

if (Player.Position.X < marginLeft)

cameraMovement = Player.Position.X - marginLeft;

else if (Player.Position.X > marginRight)

cameraMovement = Player.Position.X - marginRight;

// Update the camera position, but prevent scrolling off the ends of the level.

float maxCameraPositionWidth = Tile.Width * Width - viewport.Width;

cameraPosition = MathHelper.Clamp(cameraPosition + cameraMovement, 0.0f, maxCameraPositionWidth);

}

This is the draw method in my level class:

public void Draw(GameTime gameTime, SpriteBatch spriteBatch)

{

spriteBatch.Begin();

for (int i = 0; i <= EntityLayer; ++i)

layers[i].Draw(spriteBatch, cameraPosition);

spriteBatch.End();

ScrollCamera(spriteBatch.GraphicsDevice.Viewport);

Matrix cameraTransform = Matrix.CreateTranslation(-cameraPosition, 0.0f, 0.0f);

spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default,

RasterizerState.CullCounterClockwise, null, cameraTransform);

DrawTiles(spriteBatch);

Player.Draw(gameTime, spriteBatch);

foreach (Enemy enemy in enemies)

enemy.Draw(gameTime, spriteBatch);

spriteBatch.End();

spriteBatch.Begin();

for (int i = EntityLayer + 1; i < layers.Length; ++i)

layers[i].Draw(spriteBatch, cameraPosition);

spriteBatch.End();

}

I'm pretty new to Xna and C# and Im doing this just for fun, but it would be great if someone could tell me how to do it :)

I have tried:

private void ScrollCamera(Viewport viewport)

{

#if ZUNE

const float ViewMargin = 0.45f;

#else

const float ViewMargin = 0.5f;

const float ViewHeight = 0.3f;

#endif

// Calculate the edges of the screen.

float marginHeight = viewport.Height * ViewHeight;

float marginTop = cameraPosition + marginHeight;

float marginBottom = cameraPosition + marginHeight;

float marginWidth = viewport.Width * ViewMargin;

float marginLeft = cameraPosition + marginWidth;

float marginRight = cameraPosition + viewport.Width - marginWidth;

// Calculate how far to scroll when the player is near the edges of the screen.

float cameraMovement = 0.0f;

if (Player.Position.X < marginLeft)

cameraMovement = Player.Position.X - marginLeft;

else if (Player.Position.X > marginRight)

cameraMovement = Player.Position.X - marginRight;

if (Player.Position.Y < marginTop)

cameraMovement = Player.Position.Y - marginTop;

else if (Player.Position.Y > marginBottom)

cameraMovement = Player.Position.X - marginBottom;

// Update the camera position, but prevent scrolling off the ends of the level.

float maxCameraPositionWidth = Tile.Width * Width - viewport.Width;

cameraPosition = MathHelper.Clamp(cameraPosition + cameraMovement, 0.0f, maxCameraPositionWidth);

}

Which was not right at all.

网友答案:

From the code you provided I conclude 'cameraPosition' is a float with which you only keep track of the X position. I would recommend using a Vector2 for this. This is technically two floats in one; one for the X position and one for Y. If you do this, you will have to repeat your calculation for the Y value. If you prefer not to use a Vector2, you could make a second variable for the Y position instead.

I am unable to see what you do with the cameraPosition, so I cannot help you with that part for Y.

Edit The draw function you have made is not right, because you have only one variable for the camera position. You will need a variable for the X position, and a second one for the Y position. As I stated above, the typical way to do this in XNA, is via the Vector2 structure. If you are not familiar with structures(or classes), I recommend reading up about it as soon as possible, because they are very important in object oriented programming. A link to the microsoft Vector2 documentation: http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.vector2.aspx

What you would basically do is take the calculation you had at first.

float cameraMovement = 0.0f;
if (Player.Position.X < marginLeft)
    cameraMovement = Player.Position.X - marginLeft;
else if (Player.Position.X > marginRight)
    cameraMovement = Player.Position.X - marginRight;

// Update the camera position, but prevent scrolling off the ends of the level.
float maxCameraPositionWidth = Tile.Width * Width - viewport.Width;
cameraPosition = MathHelper.Clamp(cameraPosition + cameraMovement, 0.0f, maxCameraPositionWidth);

This is the calculation for the X position of your camera. Your code using Vector2 would be:

// Declare a Vector2 cameraPosition where you are now declaring a float cameraPosition right now.

Vector2 cameraMovement = new Vector2(0,0);
if (Player.Position.X < marginLeft)
    cameraMovement.X = Player.Position.X - marginLeft;
else if (Player.Position.X > marginRight)
    cameraMovement.X = Player.Position.X - marginRight;

float maxCameraPositionWidth = Tile.Width * Width - viewport.Width;
cameraPosition.X = MathHelper.Clamp(cameraPosition.X + cameraMovement.X, 0.0f, maxCameraPositionWidth);

You will have to do similar calculations for cameraMovement.Y and cameraPosition.Y.

When you have these, the only thing you will have to change in your draw function is the Y translation. Currently you have:

Matrix cameraTransform = Matrix.CreateTranslation(-cameraPosition, 0.0f, 0.0f);

As you see, you are only translating in the X axis. After adding the Y axis it looks like this:

Matrix cameraTransform = Matrix.CreateTranslation(-cameraPosition.X, -cameraPosition.Y, 0.0f);

I hope you figure it out now. Good luck!

分享给朋友:
您可能感兴趣的文章:
随机阅读: