Scrolling a tilemap based off array

Started by
0 comments, last by menyo 12 years, 2 months ago
I'm pretty much stuck at this point and looking for some direction as I can't figure out which direction to go.

tilesArray = [
0,0,0,0,0,0,0,1,2,9,6,0,0,7,0,0,1,0,
0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,
0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,9,0,
0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,9,0,
0,9,9,9,9,9,9,0,7,2,0,0,0,0,0,1,2,0,
0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,
0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,
0,9,0,7,2,9,9,9,9,9,9,9,9,9,9,9,9,0,
0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,
0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
]


Tiles: 0 is a stone wall, 9 is the floor, 7 is a door, 1 and 2 are walls.

Now I'm trying to find information for panning/scrolling/moving the generated background when the player moves. If I press UP, I want to shift the tiles 1 row down, draw the missing row at the top and drop the extra row at the bottom. If I press RIGHT, I need everything to shift 1 column left.

Questions:
1) Do you make 1 enormous array of the world, then slice sections of it into a "viewport" array and render the viewport array to the screen each frame?

2) Do you have each room saved as it's own array, then somehow load the individual rooms/arrays as you approach their area???

What is the term for this type of topic?? Tile generation? I'm trying to search for examples of "scrollable" tilebased maps, not much luck.


Any direction is much appreciated, tutorial, documentation, examples, whatever language, just want to see common practices. How do roguelike's generate the layouts for the dungeons??
Advertisement
You slice it to what the viewport can see. I make a separate camera class to move the map, if the camera offsets the map offsets. A handy option to this is that you can link a character or event to the camera.

You could opt for an enormous array or just stidge smaller arrays together. The enormous array will take somme more time to load but with the camera class and only showing necessary tiles this should not give you much more performance over one another.

Try googling for something like "2D camera matrix"

Here is my camera class for C#/XNA, use anything you like but make sure you know whats going on.


public class Camera
{
float zoom;
float rotation;
Matrix transform;
Vector2 position;
int velocity = 20;
public float Zoom
{
get { return zoom; }
set { zoom = value; if (zoom < 0.05f) zoom = 0.05f; } // Negative zoom will flip image
}
public float Rotation
{
get { return rotation; }
set { rotation = value; }
}
// Auxiliary function to move the camera
public void Move(Vector2 amount)
{
position += amount;
}
// Get set position
public Vector2 Position
{
get { return position; }
set { position = value; }
}
public Camera()
{
zoom = 1.0f;
rotation = 0f;
Position = new Vector2(0, 0);
}
public void Update()
{
//move camera used for debugging.
if (Input.IsKeyHold(Microsoft.Xna.Framework.Input.Keys.Down))
{
position.Y += velocity;
}
else if (Input.IsKeyHold(Microsoft.Xna.Framework.Input.Keys.Up))
{
position.Y -= velocity;
}
if (Input.IsKeyHold(Microsoft.Xna.Framework.Input.Keys.Right))
{
position.X += velocity;
}
else if (Input.IsKeyHold(Microsoft.Xna.Framework.Input.Keys.Left))
{
position.X -= velocity;
}
if (Input.IsKeyPressed(Microsoft.Xna.Framework.Input.Keys.LeftShift))
{
velocity = 120;
}
if (Input.IsKeyReleased(Microsoft.Xna.Framework.Input.Keys.LeftShift))
{
velocity = 20;
}
}
public Matrix CreateOrthogonal(GraphicsDevice graphicsDevice)
{
Matrix Orthogonal = Matrix.CreateOrthographic(graphicsDevice.Viewport.Width, graphicsDevice.Viewport.Height, 1, graphicsDevice.Viewport.Height);
return Orthogonal;
}
public Matrix get_transformations(GraphicsDevice graphicsdevice)
{
transform = Matrix.CreateTranslation(new Vector3(-position.X, -position.Y, 0)) *
//Matrix.CreateRotationX(MathHelper.ToRadians(30)) *
//Matrix.CreateRotationY(MathHelper.ToRadians(30)) *
Matrix.CreateRotationZ(MathHelper.ToRadians(rotation)) *
Matrix.CreateScale(new Vector3(zoom, zoom, 0)) *
Matrix.CreateTranslation(new Vector3(graphicsdevice.Viewport.Width * 0.5f, graphicsdevice.Viewport.Height * 0.5f, 0));
return transform;
}


In my draw method i do this:
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, null, null, null, cam.get_transformations(device));

//these are the boundaries to draw, it takes in the amount the camera has zoomed.
int top = (int)((cam.Position.Y / TileHeight) - ((device.Viewport.Height / 2) / TileHeight + 1) / cam.Zoom);
int bottom = (int)((cam.Position.Y / TileHeight) + ((device.Viewport.Height / 2) / TileHeight + 2) / cam.Zoom);
int left = (int)((cam.Position.X / TileWidth) - ((device.Viewport.Width / 2) / TileWidth + 1) / cam.Zoom);
int right = (int)((cam.Position.X / TileWidth) + ((device.Viewport.Width / 2) / TileWidth + 2) / cam.Zoom);

//draw floor

//Here i use the bounderies to only go over the necesary tiles and draw them.
for (int y = (int)top; y < (int)bottom; y++)
{
for (int x = (int)left; x < (int)right; x++)
{
if (y >= 0 && y < MapDrawer.MapHeight && x >= 0 && x < MapDrawer.MapWidth && map[x,y] != null)
{
map[x, y].Draw(spriteBatch);
}
}
}

This topic is closed to new replies.

Advertisement