TileMap Array and only drawing whats on screen?

BlitzMax Forums/BlitzMax Beginners Area/TileMap Array and only drawing whats on screen?

How do I only draw what's on screen in a tilemap array to save me from drawing every tile in the array?

calculate the edge tiles (top left, bottom right) that are visible (you will need to have a function / method that calculates tile grid position from screen x,y anyway if you ever want to interact with it) and only draw between the indices of those.

Hmm.. you're going to need to know the current viewing coordinates, the size of each array tile and use some maths to work out which array[x][y] are visable on screen.

If pixel = index * tilesize, then index = pixel / tilesize.

So if each tile is 10x10
and the screen is at coordinates (100,100)
and is of size (200, 200)
(numbers for convenience)

Then the minimum index is 100/10 = 10 and the maximum index is 300/10 = 30. Same for both x and y in this case.

So draw array[10][10] to array[30][30].

I hope this helps.

Can someone post a code example using this bit of code here?

SuperStrict

Graphics 800, 600

Global grass:TImage = LoadImage("grass.png") 

Const MAPWIDTH:Int = 8000 / 32
Const MAPHEIGHT:Int = 8000 / 32

Global MapStartX:Int = 0
Global MapStartY:Int = 0

Global MapArray:Int[MAPWIDTH, MAPHEIGHT] 

For Local x:Int = 0 Until MAPWIDTH
	For Local y:Int = 0 Until MAPHEIGHT			
		MapArray[x, y] = Rand(0, 3) 
	Next
Next

While Not KeyHit(KEY_ESCAPE) 
	
	Cls
		DrawGrass() 
	
	Flip
	
Wend

Function DrawGrass() 
	For Local x:Int = 0 Until MAPWIDTH
		For Local y:Int = 0 Until MAPHEIGHT
			If MapArray[x, y] = 1
				DrawImage grass, MapStartX + x * 32, MapStartY + y * 32, 0
			EndIf
		Next
	Next
End Function


It would be better for me to see the actual code. I learn better that way. :)

Thanks. :)

I wouldn't code it like this but it's what you asked for
SuperStrict

Graphics 800, 600

Global grass:TImage = LoadImage("grass.png") 

Const MAPWIDTH:Int = 8000 / 32
Const MAPHEIGHT:Int = 8000 / 32

Global MapStartX:Int = 0
Global MapStartY:Int = 0

Global MapArray:Int[MAPWIDTH, MAPHEIGHT] 
Global mapx_offset:Int,mapy_offset:Int
For Local x:Int = 0 Until MAPWIDTH
	For Local y:Int = 0 Until MAPHEIGHT			
		MapArray[x, y] = Rand(0, 3) 
	Next
Next

While Not KeyHit(KEY_ESCAPE) 
	
	Cls
		DrawGrass() 
	
	Flip
	
Wend

Function DrawGrass() 
	Local endmapx:Int,endmapy:Int
	If mapx_offset+25 > mapheight 
		endmapx=mapwidth
	Else
		endmapx=mapx_offset+25
	EndIf
	If mapy_offset+18 > mapheight 
		endmapy=mapheight
	Else
		endmapy=mapy_offset+25
	EndIf

	For Local x:Int = mapx_offset To endmapx
		For Local y:Int = mapy_offset Until endmapy
			If MapArray[x, y] = 1
				DrawImage grass, MapStartX + x * 32, MapStartY + y * 32, 0
			EndIf
		Next
	Next
End Function


and I am sure there'll be bugs in it.
You should check Blitz2D Newbies: Basic Map File Loading & Scrolling which will still help for BlitzMax especially as you're not using OOP.
The Orientation tutorial here might help as well.

Thanks. :)

Hi, looking at the code it seems to work but how would I convert the following code to work like say in a tilemap game?

e.g The map scrolls and as it scrolls it only draws whats on screen at that time.

SuperStrict




Graphics 800, 600

Global MapWidth:Int = 2400 / 25
Global MapHeight:Int = 2400 / 25

Global MapStartX:Int = 0
Global MapSTartY:Int = 0

Global MapXOffset:Int, MapYOffset:Int

Global array:Int[MapWidth, MapHeight] 


For Local x:Int = 0 Until MapWidth
	For Local y:Int = 0 Until MapHeight
		array[x, y] = Rand(0, 5) 
	Next
Next



While Not KeyHit(KEY_ESCAPE) 
	Cls
		
		DrawMap() 
		MoveMap() 
		
	Flip
Wend

Function MoveMap() 
	If KeyDown(KEY_LEFT) 
		'MapStartX:-3
		MapXOffset:+1
	ElseIf KeyDown(KEY_RIGHT) 
		'MapStartX:+3
		MapXOffset:-1
	End If
	
	If KeyDown(KEY_UP) 
		'MapSTartY:+3
		MapYOffset:-1
	ElseIf KeyDown(KEY_DOWN) 
		'MapSTartY:-3
		MapYOffset:-1
	End If
	
End Function


Function DrawMap() 
	Local endmapx:Int, endmapy:Int
	If MapXOffset + 25 > MapWidth
		endmapx=mapwidth
	Else
		endmapx = MapXOffset + 25
	EndIf
	If MapYOffset + 18 > MapHeight
		endmapy=mapheight
	Else
		endmapy = mapyoffset + 25
	EndIf
	
	
	For Local x:Int = 0 Until endmapx
		For Local y:Int = 0 Until endmapy
			Select array[x, y] 
				Case 0
					SetColor 255, 255, 255
					DrawRect MapStartX + x * 25, MapSTartY + y * 25, 25, 25
				Case 1
					SetColor 0, 255, 255
					DrawRect MapStartX + x * 25, MapSTartY + y * 25, 25, 25
				Case 2
					SetColor 255, 0, 255
					DrawRect MapStartX + x * 25, MapSTartY + y * 25, 25, 25
				Case 3
					SetColor 255, 255, 0
					DrawRect MapStartX + x * 25, MapSTartY + y * 25, 25, 25
				Case 4
					SetColor 0, 0, 255
					DrawRect MapStartX + x * 25, MapSTartY + y * 25, 25, 25
			End Select
		Next
	Next
End Function


I have a MapStartX/Y which moves the map but am confused on howe to synchronise it with only drawing whats on screen.

Thanks for any help you guys can offer. :)

Hi Amon,
You might to read the Orientation tutorial here .
This might also help.
I would love to write some code showing map scrolling but have little enougn spare time of my own. It's also very difficult to change your own code as it is the 'I wouldn't start from there' syndrome.
How about checking some of the Tilemap Engine Bmax source that has been released. There might be some specific formatting commands but the movex/movey code will all be very similar.

<edit> P.S. ... and the best tutorials I have found for different tilemap moving is Krylar's Learn to Program 2D Games in BlitzBasic.

this is what I used for my tank game I hope it can help you
it generates a random map of specified size it may be used with many different graphics modes.
I made it flexible enough to be used with different size tiles but I have never tried it with tiles other than 32x32 so it might and it might not work with bigger or smaller tiles.
name this "maze.bmx"

' map constants

Const MINTILESA		:Int = 10
Const MINTILESD		:Int = 10

Const TILEWIDTH		:Int = 32
Const TILEHEIGHT	:Int = 32
'type of tiles

Const WALKABLE		:Int = 0
Const UNWALKABLE	:Int = 1

' type of grass

Const GRASSA		:Int = 0

' type of wall

Const WALLA			:Int = 1


'	map controls

Const MAP_LEFT		:Int = KEY_LEFT
Const MAP_RIGHT		:Int = KEY_RIGHT
Const MAP_UP		:Int = KEY_UP
Const MAP_DOWN		:Int = KEY_DOWN

Const SPEED_X		:Float = 6.0
Const SPEED_Y		:Float = 6.0

'Type of tiles
Type set
	Field a:Int 'Walkable unwalkable
	Field b:Int 'Type of tile (ex: wall,grass)
	Field c:Int 'type of graphic tile to display (ea: if wall which wall) 
End Type

Type TMap
	Field x					:Float,..
		  y					:Float
	Field speedx			:Float,..
		  speedy			:Float
	Field maxx				:Int,..
		  maxy				:Int
	Field bitx				:Int,..
		  bity				:Int
	Field tilesAcross		:Int,..
		  tilesDown			:Int
	Field width				:Int,..
		  height			:Int
	Field viewwidth			:Int,..
		  ViewHeight		:Int
	Field Offsetx			:Int,..
		  Offsety			:Int
	Field windowwidth		:Int,..
		  windowheight		:Int
	Field tilewidth			:Int,..
		  tileheight		:Int
	Field maze				:set[][]
	Field tilesinviewacross	:Int,..
		  tilesinviewdown	:Int
	Field screen_width		:Int,.. 
		  screen_height		:Int
	Field tile_width		:Int,.. 
		  tile_height		:Int
	Field wall				:TImage
	Field tile				:TImage[8]
	Field windowshiftx		:Int
	Field windowshifty		:Int

'sets up the maze including tiles and format	

	Function Create:TMap(mw:Int=MINTILESA,mh:Int=MINTILESD,tw:Int=TILEWIDTH,th:Int=TILEHEIGHT) 'mapwidth,mapheight,tilewidth,tileheight 
		If mw< MINTILESA Then mw=MINTILESA
		If mh< MINTILESD Then mh=MINTILESD
		Local map:Tmap = New TMap
		map.tile_width  = tw 
		map.tile_height = th
		map.screen_width%  = GraphicsWidth()
		map.screen_height% = GraphicsHeight()
		map.wall=LoadAnimImage("mazetiles.png",map.tile_width,map.tile_height,0,16,FILTEREDIMAGE|DYNAMICIMAGE)
		map.tile[0]	=LoadImage("grass.png", FILTEREDIMAGE|DYNAMICIMAGE)
		map.tilesAcross = mw
		map.tilesdown = mh
		map.windowwidth=GraphicsWidth() 
		map.windowheight=GraphicsHeight()
		map.tilewidth = tw
		map.tileheight = th
		map.width = mw * tw 'multiply map width by bitmap width for map width in pixels
		map.height= mh * th 'multiply map height by bitmap height for map height in pixels
		centermap(map)
		map.maxx = map.width-map.windowwidth
		map.maxy = map.height-map.windowheight
		map.speedx = SPEED_X
		map.speedy = SPEED_Y
		
	'create map array
		map.maze = map.maze[..mw]
		For Local h:Int = 0 To mw-1
			map.maze[h]=map.maze[h][..mh]
		Next
		For Local down:Int = 0 To mh-1
			For Local across:Int = 0 To mw-1 'places a wall edge around maze
				map.maze[across][down]= New set
				If across = 0 Or across = (mw-1) Or down=0 Or down = (mh-1)
					map.maze[across][down].a=1 ' unwalkable type
					map.maze[across][down].b=1 ' wall type
				Else
					map.maze[across][down].a=0 'grass
					map.maze[across][down].b=0 'walkable type
				EndIf
			Next
		Next

	'places wall tiles randomly on the maze excluding maze edges		
		Local rx:Int
		Local ry:Int 
		For Local n:Int = 1 To mw*mh Step 5 ' step determine s more or less the density 
	 		rx = Rand(1,mw-2)
			ry = Rand(1,mh-2)
			map.maze[rx][ry].a = 1
			map.maze[rx][ry].b = 1
		Next	
		CompileMaze(map.maze)
		Return map
	End Function

	'moves the maze when mouse is at edges of screen	
	Method controller(controlled:Int=False) 
		
		If Not controlled Then
			If width > Windowwidth Then
				If KeyDown(MAP_RIGHT) Or MouseX() >(screen_width -5)
					MoveMapX(speedx)  
				ElseIf KeyDown(MAP_LEFT) Or MouseX() < 5
					MoveMapX(-speedx)
				EndIf
            EndIf

			If height > windowheight Then
				If KeyDown(MAP_DOWN) Or MouseY() > (screen_height - 5)
					MoveMapY(speedy) 
				ElseIf KeyDown(MAP_UP) Or MouseY() < 5
					MoveMapY(-speedy) 
				EndIf
			EndIf
		EndIf
		
		bitx = x Mod tilewidth	' division remainder determins the number of pixels
		bity = y Mod tileheight	' to move per tile before moving to the next tile. 
		windowshiftx = offsetx-x		
		windowshifty = offsety-y
		
	EndMethod
	
	Method GetMapXY(x:Float Var,y:Float Var)
		x = Self.x+offsetx
		y = Self.y+offsety
	End Method
	
	Method setspeed(sx:Float=SPEED_X,sy:Float=SPEED_Y)
		speedx = sx
		speedy = sy
	End Method	
	
	Method MoveMapX(x:Float = SPEED_X)
		Self.x :+x
		If Self.x < 0 
			Self.x = 0 
		ElseIf Self.x > maxx
			Self.x = maxx
		EndIf
	End Method
	
	Method MoveMapY(y:Float = SPEED_Y)
		Self.y :+ y 
		If Self.y < 0 
			Self.y = 0
		ElseIf Self.y > maxy
			Self.y = maxy
		EndIf
	End Method

	Method SetMapOffset(x:Int,y:Int)
		If width < screen_width
			If x > viewwidth 
				offsetx = viewwidth
			ElseIf x <-viewwidth
				offsetx = -viewwidth
			Else
				offsetx = x
			EndIf
		EndIf
		If height < screen_height
			If y > viewheight
				offsety = viewheight
			ElseIf y < -viewheight
				 offsety = -viewheight
			Else
				offsety = y
			EndIf
		EndIf
	End Method
		
	Method display()
		Local ny:Int,nx:Int,tilex:Int,tiley:Int
		Local tx:Int = x/tile_width	
		Local ty:Int = y/tile_height
		Local tpx:Int,tpy:Int
		SetColor 255,255,255
		SetTransform(0,1,1)
		For ny = 0 To tilesinviewdown 		
			tiley = ny+ty   
			tpy = offsety+ny*tile_height-bity
			For nx = 0 To tilesinviewacross 
				tilex = nx+tx   
				If tilex < tilesacross And tiley < tilesdown
					Local shape:Int = maze[tilex][tiley].b
					Select shape
						Case 1
							DrawImage(wall,offsetx+nx*tile_width-bitx,tpy,maze[tilex][tiley].c)
						Case 0
							DrawImage(tile[maze[tilex][tiley].c],offsetx+nx*tile_width-bitx,tpy)
					End Select
				EndIf		
			Next
		Next
	End Method
End Type

'****************************************************************************
'this function  compiles tiles adjacent to each other To uniform patterns	*
'for use with "mazetiles.png"												*
'****************************************************************************
Function  CompileMaze(maze:set[][] Var)
	Local a:Int,c:Int

	For a:Int = 0 To maze.length-1 'tiles across
		Local d:Int
		For d:Int = 0 To maze[a].length-1 'tiles down
			If maze[a][d].b = 1
				If a >0
					If a < maze.length-1
						If d >0 
							If d< maze[a].length-1			
							
								maze[a][d].c = (maze[a-1][d].a Shl 3)..	' *		%1111 
											  |(maze[a][d+1].a Shl 2)..	'*+*  	  
											  |(maze[a+1][d].a Shl 1)..	' *
											  | maze[a][d-1].a														
							Else
								maze[a][d].c = (maze[a-1][d].a Shl 3)..	' *		%1011
											  |(maze[a+1][d].a Shl 1).. '*+*
											  |maze[a][d-1].a			'
							EndIf
						Else
							
							maze[a][d].c = (maze[a-1][d].a Shl 3)..		'		%1110
										|(maze[a][d+1].a Shl 2)..		'*+*
										|(maze[a+1][d].a Shl 1)			' *
						EndIf			
					Else
						If d > 0
							If d< maze[a].length-1
								maze[a][d].c = (maze[a-1][d].a Shl 3)..	' * 	%1101
											|(maze[a][d+1].a Shl 2)..	'*+
											|maze[a][d-1].a				' *
							Else
								maze[a][d].c = (maze[a-1][d].a Shl 3)..	'+* 	%1001
											|maze[a][d-1].a				'*
							EndIf
						Else
								maze[a][d].c = (maze[a-1][d].a Shl 3).. '*     	%1100 
											|(maze[a][d+1].a Shl 2).. 	'+*
											
						EndIf
					EndIf
				Else
					If d>0
						If d< maze[a].length-1
							maze[a][d].c = (maze[a][d+1].a Shl 2)..		' *		%0111
										|(maze[a+1][d].a Shl 1).. 		' +*
										|maze[a][d-1].a					' *
						Else
							maze[a][d].c = (maze[a+1][d].a Shl 1)..		' *		%0011
										|maze[a][d-1].a					' +*
						EndIf
					Else
						maze[a][d].c = (maze[a][d+1].a Shl 2)..			' +*   	%0110
									|(maze[a+1][d].a Shl 1)				' *
					EndIf
				EndIf
			EndIf
			If maze[a][d].c = 0
				c=(c+1) Mod 7
				If c 
					maze[a][d].b= 0
					maze[a][d].a= 0
				EndIf
				
			EndIf
		Next
	Next
	
	For a:Int = 0 To maze.length-1
		For Local d:Int = 0 To maze[a].length-1
			'If maze[a][d].a = 0 maze[a][d].c = 0
		Next
	Next
	
End Function 


'centermaze to screen
Function Centermap(map:tmap)
	'centers maze to screen horizontally if smalller than screen width
		If map.width < map.windowwidth  Then  
			map.viewwidth = map.width
			map.offsetx = (map.windowwidth-map.width) / 2 
		Else ' center map horizontally to view area (absolute)
			map.viewwidth = map.windowwidth 
			map.offsetx = 0
			map.x = (map.width - map.windowwidth)/2
		EndIf
		
	'centers maze to screen vertically if smaller than screen height		
		If map.height < map.windowheight Then  
			map.ViewHeight = map.height
			map.Offsety = (map.windowheight-map.height) / 2 
		Else 'center map vertically to view area (absolute)
			map.ViewHeight = map.windowheight
			map.Offsety = 0
			map.y = (map.height - map.windowheight)/2
		EndIf
   		map.tilesinviewacross = Ceil(Float(map.viewwidth)/map.tilewidth)
		map.tilesinviewdown = Ceil(Float(map.viewheight) /map.tileheight)


test with this:
SuperStrict

Include "maze.bmx"
Graphics 800,600,32

Local map:tmap = tmap.Create(30,40) 'mapsize  create(width ,height) in tiles all tiles are 32 X 32

Repeat
	Cls
	map.MouseMove()
	map.display()
	Flip()
Until KeyDown(key_escape)

use this images:
"grass.png"

and "mazetiles.png"

note: I have not tried to use the map with anything other than 32 x 32 tiles

I came up with my own noob way of doing it thanks to understanding what tonyg was doing.

Code here if anyone wants it.

SuperStrict

Graphics 800, 600

Global MapWidth:Int = 1600 / 25
Global MapHeight:Int = 1600 / 25

Global MapStartX:Int = 50
Global MapSTartY:Int = 50

Global MapXOffset:Int, MapYOffset:Int

Global array:Int[MapWidth, MapHeight] 

Print MapWidth

For Local x:Int = 0 Until MapWidth
	For Local y:Int = 0 Until MapHeight
		array[x, y] = Rand(0, 5) 
	Next
Next

Global startmapx:Int = 0, startmapy:Int = 0

While Not KeyHit(KEY_ESCAPE) 
	Cls
		
		DrawMap() 
		MoveMap() 
		
	Flip
Wend

Function MoveMap() 
	If KeyHit(KEY_LEFT) 
		If startmapx <= 0
			startmapx = 0
			MapStartX = 50
		Else
			MapXOffset:-1
			startmapx:-1
			MapStartX:+25
		EndIf
	ElseIf KeyHit(KEY_RIGHT) 
		If startmapx < MapWidth - 28
			MapXOffset:+1
			startmapx:+1
			MapStartX:-25
		Else
			startmapx = MapWidth - 28
		End If
	End If
	
	If KeyHit(KEY_UP) 
		If startmapy <= 0
			startmapy = 0
			MapSTartY = 50
		Else
			MapYOffset:-1
			startmapy:-1
			MapSTartY:+25
		EndIf
	ElseIf KeyHit(KEY_DOWN) 
		If startmapy < MapHeight - 20
			MapYOffset:+1
			startmapy:+1
			MapSTartY:-25
		Else
			startmapy = MapHeight - 20
		EndIf
	End If
	
End Function


Function DrawMap() 
	Local endmapx:Int, endmapy:Int
		
	If MapXOffset + 25 > MapWidth
		endmapx=mapwidth
	Else
		endmapx = MapXOffset + 28
	EndIf
	If MapYOffset + 20 > MapHeight
		endmapy=mapheight
	Else
		endmapy = MapYOffset + 20
	EndIf
	
	
	For Local x:Int = startmapx Until endmapx
		For Local y:Int = startmapy Until endmapy
			Select array[x, y] 
				Case 0
					SetColor 255, 255, 255
					DrawRect MapStartX + x * 25, MapSTartY + y * 25, 25, 25
				Case 1
					SetColor 0, 255, 255
					DrawRect MapStartX + x * 25, MapSTartY + y * 25, 25, 25
				Case 2
					SetColor 255, 0, 255
					DrawRect MapStartX + x * 25, MapSTartY + y * 25, 25, 25
				Case 3
					SetColor 255, 255, 0
					DrawRect MapStartX + x * 25, MapSTartY + y * 25, 25, 25
				Case 4
					SetColor 0, 0, 255
					DrawRect MapStartX + x * 25, MapSTartY + y * 25, 25, 25
			End Select
		Next
	Next
End Function


Here's something I knocked together in half an hour or so...

SuperStrict

Graphics 800,600,0

Global mapW:Int = 30
Global mapH:Int = 30

Local map:Int[] = MakeMap(mapW, mapH)
Global tileW:Int = 24
Global tileH:Int = 24
Global screenW:Int = 26
Global screenH:Int = 20

Global playerX:Int = 200
Global playerY:Int = 200

Global playerDisplayX:Int
Global playerDisplayY:Int

While Not KeyDown(key_escape)

	UpdatePlayer()

	Cls
	
	DrawMap(map)

	DrawPlayer()
	
	Flip


Wend

Function UpdatePlayer()

	If KeyDown(key_left)
		playerX:- 1
	End If
	If KeyDown(key_right)
		playerX:+ 1
	End If
	If KeyDown(key_up)
		playerY:- 1
	End If
	If KeyDown(key_down)
		playerY:+ 1
	End If
	
	' limit player bounds
	playerX = Max(0, Min(playerX, tileW * mapW))
	playerY = Max(0, Min(playerY, tileH * mapH))
	
	
	' calculate player display position
	Local screenCenterX:Int = (tileW * screenW) / 2
	Local screenCentery:Int = (tileH * screenH) / 2
	
	playerDisplayX = screenCenterX
	playerDisplayY = screenCenterY
	
	If playerX - screenCenterX < 0 Then
		playerDisplayX = playerX
	End If

	If playerX + screenCenterX > mapW * tileW Then
		playerDisplayX = screenCenterX + (screenCenterX - ( mapW * tileW - playerX))
	End If

	If playerY - screenCenterY < 0 Then
		playerDisplayY = playerY
	End If

	If playerY + screenCenterY > mapH * tileH Then
		playerDisplayY = screenCenterY + (screenCenterY - ( mapH * tileH - playerY))
	End If
	
End Function


Function MakeMap:Int[](w:Int, h:Int)

	Local map:Int[] = New Int[w * h]
	
	For Local i:Int = 0 Until map.length
		map[i] = Rand(0, 10)
	Next

	Return map
End Function

Function DrawPlayer()

'	DrawText "X", 100 + playerDisplayX - 4, 100 + playerDisplayY - 5
	DrawText "X", 100 + playerDisplayX, 100 + playerDisplayY

	DrawText "Player = " + playerX + ", " + playerY, 10, 25
End Function

Function DrawMap(map:Int[])

	Local w:Int = tileW * screenW
	Local h:Int = tileH * screenH
	
	' draw the tiles based on the player position
	
	' calc current player/tile 
	Local pTileX:Int = playerX / tileW
	Local pTileY:Int = playerY / tileH

	DrawText "Current Tile = " + pTileX + ", " + pTileY, 10, 10

	Local screenCenterX:Int = w / 2
	Local screenCentery:Int = h / 2

	' top left
	Local startTileX:Int = pTileX - (screenW / 2)
	Local startTileY:Int = pTileY - (screenH / 2)
	
	Local offsetX:Int = playerX Mod tileW
	Local offsetY:Int = playerY Mod tileH
	
	If startTileX < 0 Then
		startTileX = 0
		offsetX = 0
	End If

	If startTileX + screenW >= mapW Then
		startTileX = mapW - screenW
		offsetX = 0
	End If
	
	If startTileY < 0 Then
		startTileY = 0
		offsetY = 0
	End If

	If startTileY + screenH >= mapH Then
		startTileY = mapH - screenH
		offsetY = 0
	End If

	For Local y:Int = 0 To screenH
		If y + startTileY < mapH Then
			For Local x:Int = 0 To screenW
				If x + startTileX < mapW Then
					' tile pixel coords
					Local tileX:Int = x * tileW
					Local tileY:Int = y * tileH
					
					' adjust to player pixel position
					' This makes it scroll smoothly
					tileX:- offsetX
					tileY:- offsetY
					
				
					Local tile:Int = (startTileY + y) * mapW + startTileX + x
					DrawTile(tileX, tileY, map[tile], tile)
				End If
			Next
		End If
	Next

	' draw the screen edge
	DrawLine 100, 100, 100 + w, 100
	DrawLine 100 + w, 100, 100 + w, 100 + h
	DrawLine 100 + w, 100 + h, 100, 100 + h
	DrawLine 100, 100 + h, 100, 100

End Function

Function DrawTile(x:Int, y:Int, map:Int, tile:Int)
	Local xPos:Int = 100 + x
	Local yPos:Int = 100 + y
	
	SetColor(255, 0, 0)
	' tile border
	DrawLine xPos, yPos, xPos + tileW, yPos
	DrawLine xPos + tileW, yPos, xPos + tileW, yPos + tileH
	DrawLine xPos + tileW, yPos + tileH, xPos, yPos + tileH
	DrawLine xPos, yPos + tileH, xPos, yPos
	
	' tile text
	DrawText map, xPos + 2, yPos + 2
	
	' tile array pos
	'SetColor(0, 100, 100)
	'DrawText tile, xPos + 0, yPos + 10
	
	SetColor(255, 255, 255)
End Function


I think the important thing when you are scrolling is doing it smoothly, unless your character moves in whole-tile-steps ;-)

I've made the actual scroll area such that you can see how it is drawing the tiles across the viewable area in order to have those new tiles appear smoothly.

Note that it is always drawing width/length +1 row/column number of tiles.

Hope it helps... :-)

Ahh! Thanks. Will study it. Da Codezz r teh always g00d. :)

I updated the map I posted above. A little bit more documented and slightly more flexible. Let me know what you think. Let me know what you don't understand and I'll try to explain it to the best of my ability.