Create scrolling background with tilemap

Hi,

I want create a scrolling background from a tilemap. What would be the best way of doing it:

  • creating only the required section with size of the screen or
  • creating the whole map as an Image and get the right position with g.drawImage(…)

I think the second option is the easiest to code, but I’m afraid to cause performance problems. :-\

U should do the first option. As u get into code, u ll see that it isnt difficult.

Second option would consume too much memory…

I could post some code if u need it.

As these things go, a clean way to do this is to first design your interface of a TileMap and implement it the easiest way and later, if needed, you can always create a more optimized implementation and simply switch to your new implementation without otherwise changing your game code:

TileMap bgScroll = new SimpleTileMap();
can be then changed to
TileMap bgScroll = new OptimizedTileMap();
were TileMap is an abstract interface, and the SimpleTileMap and OptimizedTileMap are the implementations.

However, I agree with SluX that you’ll probably find that your option 1) is not that difficult, but if you design things properly, optimizations like this can be integrated in your code cleanly.
I would just create an array of tile references, and only draw the visible tiles.

This code looks a bit different… well, you can use it as some kind of pseudo code reference :wink:

import com.kaioa.y3.game.*;
import com.kaioa.y3.ext.*;
import java.util.*;


public class TestModuleBsh extends Game {
	int MAP_W=10; //usually bigger + dynamic
	int MAP_H=10; //usually bigger + dynamic
	int SCREEN_W=256; //usually bigger
	int SCREEN_H=256; //usually bigger
	int TILE_W=32;
	int TILE_H=32;
	int TILES_X=SCREEN_W/TILE_W;
	int TILES_Y=SCREEN_H/TILE_H;
	int MAX_WX=MAP_W*TILE_W-TILES_X*TILE_W-1;
	int MAX_WY=MAP_H*TILE_H-TILES_Y*TILE_H-1;

	int [][]map=new int[MAP_W][MAP_H];
	int wx=0;
	int wy=0;

	TGATextureManager gfx=TGATextureManager.getInstance();
	Texture []set;

	public void init() {
		set=gfx.addSlicesWH("set2.tga",32,32);
		Random gen=new Random();
		for(int x=0;x<MAP_W;x++)
			for(int y=0;y<MAP_H;y++)
				map[x][y]=gen.nextInt(6); //usually this wouldnt be random
	}

	public void tick() {
		wx+=Controls.simpleX()*4;
		wy+=Controls.simpleY()*4;
	}

	public void render() {
		GTool.clear(); //dont clear the screen if you overdraw everything anyways
		GTool.setColor(1f,1f,1f);

		//clap world coords
		if(wx<0)wx=0;
		if(wy<0)wy=0;
		if(wx>MAX_WX)wx=MAX_WX;
		if(wy>MAX_WY)wy=MAX_WY;

		//find the array offsets
		int ox=wx/32;
		int oy=wy/32;

		for(int x=0;x<TILES_X+1;x++)
			for(int y=0;y<TILES_Y+1;y++)
				GTool.drawImage(set[map[ox+x][oy+y]],x*TILE_W-wx%TILE_W,y*TILE_H-wy%TILE_H);

		GTool.setColor(0f,0f,1f);
		GTool.va.print("wx:"+wx+" wy:"+wy,20,20);
	}
}

Thats basically everything there is to it. You load the tiles, you load the 2d map array, then you draw those tiles which are on the screen. Eg if the resolution is 640x480 and the tiles are 32x32 then 20x15 tiles are fitting on the screen… if you scroll a bit right/down you’ll have a gap there. Therefore you would need to draw 21x16 instead to be sure that the whole screen is filled.

O.k… I thought that it would be better to do it the first way.

Thank you all. ;D

This also dependson what the rest of your render logic is,

if this is a true tile-based game then you will need to re-render sub-sections at least on every frame as your characters move in order for the ordering to work out. (You could theoretically spend a lot of logic clipping the characters v. other tiles but I doubt you’ld end up ahead of the game v. an efficient VRAM based pure tile engine.)