Simon Surename
Simon Surename

Reputation: 23

XNA 2D Camera - How to make it properly follow sprite

Hello there wonderful people!

Let's just cut to the chase. I've made a tile engine that draws my map relative to my camera (The tiles that are drawn are the ones visible in the camera window), and i've made a sprite (my character) that is centered within the camera. Whenever i move the camera my character follows accordingly, the only problem is when i reach the borders of my map. Programing the way i did has constrained my camera from moving beyond the borders, resulting in limiting my character from moving closer to the borders(since it's always centered within the camera).

How do i free my camera from the restraints of my evil map?

p.s. I've made a picture to illustrate what i want to do. And here is the guide i followed.

Here's my code where i draw the tiles and place the camera:

protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.Black);

        spriteBatch.Begin();

        Vector2 firstSquare = new Vector2(Camera.Location.X / Tile.TileWidth, Camera.Location.Y / Tile.TileHeight);
        int firstX = (int)firstSquare.X;
        int firstY = (int)firstSquare.Y;

        Vector2 squareOffset = new Vector2(Camera.Location.X % Tile.TileWidth, Camera.Location.Y % Tile.TileHeight);
        int offsetX = (int)squareOffset.X;
        int offsetY = (int)squareOffset.Y;

        for (int y = 0; y < squaresDown; y++)
        {
            for (int x = 0; x < squaresAcross; x++)
            {
                foreach (int tileID in myMap.Rows[y + firstY].Columns[x + firstX].BaseTiles)
                {
                    spriteBatch.Draw(
                        Tile.TileSetTexture,
                        new Rectangle(
                            (x * Tile.TileWidth) - offsetX, (y * Tile.TileHeight) - offsetY,
                            Tile.TileWidth, Tile.TileHeight),
                        Tile.GetSourceRectangle(tileID),
                        Color.White);
                }
            }
        }

        spriteBatch.End();
        // TODO: Add your drawing code here

        base.Draw(gameTime);
    }

And here is the code where i move the camera:

protected override void Update(GameTime gameTime)
    {
        // Allows the game to exit
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();

        IsMouseVisible = true;
        KeyboardState ks = Keyboard.GetState();
        if (ks.IsKeyDown(Keys.A))
        {
            Camera.Location.X = MathHelper.Clamp(Camera.Location.X - 2, 0, (myMap.MapWidth - squaresAcross) * Tile.TileWidth);
        }

        if (ks.IsKeyDown(Keys.D))
        {
            Camera.Location.X = MathHelper.Clamp(Camera.Location.X + 2, 0, (myMap.MapWidth - squaresAcross) * Tile.TileWidth);
        }

        if (ks.IsKeyDown(Keys.W))
        {
            Camera.Location.Y = MathHelper.Clamp(Camera.Location.Y - 2, 0, (myMap.MapHeight - squaresDown) * Tile.TileHeight);
        }

        if (ks.IsKeyDown(Keys.S))
        {
            Camera.Location.Y = MathHelper.Clamp(Camera.Location.Y + 2, 0, (myMap.MapHeight - squaresDown) * Tile.TileHeight);
        }
        // TODO: Add your update logic here

        base.Update(gameTime);
    }

Upvotes: 0

Views: 1150

Answers (1)

jgallant
jgallant

Reputation: 11273

Instead of making your player follow the camera, you need to make your camera follow the player. That way you can set restrictions on the camera, instead of attempting to hack the camera system to make the character do things.

On every update, you would have something like:

Player.Update(gametime);
Camera.Update(Player.Position);

Upvotes: 1

Related Questions