TileMap Array and only drawing whats on screen?

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

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

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