Problems when scrolling the map

Oct 17, 2011 at 8:51 AM

First of all I'd like to say how fantastic this program is, has saved me a lot of time and it works great :)

I've followed the tutorial and have now gone to implement the map into my own game, however an issue has arisen that I can't quite fix.

Whenever I scroll the map, there seems to be some kind of parallax movement with my player sprite, and the map as if the map is a background.

I'm scrolling the map in all directions as its a top down game I am making. I'd just like to know how i can go about centering the viewport to my player position, and scrolling the map around accordingly.

 

Any help is greatly appreciated.

Coordinator
Oct 17, 2011 at 9:17 AM

You should set your Viewport's width and height to match your screen resolution. Let's call these VW and VH.

To centre the vewport around the player's coordinates (let's call them PX and PY), you need to set the Viewport's tp-left position (let's call them VX, VY) as

VX = PX - VW / 2

VY  = PY - VH / 2

 

In your game loop you basically take care of the player's movement by updating his position (PX, PY). Then, you update the viewport using the formula above.

 

Note that this makes the 'camera' rigid, that is, it always keeps the player strictly in the centre. To make the camera follow the player with a slight delay (which looks more natural), you could calculate target positions using the same formulas above (that is, TX = PX - VW / 2 and TY = PY - VH / 2). Then you move VX and VY slightly towards the target TX, TY. For example as follows:

DeltaX = TX - VX

DeltaY = TY - VY

VX += DeltaX * K * DeltaT

VY += DeltaY * K * DeltaT

where DeltaT is the time in seconds since the last game loop call (from gameTime.ElapsedTime.TotalSeconds) and K is some constant to control the agility of your camera. Values of K = 4 usually work well. If you make K smaller the camera might scroll to slowly and if you make K much larger it will almost feel like the rigid camera with the original formulas at the top.

 

Hope that helps.

P.S. Remember also that when rendering your character or other entity sprites on the map, you need to subtract the viewport position VX, VY from the entities' positions in map pixels to get the correct screen coordinates. See this discussion for more info.

Oct 17, 2011 at 10:54 AM

Hello again, thank you very much for the swift reply, I've done what you advised, but I'm still coming across problems.

I set the viewport values as you said to above, as to make the camera rigid to the position of the player's sprite, but I'm still getting the same parallax movement problem. I'm using the viewport that is used in the tutorial thats passed to the map.Draw method, I've also got my own Camera class and tried using that alongside but I'm still not getting the desired effect.

I've uploaded my project files to http://www.mediafire.com/?145tacop5cz4rqq, I'd appreciate it if you could take a look if you have any free time.

 

Oct 19, 2011 at 3:24 AM

You're confusing the player's "map" coordinates with its "screen" coordinates. If you want the camera to be centered on the player, then you should always draw the player at the center of the screen.

Simply change your Draw() method at Player.cs to the following:

    public void Draw(SpriteBatch spriteBatch)
    {
        Vector2 screenCenter = new Vector2(Config.SCREEN_WIDTH/2, Config.SCREEN_HEIGHT/2);
        spriteBatch.Draw(this.TextureBase, screenCenter , null, Color.White, this.Rotation, this.Origin, 1.0f, SpriteEffects.None, 0.0f);
        spriteBatch.Draw(this.TextureBody, screenCenter, null, Color.White, this.bodyRotation, this.Origin, 1.0f, SpriteEffects.None, 0.0f);
    }

Coordinator
Oct 19, 2011 at 7:33 AM

That works too, as long as you intend to keep the player centred on screen all the time. You would then have to see how to handle the player when he/she reaches the edges of the map, such as you simply let the maps's edges enter the screen (leaving an unrendered area beyond), or if you set up your map such that the player is blocked from reaching the edge by walls or other obstacles on the map.