How to make a scroll map in XNA (2D)?

I have a map containing many objects in an area of ​​size 5000 * 5000. my screen size is 800 * 600.

how can I scroll my map, I don’t want to move all my objects left and right, I want the “camera” to move, but, unfortunately, I did not find a way to move it.

thanks

+4
source share
2 answers

I think you are looking for the transformMatrix parameter for SpriteBatch.Begin ( this overload ).

You say you don’t want the objects to move, but you want the camera to move. But at the lowest level, both in 2D and in 3D rendering, there is no concept of a “camera”. Rendering always happens in one region - and you should use transformations to place your tops / sprites in this region.

If you need a camera effect, you must realize it by moving the whole world in the opposite direction.

Of course, you do not actually store the moved data. You just apply the offset when visualizing the data. Emartel's answer is that you do this for each sprite. However, using a matrix is ​​cleaner because you don’t need to duplicate the code for each Draw - you just let the GPU do it.

To end with an example: say you want your camera to be set to (100, 200). To do this, go to Matrix.CreateTranslation(-100, -200, 0) in SpriteBatch.Begin .

(Doing the deviations from yourself, according to emartel answers, is probably a waste of time if your world is really huge. See this answer for an explanation of performance considerations.)

+7
source

Viewport

You start by creating a camera viewport. In the case of a 2D game, this can be as simple as defining the bottom left position where you want to start rendering and expand it using the screen resolution, in your case 800x600 .

 Rectangle viewportRect = new Rectangle(viewportX, viewportY, screenWidth, screenHeight); 

Here is an example of what your camera would look like if it were offset 300,700 (the picture is very approximate, it just gives you a better idea)

Viewport

Visibility check

Now you want to find every sprite that intersects red square , which can be understood as your Viewport . This can be done with something similar (this is unverified code, just an example of how it might look)

 List<GameObject> objectsToBeRendered = new List<GameObject>(); foreach(GameObject obj in allGameObjects) { Rectangle objectBounds = new Rectangle(obj.X, obj.Y, obj.Width, obj.Height); if(viewportRect.IntersectsWith(objectBounds)) { objectsToBeRendered.Add(obj); } } 

Here, as it would be graphically, the green sprites are those added to objectsToBeRendered . Adding objects to a separate list is easy if you want to sort them from Back to Front before rendering them!

Visible

Rendering

Now that we have discovered which objects intersect, we need to find out where the screen ends.

 spriteBatch.Begin(); foreach(GameObject obj in objectsToBeRendered) { Vector2 pos = new Vector2(obj.X - viewportX, obj.Y - viewportY); spriteBatch.Draw(obj.GetTexture(), pos, Color.White); } spriteBatch.End(); 

As you can see, we display the X and Y positions of the viewport to bring the world position of the object into Screen Coordinates in the viewport. This means that a small square, which can be 400, 800 in World Coordinates , will be displayed at 100, 100 on the screen, if you have a viewport.

Edit:

While I agree to changing the “correct answer”, keep in mind that what I posted here is still very useful when you decide which animations to process, which AIs to update, etc., allowing you to do the camera and the GPU only this work prevents you from knowing what objects were actually on the screen!

+7
source

All Articles