2
\$\begingroup\$

I'm working on my first XNA 2D game (overhead view), and I'm pondering how to manage the difference in position on screen vs. the position of a sprite on a global map.

The solution I'm currently thinking about is having the map keep track of everything on it, the player, other sprites, etc. The sprites will know where they are on the map, and when .Draw() is called on the map it will delegate drawing items to the items themselves, but pass a position to draw on the screen. For instance, something akin to the following:

class Map {
    Vector2D ScreenCenter;
    List<DrawableItem> Content;

    void Draw(GameTime gameTime) {
        foreach (var i in Content) { 
            i.Draw(spriteBatch, i.Position - ScreenCenter);
        }
    }
}

class DrawableItem {
    Vector2D Position;

    void Draw(SpriteBatch spriteBatch, Vector2D screenPosition) {
        // Draw ourselves at screenPosition
    }
}

Is there some better way of doing this? Or am I on the right sort of track here?

\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

I think the best way to do this is to use a Camera class which has conversion methods that allow you to convert from "World Coordinates" (which are the pixel/tile coordinates of your map) to "Screen Coordinates" (which are the pixels shown on screen). The Camera has a Location property (Vector2) which is in World Coordinates and allows the Camera object to figure out what to draw within the Screen Coordinates.

This has the added benefit of allowing you to move the Camera independently from sprites/characters on the screen.

There's a really good tutorial series on xnaresources.com that goes through designing a tile engine that uses a camera class. I highly recommend it.

I've also gone on with the Camera class to make it utilize an interface called ICameraTarget (which just defines an X and Y coordinate for the target, in World Coordinates). I implement the interface on my player characters so that it will lock on a player and update itself automatically to their location during the game loop.

Edit
To elaborate a bit more: in my game, the map is in tiles, so every player, item, etc has a tile coordinate and an offset (how far off the tile they are in pixels, used for when they are moving across tiles). The Camera class has a function that I use in my .Draw() that is called WorldTileToScreen(int tileX, int tileY). This returns a Point() or Vector2() (I use point, but it's up to you). This takes the player's (/item's/etc.) X/Y values (in tiles) and multiplies them by the width and height of the map's tiles in pixels (respectively). It then subtracts the Camera's Location property (which is an X/Y value) from that to find the object's Screen Coordinates. Then, I add the object's offset to those values to that to get the position to draw the object on screen.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .