Scrolling the map and getting tile location

Aug 4, 2011 at 9:33 PM

I am probably wasting my breath here, but it really would be nice if you documented this thing better.  A couple of issues:

1.  The little tutorial you have on Codeplex makes use of the following overload of the Draw method of the Map class:

map.Draw(mapDisplayDevice, viewport);

I have found that if I want to be able to scroll I need to use the following overload:

map.Draw(mapDisplayDevice, displayOffset, viewport),

where I treat displayOffset as the location of the map viewport.  Using this overload means I have to offset my character's x and y when I draw him:

Vector2 correctedPosition = new Vector2(character.X + displayOffset.X, character.Y + displayOffset.Y);

spriteBatch.Draw(character.sprite, correctedPosition, Color.White);

2.  The intellisense in VisualStudio says that there are two overloads for the Tiles method of the Layer class.  One takes a Location as a parameter, and the other takes an x and a y.  So far as I can tell, the overload with the x and y parameters interprets them as tile coordinates and not as x-y coordinates.  Using this overload earned me many errors of the flavor "Tile indices out of bounds."

The overload that takes a location does what I want, in that it returns the tile that occupies those x-y coordinates on the map.

Coordinator
Aug 5, 2011 at 12:32 PM
Edited Aug 6, 2011 at 8:22 AM

Jordan,

You can think of the viewport as the representation of a 2D camera. The centre of the viewport is the focal point of the camera, while the width and height are the extents visible to the camera. To get the map to scroll, say, from right to left (as in a horizontal shooter), you actually need to move the viewport from left to right, that is, by increasing the viewport's X property. 

The displayOffset serves another purpose: it controls where the contents of the viewport are to be rendered on the screen. Normally, you would use a displayOffset set to (0, 0), or alternatively use the two-parameter Draw method (the first one in your post). The displayOffset is useful when you want to inlay the level view in a border, or if you are implementing some form of split-screen play.

To place the player correctly, you need to compute the absolute screen position of the player sprite (SX, SY) as SX = PX + DX - VX and SY = PY +DY - VY where (PX, PY) are the player's position in map coordinates, (VX, VY) are the viewport's top left corner, and (DX, DY) are the display offsets. 

I hope that helps,

Colin

P.S. I agree with you, some documentation is needed. In the meantime, I suggest you have a look at the demo project in the code by going through this link: http://tide.codeplex.com/SourceControl/BrowseLatest

Aug 5, 2011 at 5:50 PM

Alright, so I found the real problem.  Any layers that are not larger, in pixels, than the game window will not scroll.  I noticed that your DemoGame.cs file contains code to limit viewport movement, but my project did not have that code and still the viewport was constrained to the boundaries of the map.  Is there code in the Viewport (aka Rectangle) class that won't let the viewport pass beyond the boundaries of the map?  The reason my map would not scroll is because all of its layers were smaller than my game window.  I realize that scrolling is only necessary for maps that are larger than the game window, but I was not yet at the point of making actual maps.  I was just experimenting to get a feel for the tool.

Another issue:  If I want to update a map file I cannot just save it in the map editor and rebuild my project.  I have to SaveAs before I can rebuild and see the changes ingame.

Thanks for the speedy response!  Best Regards,

Jordan

 

Apr 4, 2012 at 2:46 PM
Edited Apr 4, 2012 at 2:48 PM

Knowing this is an 8 month old discussion, I'm only replying to comment on jordanwilcken's unsolved issue: I couldn't find the answer by searching and after solving the problem, feel it'd be worth posting here for anyone who comes across this discussion while trying to solve the problem as well.

In the Layer.ConvertMapToLayerLocation method, modifying a few lines will fix the "I can't get the viewport to scroll because the viewport is bigger than the map" problem. Below is an example of the old, commented out code, that causes the viewport to not scroll, and the new code which bypasses the issue.

 

            /*
            int layerLocationX = mapWidthDifference > 0
                ? mapDisplayLocation.X * layerWidthDifference / mapWidthDifference
                : 0;
            */

            int layerLocationX = mapDisplayLocation.X * layerWidthDifference / mapWidthDifference;

            /*
            int layerLocationY = mapHeightDifference > 0
                ? mapDisplayLocation.Y * layerHeightDifference / mapHeightDifference
                : 0;
            */

            int layerLocationY = mapDisplayLocation.Y * layerHeightDifference / mapHeightDifference;