Presence of background or Scrolling camera according to charcter position

I am working on an RPG game that has a top-down view. I want to load the image into the background image to which the character is going, but so far I have not figured out how to correctly redraw the background so that it โ€œscrollsโ€. Most of the examples I find are automatic scrolling.

I want the camera to remain centered on the symbol until the background image reaches its borders, then the symbol will move without re-drawing the image in a different position.

0
source share
2 answers

Your question is a little unclear, but I think I understood the essence of it. Let's look at your requirements.

  • You have an upper camera that looks straight down at a two-dimensional plane. We can imagine this as a simple coordinate pair {x, y}, corresponding to a point on the plane on which the camera is looking.
  • The camera can track the movement of an object, perhaps a player, but in general, something in the game world.
  • The camera must remain within the final boundary of the game world.

It is simple enough to implement. Broadly speaking, somewhere inside your Update() method, you need to follow the steps to fulfill each of these requirements:

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

In other words: if we have a target, block our position to its position; but make sure that we do not go beyond.

ClampCameraToBounds() also easy to implement. Assuming you have some kind of object, world , which contains the Bounds property, which represents the scale of the world in pixels:

 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); } 

This ensures that the camera will never be closer than half the screen to the edge of the world. Why half the screen? Since we defined the camera {x, y} as the point that the camera is looking at, which means that it should always be centered on the screen.

This should give you a camera with the behavior you indicated in your question. Hence, itโ€™s just a matter of implementing your terrain renderer so that your background is drawn relative to the {x, y} coordinate given by the camera object.

Given the position of the object in the coordinates of the game world, we can translate this position into camera space:

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

And then from camera space to screen space:

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

Then you can use the screen space coordinates of the object to display it.

+2
source

Your position can represent a position in simple Vector2 and move it to any object. public Vector2 cameraPosition;

When you load your level, you will need to set the camera position on your player (or the object in which it should be)

You will need a matrix and some other things, as can be seen from the code below. This is explained in the comments. Performing this method will not allow you to add the CameraPosition function to everything that you draw.

  //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 

I added scale and rotation if you want to add something fantastic. Just replace the variables.

This should make you start with it.

However, you will want to make sure that the camera is within the boundaries and do so.

Show how to add smooth scrolling. However, if you want a simple scroll, look at this sample .

  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); } 

Hope this helps!

0
source

All Articles