我工作的一个RPG游戏,有自上而下的视图。 我想要的图片加载到这是什么字符走在后台,但到目前为止,我还没有想出如何正确有背景重绘,这样它的“滚动”。 大部分时间我找到的例子是自动滚动。
我希望相机在您之前的背景图像达到其边界的性质仍然为中心,那么该角色会没有像在其他位置重画移动。
我工作的一个RPG游戏,有自上而下的视图。 我想要的图片加载到这是什么字符走在后台,但到目前为止,我还没有想出如何正确有背景重绘,这样它的“滚动”。 大部分时间我找到的例子是自动滚动。
我希望相机在您之前的背景图像达到其边界的性质仍然为中心,那么该角色会没有像在其他位置重画移动。
你的问题是有点不清楚,但我觉得我得到它的要点。 让我们来看看你的要求。
这是很简单的实现。 从广义上讲,你的某处里面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;
然后,您可以使用一个对象的屏幕空间坐标上呈现。
你可以表示一个简单的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);
}
希望这可以帮助!