Help creating a tile based game

BlitzMax Forums/BlitzMax Beginners Area/Help creating a tile based game

spraycanmansam(Posted 2011) [#1]
Hi all,

As the title, I've been searching the forum and external sources for a few days for info and code snippets to help me on my way to create a tile based RPG.

I wouldn't class myself as a noob when it comes to programming, I've punched out a few run-of-the-mill games but I've never attempted a tile-based game.

I work best when I can see the basic working code/principle and break it down. Are there any links to posts on the forum with a working example and source code?

I really need to know where to start and how to setup and handle the tiles? Even if there's a framework/engine that would help?

Much appreciated :)


Cheers,
Sam


Czar Flavius(Posted 2011) [#2]
In this post I helped someone with what sounds like a similar game. Here is the post with a working code sample, that might give you some ideas. You need to press enter to start it.

http://blitzbasic.com/Community/posts.php?topic=90762#1033024

You could take a look at TileMax by _Skully

http://tilemax.webs.com/

Last edited 2011


Corum(Posted 2011) [#3]
Although nowadays they aren't the most performing ones, they're still a good source of information, helping the novice to figure out what are the basic mechanics behind a tile-based visualization engine.
Both engines come with an handy module+example written for Blitzmax. You can find them by scrolling the following urls:
http://tilestudio.sourceforge.net/
http://tilemap.co.uk/mappy.php

Tile Studio, IMHO, is very interesting to work on. ;-)


slenkar(Posted 2011) [#4]
when you say tile-based do you mean square tiles or iso?


Jesse(Posted 2011) [#5]
here is a link to a simple tile engine source code I made a few years back:

http://www.blitzmax.com/codearcs/codearcs.php?code=2235

it is not much but it illustrate basic principles.

Last edited 2011


AltanilConard(Posted 2011) [#6]
The idea behind tilebased RPG's are pretty universal. Once you're familiar with BlitzMax you could best learn from other sources. I remember finding some GameDev articles extremely usefull, but can't find them atm...

For handling the Tiles, just use a 2 dimensional array of integers, use a tilesheet where each frame represents a tile, and drawing the map gets easy.

I believe writing a full featured Tilemap class yourself (probably multiple times) is a necessary experience for all 2D game programmers, you'll learn lots from it.


spraycanmansam(Posted 2011) [#7]
@slenkar: I would love to make an iso-tile game, but I'm starting easy and going for the basic square tile game :)

Thanks for the examples, they're very useful :)

I've been thinking about how to go about generating and reading the tile maps...? (the examples created random tile maps)

I'm downloading Tilestudio to see if I can figure out if it will do what I want it to do. Half the problem is I don't know what I want it to do :P


spraycanmansam(Posted 2011) [#8]
Ok well I've knocked up a lil tile system from the examples, I've included the code (modified so it'll run out of the box :) If I've done anything wrong or there's a more efficient way, school me :P

Something I need help with is how would I program the character to move on the tiles? Specifically, I want the character to move a tile at a time but with a smooth transition... does that make sense?

Say a tile is 32px. If the character moves 32px every key hit it's too fast and jerky. I'm after a way to make the character keep moving to the next tile after the direction key press.


Strict


Graphics( 1024, 768 )

'MAP VARIABLES

Const tileSize		= 32
Const mapWidth		= 20								'width of map in tiles
Const mapHeight		= 20								'height of map in tiles

Global map:TTile[,] = New TTile[ mapWidth, mapHeight ] 	'creates a tile map mapWidth wide * mapHeight high



'TILE VARIABLES

Global numOfTileBases = 1
Global allTileBases:TTileBase[] = New TTileBase[ numOfTileBases ]



'TYPES

Type TTile
	
	Field X:Int
	Field Y:Int
	
	Field tileBase:TTileBase	
	
	Global list:TList
	Global image:TImage

	
	Method render()
		
		tileBase.render( X, Y )
	
	End Method
	
	Method update()
	
		render()
	
	End Method
	
	
	Function updateAllTiles()
		
		If Not list  Return
		
		For Local t:TTile = EachIn list
		
			t.update()	
		
		Next
	
	End Function

	Function createTile:TTile( x:Int, y:Int, tileBase:Int )
	
		If Not list  list = CreateList()
		Local t:TTile = New TTile
		list.AddLast( t )
		
			t.X = x
			t.Y = y
			
			t.tileBase = allTileBases[ tileBase ]
		
	End Function
		
End Type


Type TTileBase
	
	Global image:TImage
	

	Method render( x:Int, y:Int )
	
		'DrawImage( image, tileXYtoPixelXY( x ), tileXYtoPixelXY( y ) )
		
		SetColor( 75, 75, 75 )
		DrawRect( tileXYtoPixelXY( x ), tileXYtoPixelXY( y ), tileSize - 1, tileSize - 1 )
		SetColor( 255, 255, 255 )
		
	End Method
	
	
	Function createTileBase:TTileBase( passable:Int )
		
		Local tb:TTileBase = New TTileBase
					
		
		'If Not image  image = LoadImage( "images/grassimg.png" )

		Return( tb )
		
	End Function
	
End Type




Type TPlayer
	
	Field X:Float
	Field Y:Float
	
	Global list:TList
	Global image:TImage

	
	Method render()
	
		'DrawImage( image, X, Y )
		DrawRect( X, Y, tileSize, tileSize )
		
	End Method
	
	Method update()
	
		render()
		
		
		'dont want to be able to move diagonally
		
		If KeyDown( KEY_LEFT )	
			X:-1
		Else If KeyDown( KEY_RIGHT )
			X:+1
		Else If KeyDown( KEY_DOWN )
			Y:+1
		Else If KeyDown( KEY_UP )
			Y:-1
		End If

	End Method
	
	
	Function updatePlayer()
	
		If Not list  Return
		
		For Local p:TPlayer = EachIn list
		
			p.update()
		
		next
				
	End Function
	
	Function createPlayer()
	
		If Not list  list = CreateList()
		Local p:TPlayer = New TPlayer 
		list.AddLast( p )
		
			p.X = ( mapWidth / 2 ) * tileSize
			p.Y = ( mapHeight / 2 ) * tileSize
		
		'If Not image  image = LoadImage( "images\playerimg.png" )
		
	End Function

End Type




loadMap()
TPlayer.createPlayer()

SetOrigin( (1024/2)-(mapWidth/2)*tileSize, 768/2-(mapHeight/2)*tileSize ) 'centers map


While Not KeyHit( KEY_ESCAPE )
	
	Cls
	
		TTile.updateAllTiles()
		TPlayer.updatePlayer()
	
	Flip

Wend




'FUNCTIONS

Function loadMap() 										'create map of tiles
	
	allTileBases[ 0 ] = TTileBase.createTileBase( Null )
	
	
	For Local x:Int = 0 To ( mapWidth - 1 )
		For Local y:Int = 0 To ( mapHeight - 1 )
			map[ x, y ] = TTile.createTile( x, y, 0 )
		Next
	Next

End Function


Function tileXYtoPixelXY( z:Int )								'multiplies map x and y values by the tileSize
	
	Return( z * tileSize )

End Function


Last edited 2011


CS_TBL(Posted 2011) [#9]
To keep a character moving: use a timer, and don't control the x,y-coords directly from reading out the cursor keys, but let cursor keys set a walking state to 1, and a direction variable to the direction given with these cursors. As long as the state is 1, the player moves into the direction given by the direction variable. If the player has arrived onto the new tile, set the walking state to 0.

With each timer tick you update the whole shebang..


CS_TBL(Posted 2011) [#10]
Simplified, but clear as a whistle.

SuperStrict
Graphics 640,480

Local px:Int=64,py:Int=64,direction:Int,walking:Int
Local timer:ttimer=CreateTimer(30)

Repeat
	WaitTimer(timer)

	' scan the cursors
	'
	If KeyDown(KEY_LEFT)
		If walking=0 direction=3;walking=1
	ElseIf KeyDown(KEY_RIGHT)
		If walking=0 direction=1;walking=1
	ElseIf KeyDown(KEY_UP)
		If walking=0 direction=0;walking=1
	ElseIf KeyDown(KEY_DOWN)
		If walking=0 direction=2;walking=1
	EndIf
	
	' update player
	If walking
		Select direction
			Case 0 py:-2
			Case 1 px:+2
			Case 2 py:+2
			Case 3 px:-2
		End Select
		If px=(px/16)*16 And py=(py/16)*16 ' check whether the player is on a grid point
			walking=0
		EndIf
	EndIf
	
	' draw the whole shebang
	Cls

	' blue grid	
	SetColor 0,0,255
	For Local y:Int=0 To 479 Step 16
		DrawRect 0,y,640,1
	Next
	For Local x:Int=0 To 639 Step 16
		DrawRect x,0,1,480
	Next
	
	' yellow hero
	SetColor 255,255,0
	DrawRect px,py,16,16
	
	DrawText "U R D L Esc",2,2
	Flip
Until KeyHit(KEY_ESCAPE)
End



Snader(Posted 2011) [#11]
Thanks mate!