Getting absolute Tile Position?

BlitzMax Forums/BlitzMax Beginners Area/Getting absolute Tile Position?

I have a TileMap drawn to screen. If the tiledata = 2 it draws my player at that tile position.

eg.

if Map[xy] = 2
Drawimage Player, x*32 , y*32, 0

Now, How would I get it's actual location across the screen (ie it's at coords 400,300 px)?

Another example below.

defdata 0,0,0,0,0
defdata 0,0,0,0,0
defdata 0,0,0,0,0
defdata 0,0,x,0,0

Where x is. I need to know it's screen location.

Am I making sense?

By the way. I'm trying some Platform Code I learned a long time ago from a guy called Alan Mcdonald. This is going back 5 years. Don't know if he is still around.

I can't find the thread where he helped me and am trying from memory to recode it for max.

Heres how far I've got so far.

SuperStrict


Graphics 800 , 600

Global Tiles:TImage = LoadAnimImage("ice_floortiles.png",32,32,0,8)
Global Player:TImage = LoadImage("player.png")


Const MAPWIDTH:Int = 800/32
Const MAPHEIGHT:Int = 600/32

Global Map:Int[MAPWIDTH , MAPHEIGHT]

Global PlayerX:Int
Global PlayerY:Int

Global Direction:String = "Standing"

ReadLevelData()

While Not KeyHit(KEY_ESCAPE)
	
	Cls
	
	DrawMap()
	DrawPlayer()
	MovePLayer()
	CheckIfPlayerCollideWithTile()
	Flip
	
	
Wend

Function DrawPlayer()
	For Local x:Int = 0 Until MAPWIDTH
		For Local y:Int = 0 Until MAPHEIGHT
			Select Map[x,y]
				Case 2
					'DrawImage Player , PlayerX+x*32 ,PlayerY + y*32 , 0
					DrawImage Player ,x*32 ,y*32 , 0
					Local TempPosX:Int = x/32
					
					DrawText "tempPosX = " + TempPosX , 0 , 20
			End Select
		Next
	Next	
End Function

Function MovePLayer()
	
	If KeyDown(KEY_LEFT)
		If Not KeyDown(KEY_RIGHT)
			Direction = "Moving_Left"
			PlayerX:-2
		EndIf
	ElseIf KeyDown(KEY_RIGHT)
		If Not KeyDown(KEY_LEFT)
			Direction = "Moving_Right"
			PlayerX:+2
		EndIf
	End If
End Function

Function CheckIfPlayerCollideWithTile()
	Local TempX:Int = PlayerX/32
	Local TempY:Int = PlayerY/32
	
	If Direction = "Moving_Right"
'	If TempX>0
		If Map[TempX, TempY] = 1
			PlayerX:-2
		End If
	EndIf
'	EndIf
	DrawText "TempX = "+TempX,0,0
End Function


Function DrawMap()
	For Local x:Int = 0 Until MAPWIDTH
		For Local y:Int = 0 Until MAPHEIGHT
			Select Map[x,y]
				Case 1
					DrawImage Tiles , x*32 , y*32 , 0
			End Select
		Next
	Next
End Function


Function ReadLevelData()
	For Local y:Int = 0 Until MAPHEIGHT
		For Local x:Int = 0 Until MAPWIDTH
			Local data:Int 
			ReadData data
			Map[x,y] = data
		Next
	Next
End Function



DefData 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,2,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1
DefData 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1


As you can see I'm trying to get platform collision working.

I'm not quite sure what you're asking, but hopefully this function-tastic code will be helpful in some way? ;)

Assuming your tiles will have a size sizeX, and perhaps offset from the side of the screen offsetX.

Function getX:Int(x:Int)
   Return sizeX * x + offsetX
End Function


And a similar function for Y. Store the values at least as constants, rather than "magic numbers"

So to draw your tiles,

For Local x:Int = 0 Until MAPWIDTH
   For Local y:Int = 0 Until MAPHEIGHT
      Drawimage Blah, getX(x), getY(y), blahh
   Next
Next


I made a simple top-down tile game stored using an array. You can look at it if you want. It was written in the old Blitz Basic though.

Thanks for the code. I'll try it.

Can you send me your old BB code. My email is in my profile. :)

The code you posted seems kind of weard in my eyes and I don't really understand how you were planning to keep track of the players location. I allways handle tile maps by keeping track of the player his ScreenX and Y location and his MapX and Y location (MapX = ScreenX/TILE_WIDTH). Here I edited your code to show you what I mean:
SuperStrict


Graphics 800 , 600

Global Tiles:TImage = LoadAnimImage("ice_floortiles.png",32,32,0,8)
Global Player:TImage = LoadImage("player.png")


Const MAPWIDTH:Int = 800/32
Const MAPHEIGHT:Int = 600/32

Global Map:Int[MAPWIDTH , MAPHEIGHT]

Global PlayerScreenX:Int
Global PlayerScreenY:Int
Global PlayerMapX:Int
Global PlayerMapY:Int

Global Direction:String = "Standing"

ReadLevelData()

While Not KeyHit(KEY_ESCAPE)
	
	Cls
	
	DrawMap()
	DrawPlayer()
	MovePLayer()
	CheckIfPlayerCollideWithTile()
	Flip
	
	
Wend

Function DrawPlayer()
	For Local x:Int = 0 Until MAPWIDTH
		For Local y:Int = 0 Until MAPHEIGHT
			Select Map[x,y]
				Case 2
					'DrawImage Player , PlayerX+x*32 ,PlayerY + y*32 , 0
					DrawImage Player, PlayerScreenX, PlayerScreenY, 0
			End Select
		Next
	Next	
End Function

Function MovePLayer()
	
	If KeyDown(KEY_LEFT)
		If Not KeyDown(KEY_RIGHT)
			Direction = "Moving_Left"
			PlayerScreenX:-2
		EndIf
	ElseIf KeyDown(KEY_RIGHT)
		If Not KeyDown(KEY_LEFT)
			Direction = "Moving_Right"
			PlayerScreenX:+2
		EndIf
	End If
End Function

Function CheckIfPlayerCollideWithTile()
	PlayerMapX = PlayerScreenX/32
	PlayerMapY = PlayerScreenY/32
	
	If Direction = "Moving_Right"
		If Map[PlayerMapX+1,PlayerMapY] = 1
			PlayerScreenX:-2
		End If
	ElseIf Direction = "Moving_Left"
		If Map[PlayerMapX,PlayerMapY] = 1
			PlayerScreenX:+2
		EndIf
	EndIf

	DrawText "PlayerMapX = "+PlayerMapX,0,0
End Function


Function DrawMap()
	For Local x:Int = 0 Until MAPWIDTH
		For Local y:Int = 0 Until MAPHEIGHT
			Select Map[x,y]
				Case 1
					DrawImage Tiles , x*32 , y*32 , 0
			End Select
		Next
	Next
End Function


Function ReadLevelData()
	For Local y:Int = 0 Until MAPHEIGHT
		For Local x:Int = 0 Until MAPWIDTH
			Local data:Int 
			ReadData data
			Map[x,y] = data
			If Map[x,y] = 2 Then
				PlayerMapX = x
				PlayerMapY = y
				PlayerScreenX = x*32
				PlayerScreenY = y*32
			EndIf
		Next
	Next
End Function



DefData 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,2,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1
DefData 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1


(It only uses the 2 value of the map to determine the players starting location and then updates it to PlayerScreenX/Y and PlayerMapX/Y)

Hi. Thanks for the replies. I've made some progress.

Here it is. It Kind of works but not to the extent of a working platformer example.

Any help would be appreciated.

SuperStrict


Graphics 800 , 600

Global Tiles:TImage = LoadAnimImage("ice_floortiles.png",32,32,0,8)
Global Player:TImage = LoadImage("player.png")


Const MAPWIDTH:Int = 800/32
Const MAPHEIGHT:Int = 600/32

Global Map:Int[MAPWIDTH , MAPHEIGHT]

Global PlayerX:Float
Global PlayerY:Float

Global CheckPlayerPosition:Int = 0

Global Direction:String = "Standing"

Global Jump:Int = 0
Const Gravity:Float = 0.1
Global JumpHeight:Float = 3
Global CanJump:Int = 0
Global Falling:Int = 0

ReadLevelData()

While Not KeyHit(KEY_ESCAPE)
	
	Cls
	
	DrawMap()
	DrawPlayer()
	MovePLayer()
	DoJump()
	CheckIfPlayerCollideWithTile()
	
	Flip
	
	
Wend

Function DrawPlayer()
	If CheckPlayerPosition = 0
	For Local x:Int = 0 Until MAPWIDTH
		For Local y:Int = 0 Until MAPHEIGHT
			Select Map[x,y]
				Case 2
					'DrawImage Player ,x*32 ,y*32 , 0
					PlayerX = getX(x)
					PlayerY = getY(y)
					CheckPlayerPosition = 1
			End Select
		Next
	Next
	EndIf
	DrawText "PlayerX = " + PlayerX , 0 , 20
	DrawImage Player, PlayerX , PlayerY , 0	
End Function

Function MovePLayer()
	
	If KeyDown(KEY_LEFT)
		If Not KeyDown(KEY_RIGHT)
			Direction = "Moving_Left"
			PlayerX:-2
		EndIf
	ElseIf KeyDown(KEY_RIGHT)
		If Not KeyDown(KEY_LEFT)
			Direction = "Moving_Right"
			PlayerX:+2
		EndIf
	End If
End Function

Function CheckIfPlayerCollideWithTile()
	Select Direction
		Case "Moving_Right"
			If Jump = 0
			If Map[PlayerX/32 + 1, PlayerY/32] = 1
				PlayerX:-2
			EndIf
			EndIf
		Case "Moving_Left"
			If Jump = 0
			If Map[PlayerX/32, PlayerY/32] = 1
				PlayerX:+2
			End If
			endif
		Case "Standing"
			If Map[PlayerX/32 , PlayerY/32+1] = 1
				Jump = 0
				CanJump = 1
				JumpHeight = 3
				Falling = 0
			End If
	End Select
	
	If Falling = 1
		If Map[PlayerX/32 , PlayerY/32+1] = 1
			Jump = 0
			CanJump = 1
			JumpHeight = 3
			Falling = 0
			PlayerY:-PlayerY
		End If
	End If
	
	
End Function

Function DoJump()
	If KeyHit(KEY_SPACE) And CanJump = 1
		Jump = 1
		CanJump = 0
	End If
	
	If Jump = 1
		PlayerY:-JumpHeight
		JumpHeight:-Gravity
		If JumpHeight <=-5
			JumpHeight = -5
			Falling = 1
		EndIf
	End If
	
	
End Function

Function DrawMap()
	For Local x:Int = 0 Until MAPWIDTH
		For Local y:Int = 0 Until MAPHEIGHT
			Select Map[x,y]
				Case 1
					DrawImage Tiles , x*32 , y*32 , 0
			End Select
		Next
	Next
End Function


Function ReadLevelData()
	For Local y:Int = 0 Until MAPHEIGHT
		For Local x:Int = 0 Until MAPWIDTH
			Local data:Int 
			ReadData data
			Map[x,y] = data
		Next
	Next
End Function

'Function getX:Int(x:Int)
'   Return sizeX * x '+ offsetX
'End Function
'
'Function getY:Int(y:Int)
'   Return sizeX * y '+ offsetX
'End Function

Function getX:Int(x:Int)
   Return 32 * x '+ offsetX
End Function

Function getY:Int(y:Int)
   Return 32 * y '+ offsetX
End Function

DefData 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1
DefData 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1


Version 3. Again this Kind of Works. :/

Please someone help me figure out how to make platform games collision. :)

SuperStrict


Graphics 800 , 600

Global Tiles:TImage = LoadAnimImage("ice_floortiles.png",32,32,0,8)
Global Player:TImage = LoadImage("player.png")


Const MAPWIDTH:Int = 800/32
Const MAPHEIGHT:Int = 600/32

Global Map:Int[MAPWIDTH , MAPHEIGHT]

Global PlayerX:Float
Global PlayerY:Float

Global CheckPlayerPosition:Int = 0

Global Direction:Int = -1

Global Jump:Int = 0
Const Gravity:Float = 0.2
Global JumpHeight:Float = 5.5
Global CanJump:Int = 1
Global Falling:Int = 0
Global Jumping:Int = 0

ReadLevelData()

While Not KeyHit(KEY_ESCAPE)
	
	Cls
	
	DrawMap()
	DrawPlayer()
	MovePLayer()
	DoJump()
	CheckIfPlayerCollideWithTile()
	
	Flip
	
	
Wend

Function DrawPlayer()
	If CheckPlayerPosition = 0
	For Local x:Int = 0 Until MAPWIDTH
		For Local y:Int = 0 Until MAPHEIGHT
			Select Map[x,y]
				Case 2
					'DrawImage Player ,x*32 ,y*32 , 0
					PlayerX = getX(x)
					PlayerY = getY(y)
					CheckPlayerPosition = 1
			End Select
		Next
	Next
	EndIf
	DrawText "PlayerX = " + PlayerX , 0 , 20
	DrawImage Player, PlayerX , PlayerY - 3 , 0	
End Function

Function MovePLayer()
	
	If KeyDown(KEY_LEFT)
		If Not KeyDown(KEY_RIGHT)
			Direction = 0
			PlayerX:-2
		EndIf
	ElseIf KeyDown(KEY_RIGHT)
		If Not KeyDown(KEY_LEFT)
			Direction = 1
			PlayerX:+2
		EndIf
	End If
End Function

Function CheckIfPlayerCollideWithTile()
'#Region 
	Select Direction
		Case 1
			If Map[PlayerX/32+1, PlayerY/32] = 1
				PlayerX:-2
			EndIf
		Case 0
			If Map[PlayerX/32, PlayerY/32] = 1
				PlayerX:+2
			End If
	End Select
		
'#End Region 

	If Falling = 1
		PlayerY:+5
		If Map[PlayerX/32,PlayerY/32+1] = 1
			Jump = 0
			Falling = 0
			CanJump = 1
			JumpHeight = 5.5
		Else
			Falling = 0
		End If
	End If

End Function

Function DoJump()
	If KeyHit(KEY_SPACE) And CanJump = 1
		Jump = 1
		CanJump = 0
		Jumping = 1
	End If
	
	If Jump = 1
		PlayerY:-JumpHeight
		JumpHeight:-Gravity
		If JumpHeight <=-3
			Falling = 1
		EndIf
	End If
	
	
End Function

Function DrawMap()
	For Local x:Int = 0 Until MAPWIDTH
		For Local y:Int = 0 Until MAPHEIGHT
			Select Map[x,y]
				Case 1
					DrawImage Tiles , x*32 , y*32 , 0
			End Select
		Next
	Next
End Function


Function ReadLevelData()
	For Local y:Int = 0 Until MAPHEIGHT
		For Local x:Int = 0 Until MAPWIDTH
			Local data:Int 
			ReadData data
			Map[x,y] = data
		Next
	Next
End Function

'Function getX:Int(x:Int)
'   Return sizeX * x '+ offsetX
'End Function
'
'Function getY:Int(y:Int)
'   Return sizeX * y '+ offsetX
'End Function

Function getX:Int(x:Int)
   Return 32 * x '+ offsetX
End Function

Function getY:Int(y:Int)
   Return 32 * y '+ offsetX
End Function

DefData 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1
DefData 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1


here I tried to fix your code but is taking me too long to figure out what you are doing I managed to fix the movement and added falling code sorry for removing the jump function but I thought it was better for all user input to be in the same function. It is just my opinion. anyway I was trying to figure out why you land in the middle of tiles but it was taking me too long and I don't have the time. maybe if no one solves it for you I might have time later on to do it. also I noted that you add the movement before you check for collition. I suggest you check for collition before you move the character and add after. I think it makes the code more readable. again just an opinion.
SuperStrict

Graphics 800 , 600

Global Tiles:TImage = LoadAnimImage("ice_floortiles.png",32,32,0,8)
Global Player:TImage = LoadImage("player.png")


Const MAPWIDTH:Int = 800/32
Const MAPHEIGHT:Int = 600/32

Global Map:Int[MAPWIDTH , MAPHEIGHT]

Global PlayerX:Float
Global PlayerY:Float

Global CheckPlayerPosition:Int = 0

Global Direction:Int = -1
Global Jump:Int = 0
Const Gravity:Float = 0.2
Global JumpHeight:Float = 5.5
Global CanJump:Int = 1
Global Falling:Int = 0
Global Jumping:Int = 0

ReadLevelData()

While Not KeyHit(KEY_ESCAPE)
	
	Cls
	
	DrawMap()
	DrawPlayer()
	MovePLayer()
	CheckIfPlayerCollideWithTile()
	DrawText direction,10,10
	Flip
	
	
Wend

Function DrawPlayer()
	If CheckPlayerPosition = 0
		For Local x:Int = 0 Until MAPWIDTH
			For Local y:Int = 0 Until MAPHEIGHT
				Select Map[x,y]
					Case 2
						'DrawImage Player ,x*32 ,y*32 , 0
						PlayerX = getX(x)
						PlayerY = getY(y)
						CheckPlayerPosition = 1
				End Select
			Next
		Next
	EndIf
	DrawText "PlayerX = " + PlayerX , 0 , 20
	DrawImage Player, PlayerX , PlayerY - 3 , 0	
End Function

Function MovePLayer()
	
	If KeyDown(KEY_LEFT) And Not KeyDown(KEY_RIGHT) 
		Direction = -2
	ElseIf KeyDown(KEY_RIGHT) And Not KeyDown(KEY_LEFT)
		Direction = 2
	Else
		Direction = 0
	EndIf
	If KeyHit(KEY_SPACE) And CanJump = 1
		Jump = 1
		falling = 0
		CanJump = 0
		Jumping = 1
	End If
	If Jump = 1
		PlayerY:-JumpHeight
		JumpHeight:-Gravity
		If JumpHeight <=-3
			Falling = 1
		EndIf
	End If
End Function

Function CheckIfPlayerCollideWithTile()
'#Region
	' this check the tile to the right  
	If direction > 0 Then If Map[(PlayerX+32+direction)/32, PlayerY/32] <> 1 PlayerX:+direction
	' this checks the tile to the left
	If direction < 0 Then If Map[(PlayerX+direction)/32, PlayerY/32] <> 1 PlayerX:+direction
	' this checks if there is tiles below
	If Not falling And CanJump
	    'checks below the player from the begining to the end of the player tile for missing tiles
		If map[(PlayerX)/32+1,PlayerY/32+1] <> 1  And map[PlayerX/32,PlayerY/32+1] <> 1 Then
			'starts to fall if no tiles below
			falling = 1
		EndIf 
	EndIf	 
'#End Region 

	If Falling = 1
		PlayerY:+5
		If Map[PlayerX/32,PlayerY/32+1] = 1
			Jump = 0
			Falling = 0
			CanJump = 1
			JumpHeight = 5.5
		Else
			Falling = 0
		End If
	End If

End Function

Function DrawMap()
	For Local x:Int = 0 Until MAPWIDTH
		For Local y:Int = 0 Until MAPHEIGHT
			Select Map[x,y]
				Case 1
					DrawImage Tiles , x*32 , y*32 , 0
				Case 2
					DrawImage Tiles , x*32 , y*32 , 1
			End Select
		Next
	Next
End Function


Function ReadLevelData()
	For Local y:Int = 0 Until MAPHEIGHT
		For Local x:Int = 0 Until MAPWIDTH
			Local data:Int 
			ReadData data
			Map[x,y] = data
		Next
	Next
End Function

'Function getX:Int(x:Int)
'   Return sizeX * x '+ offsetX
'End Function
'
'Function getY:Int(y:Int)
'   Return sizeX * y '+ offsetX
'End Function

Function getX:Int(x:Int)
   Return 32 * x '+ offsetX
End Function

Function getY:Int(y:Int)
   Return 32 * y '+ offsetX
End Function

DefData 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1
DefData 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1


'Draw tiles 32*32 on a 640*480 screen
For loopy = 0 to MAP_HEIGHT-1 'We're MAP_HEIGHT = 15
   For loopx = 0 to MAP_WIDTH-1 'We're MAP_WIDTH = 20
      DrawImage Tiles, loopx Shl 5, loopy shl 5, map[loopx,loopy]
   'Get screen coordinate of Tile marked 2
   if map[loopx,loopy] = 2
      TileX = loopx shl 5
      TileY = loopy shl 5
   end if
   Next
Next


And thats it! Bewarned, People dont like Bitshifting for some strange reason, I do though!

Dabz

Give this a spin.

SuperStrict
'grid-array example

Framework brl.GLMax2D
Import BRL.Timer

Const Xnum:Int = 5, Ynum:Int = 5; 'the number of cells
Const Xsize:Int = 32, Ysize:Int = 32; 'size of cells in pixels
Const Xoffset:Int = 32, Yoffset:Int = 64; 'pixels by which the board is offset

'used for glow effect
Const minFlow:Int = 32, maxFlow:Int = 230, flowRate:Int = 1;

'id constants
Const containNum:Int = 3
Const nothing:Int = 0, aThing:Int = 1, aWall:Int = 2;

Const speed:Float = 0.1; 'speed of the player

Type TPlayer
	Field x:Int, y:Int, dirX:Int, dirY:Int 'the current location of the player and if it is moving, the dir is which way. ie dirX=1 means moving right 1 celll
	Field progressX:Float, progressY:Float 'what percentage of the progress to the next cell has been completed
	Field score:Int
	
	Method draw()
		'draws the player at its current location
		SetColor 255, 0, 0;
		DrawOval getX(x) + progressX * dirX * Xsize, getY(y) + progressY * dirY * Ysize, Xsize, Ysize;
		SetColor 255, 255, 255;
		DrawText score, 10, 10;
	End Method
	
	Method updateProgress:Int()
		'if the player is moving between cells, update its progress. returns true if player has completed movement
		Local check:Int = False;
		If dirX
			progressX :+ speed;
		End If
		If dirY
			progressY :+ speed;
		End If
		If progressX > 1.0
			progressX = 0;
			x :+ dirX;
			dirX = 0;
			check = True;
		End If
		If progressY > 1.0
			progressY = 0;
			y :+ dirY;
			dirY = 0;
			check = True;
		End If
		Return check;
	End Method
	
	Method checkMove:Int(xx:Int, yy:Int)
		'can the player move there? or is it off the board
		Return (xx + x >= 0 And xx + x < Xnum) And (yy + y >= 0 And yy + y < Ynum);
	End Method
	
	Method move(directionX:Int, directionY:Int)
		'make a move, unless the player is already moving
		If Not dirX And Not dirY
				dirX = directionX; dirY = directionY;
		End If
	End Method
End Type

'colours
Type TColour
	Field red:Int, green:Int, blue:Int
	
	Method set()
		SetColor red, green, blue;
	End Method
End Type

Function getX:Int(x:Int)
	'gets a cell, returns a pixel
	Return x * Xsize + Xoffset;
End Function

Function getY:Int(y:Int)
	'gets a cell, returns a pixel
	Return y * Ysize + Yoffset;
End Function

Function toX:Int(x:Int)
	'gets a pixel, returns a cell
	Return (x - Xoffset) / Xsize;
End Function

Function toY:Int(y:Int)
	'gets a pixel, returns a cell
	Return (y - Yoffset) / Ysize;
End Function

'each grid cell contains a block
Type TBlock
	Field contains:Int 'nothing, an item, a wall
	Field hasPlayer:Int
	Field mouseOver:Int
	Global flow:Int, flowDirection:Int 'used for flow effect
	Global colour:TColour[] = New TColour[containNum]
	
	Method New()
		'set up the colours for the different types of block
		For Local i:Int = 0 Until containNum
			TBlock.colour[i] = New TColour;
		Next
		
		TBlock.colour[nothing].red = 0; TBlock.colour[nothing].green = 0; TBlock.colour[nothing].blue = 0;
		TBlock.colour[aThing].red = 0; TBlock.colour[aThing].green = 255; TBlock.colour[aThing].blue = 0;
		TBlock.colour[aWall].red = 0; TBlock.colour[aWall].green = 0; TBlock.colour[aWall].blue = 255;
		
		'flow glow
		flow = minFlow; flowDirection = flowRate;
	End Method
	
	Method draw(x:Int, y:Int)
		'draws the cell, with a glowing border if mouse is over
		If mouseOver
			SetColor 255, flow, flow;
		Else
			SetColor 255, 255, 255;
		End If
		updateflow();
		DrawRect x, y, Xsize, Ysize;
		colour[contains].set();
		DrawRect x+1, y+1, Xsize-2, Ysize-2;
	End Method
	
	Method updateflow()
		'updates the glowing effect
		flow :+ flowDirection;
		If flow >= maxFlow
			flowDirection = -flowDirection;
		ElseIf flow <= minFlow
			flowDirection = -flowDirection;
		End If
	End Method
	
	Method isPassable:Int()
		'returns true if this cell can be traversed
		Select contains
			Case nothing
				Return True;
			Case aThing
				Return True;
			Case aWall
				Return False;
			Default
				Return False;
		End Select
	End Method
	
	Method click()
		'change the contents of the cell if clicked
		contains :+ 1;
		If contains => containNum
			contains = 0;
		End If
	End Method
	
	Method pickUp:Int()
		'if the player moves into this cell, and it contains a thing, remove it and increase score
		Select contains
			Case aThing
				contains = nothing;
				Return 1;
			Default
				Return 0;
		End Select
	End Method
End Type



'now for our main game
Type TGame
	Field moving:Int 'is the player currently moving
	Field keypress:Int 'the key pressed by the user
	Field grid:TBlock[,] = New TBlock[Xnum, Ynum] 'the game grid
	Field player:TPlayer = New TPlayer
	Field timer:TTimer = CreateTimer(20) 'fps
	
	Method New()
		'setup the grid
		For Local x:Int = 0 Until Xnum
			For Local y:Int = 0 Until Ynum
				grid[x, y] = New TBlock;
				grid[x, y].contains = nothing;
			Next
		Next
		'setup some starting walls and player
		grid[0, 0].contains = aWall;
		grid[Xnum-1, Ynum-1].contains = aWall;
		grid[0, Ynum-1].contains = aThing;
		grid[Xnum-1, 0].contains = aThing;
		player.x = Floor((Xnum-1)/2); player.y = Floor((Ynum-1)/2);
		grid[player.x, player.y].hasPlayer = True; 'put the player in the middle
	End Method
	
	Method drawGrid()
		'draws the map
		For Local x:Int = 0 Until Xnum
			For Local y:Int = 0 Until Ynum
				grid[x, y].draw(getX(x), getY(y));
			Next
		Next
	End Method
	
	Method drawPlayer()
		'draw the player
		player.draw();
	End Method
	
	Method update()
		'update the player's progress in movement
		If player.updateProgress()
			'if the player has completed movement, check for pickups in this cell
			player.score :+ grid[player.x, player.y].pickUp();
		End If
	End Method
	
	Method move(x:Int, y:Int)
		'attempt to move the player. x y are relative
		If player.checkMove(x, y)
			'if the movement is on the board
			If grid[player.x + x, player.y + y].isPassable()
				'if the cell is passable, make the move
				player.move(x, y);
			End If
		End If
	End Method
	
	Method checkmouse(x:Int, y:Int)
		'scan each cell for the mouse
		x = toX(x); y = toY(y); 'conver the mouse's pixel to a grid coordinate
		For Local xx:Int = 0 Until Xnum
			For Local yy:Int = 0 Until Ynum
				'if the mouse coordinates equal this cells, ergo the condition returns TRUE, set the mouseOver to true
				grid[xx, yy].mouseOver = (x = xx And y = yy);
			Next
		Next
	End Method
	
	Method click()
		'if clicked, look for the cell with the mouse over and click. probably not the best way to do it
		For Local xx:Int = 0 Until Xnum
			For Local yy:Int = 0 Until Ynum
				If grid[xx, yy].mouseOver
					grid[xx, yy].click();
				End If
			Next
		Next
	End Method
End Type

'actual game
Graphics 640, 480;
Notify "Simple grid-based game by Czar Flavius. Use the arrow keys to move and click on a cell to change it. Escape to end.";
Local game:TGame = New TGame;
While Not KeyDown(KEY_ESCAPE)
	Cls;
	game.drawGrid();
	game.drawPlayer();
	Flip;
	game.timer.Wait();
	
	If KeyDown(KEY_UP)
		game.move(0, -1);
	ElseIf KeyDown(KEY_DOWN)
		game.move(0, 1);
	ElseIf KeyDown(KEY_LEFT)
		game.move(-1, 0);
	ElseIf KeyDown(KEY_RIGHT)
		game.move(1, 0);
	End If
	
	game.checkMouse(MouseX(), MouseY());
	
	If MouseHit(1)
		game.click();
	End If
	
	game.update();
	
	If AppTerminate()
		Exit;
	End If
	
Wend
End;




Hi! Thanks for all the replies. I've made some modification from ideas I got from this thread and I have made some progress.

The code works but not flawlessly. I get stuck in between tiles when jumpin ie. i land in the middle of them.

I'm so close to getting this sorted but need a bit more help from you guys.

I've gone through the code and commented it as much as I could so that people can understand what I'm trying to do. Hopefully this will end up as a little template for people to figure out how to make platformers from.

More help is ofcourse appreciated. :)


SuperStrict


Graphics 800 , 600

Global Tiles:TImage = LoadAnimImage("ice_floortiles.png",32,32,0,8)
Global Player:TImage = LoadImage("player.png")


Const MAPWIDTH:Int = 800/32
Const MAPHEIGHT:Int = 600/32

Global Map:Int[MAPWIDTH , MAPHEIGHT]

Global PlayerX:Float 'The players X Location On Screen
Global PlayerY:Float ' The Players Y Location On Screen

Global CheckPlayerPosition:Int = 0 ' A Flag to check the Players Current position. 

Global Direction:Int = -1' The Direction the Player is travelling in

Global Jump:Int = 0 ' Are we Jumping
Const Gravity:Float = 0.2 ' Amount of Gravity to apply to JumpHeight
Global JumpHeight:Float = 5.3' The height The player Jumps in pixels
Global CanJump:Int = 1 ' Whether we can Jump. If we're already jumping we can't jump again ie. double jump.
Global Falling:Int = 0 ' Whether the player is falling. 1 = Falling
'Global Jumping:Int = 0 ' Are we jumping

ReadLevelData() ' We Read the level data

While Not KeyHit(KEY_ESCAPE)
	
	Cls
	
	DrawMap()
	CheckIfPlayerCollideWithTile()
	DrawPlayer()
	MovePLayer()
	DoJump()
	
	
	Flip
	
	
Wend

'######################################################
'#### Function DrawPLayer()							  #
'#### Draws Player to Screen and gets Player Position #
'######################################################
Function DrawPlayer()
	If CheckPlayerPosition = 0 ' We use this to check if there is a number 2 in the tilemap array. If you notice there is a number 2
							   'in the defdata statements. This is used to start the player at that position.		
	For Local x:Int = 0 Until MAPWIDTH ' Loop until MapWidth
		For Local y:Int = 0 Until MAPHEIGHT' Loop Until MapHeight
			Select Map[x,y]' We use a select function to select check data in the MapArray
				Case 2 ' If the data in the map array = 2\/ 
					PlayerX = getX(x) 'we get the location in pixels of the tiles x position and pass it to PlayerX
					PlayerY = getY(y) ' we get the location in pixels of the tiles y position and pass it to PlayerY
					CheckPlayerPosition = 1 ' We switch this to one because we don't want to check the start position of the player anymore
			End Select
		Next
	Next
	EndIf
	DrawText "PlayerX = " +PlayerX , 0 , 20 
	
	DrawImage Player, PlayerX , PlayerY , 0	' Now we have the where the number 2 was in the MapArray and have passed this position
											'to Player X and PlayerY, we use this to draw the player at that location. So if you move the number 2	
											'elsewhere in the defdata statements the player will be drawn according to where it is.
End Function

'#################################################
'###	Function MovePLayer()					 #	
'## 	Moves Player and checks outer boundaries #	
'#################################################
Function MovePLayer()
	
	If KeyDown(KEY_LEFT) And Not KeyDown(KEY_RIGHT)
			Direction = 0 ' set direction to 0. Going Left
			PlayerX:-2 ' Minus 2 from Players X position to move him left
	ElseIf KeyDown(KEY_RIGHT) And Not KeyDown(KEY_LEFT)
			Direction = 1 ' set direction to 1. Going Right
			PlayerX:+2 ' Add 2 to the players X position to move him right
	End If
	
	If PlayerX-32 <=0 ' Boundary checks to prevent our Player Jumping out the screen
		PlayerX:+2
	ElseIf PlayerX >= 800-64 
		PlayerX:-2
	End If
End Function

'##########################################################
'### Function CheckIfPlayerCollideWithTile()			  #
'### Checks to see if the player has collided with a tile #
'### Checks also if the Player is falling                 #
'##########################################################
Function CheckIfPlayerCollideWithTile()
'#Region 
	Select Direction
		Case 1
		If Jump = 0
			If Map[PlayerX/32+1, PlayerY/32] = 1 ' If we put the players X&y position within the map array and divide them by 32
				PlayerX:-2                       ' which is the size of the player and the tiles, we are able to determine which
			EndIf								 ' tile the Player is on or near. if we have a +1 in PlayerX/32+1 or PlayerY/32+1		
		EndIf									 ' it just means we are checking the tiles next to the player. so if we add a +1		
		Case 0									 ' to PlayerY/32 we are checking the tile under the players feet.
		If Jump = 0								 ' In this we are checking the tiles to the right and left and if they = 1 (Tile is present)			
			If Map[PlayerX/32, PlayerY/32] = 1   ' then we stop the player from moving.
				PlayerX:+2
			End If
		EndIf
	End Select
		
'#End Region 

	If Falling = 1 ' If falling = 1 we minus 3.2 from the players Y position making him fall.
		PlayerY:+3.2
		If Map[PlayerX/32,PlayerY/32+1] = 1 ' While he's falling if we check to see if a tile is underneath and if there is
			Jump = 0                        ' We stop falling. We reset Jump to 0 and CanJump to 1 and also reset the JumpHeight
			Falling = 0
			CanJump = 1
			JumpHeight = 5.5
		EndIf
	End If

	If Map[PlayerX/32,PlayerY/32+1] = 1 ' This is used seperately and does nothing apart from enabling me to use the "else bit"
	Else                                ' If there's nothing under the players feat we start falling but only if we're not jumping
		If Jump = 0
			Falling = 1
		EndIf
	End If
End Function

'##############################################
'### Function DoJump()                        #
'### Makes our player jump                    #
'##############################################
Function DoJump()
	If KeyHit(KEY_SPACE) And CanJump = 1 ' If we hit the space button and CanJump = 1
		Jump = 1 ' We enable Jump
		CanJump = 0 ' We Disable CanJump. Can't jump while jumping 
	End If
	
	If Jump = 1 ' If Jump is enabled
		PlayerY:-JumpHeight ' we minus JumpHeight from Players Y Position
		JumpHeight:-Gravity ' We minus Gravity from JumpHeight
		If JumpHeight <=-1.0 ' If JumpHeight <= -1.0
			Falling = 1 ' We beging to fall by setting Falling to 1
		EndIf
	End If
	
	
End Function

'########################################
'### Function DrawMap()                 #
'### We Draw the Map to screen          #
'########################################
Function DrawMap()
	For Local x:Int = 0 Until MAPWIDTH ' we loop until MapWidth
		For Local y:Int = 0 Until MAPHEIGHT ' We loop until MapHeight
			Select Map[x,y] ' We select the data stored in the MapArray
				Case 1 ' if it = 1
					DrawImage Tiles , x*32 , y*32 , 0 ' we draw the tiles to there corresponding position
			End Select
		Next
	Next
End Function

'#######################################################
'### Function ReadLevelData()            			   #
'### We read the data stored in the defdata statements #
'#######################################################
Function ReadLevelData()
	For Local y:Int = 0 Until MAPHEIGHT' We loop through the Y position first until MapHeight
		For Local x:Int = 0 Until MAPWIDTH ' We Loop Until MAPWIDTH
			Local data:Int  ' Setup a local variable to store the data in
			ReadData data ' We read the data from the defdata statements in to the data variable
			Map[x,y] = data ' we assign the data in the data variable to our MapArray
		Next
	Next
End Function

'Function getX:Int(x:Int)
'   Return sizeX * x '+ offsetX
'End Function
'
'Function getY:Int(y:Int)
'   Return sizeX * y '+ offsetX
'End Function


Function getX:Int(x:Int)
   Return 32 * x '+ offsetX
End Function

Function getY:Int(y:Int)
   Return 32 * y '+ offsetX
End Function

DefData 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1
DefData 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1


[edit 1] The art needed to get this example working can be download here. http://www.kamikazekrow.com/storage/PlatArt.zip

[edit 2] to put code in a scrollable box use the codebox tag. it's the same as [ code ] but [ codebox ].

Could you put up the image files, or make it so the program is not dependant upon external files? Thanks.

The files can be downloaded here.

http://www.kamikazekrow.com/storage/PlatArt.zip

:)

bump! :)

If I'm going about it wrong then please let me know. Currently it works ok but you can get stuck in the middle of a tile on it's y axis when jumping.

Are there better methods to platform collsision?

I'll have a go at the code later.
Couple of things.
1) You're checking for collision with a tile regardless of the height of the player's jump.
e.g. If the player end his jump and begin to fall at Y=48 it will be half way intoa tile and get stuck.
You should only be checking for the collision when Y is 'tile' boundary.
2) You're fall speed means you sometimes fall through a tile. If you collide you need to check if your previous position would also have collided
e.g. Y=Y+3. If Y+3 is 2 pixels into a tile you need to check Y+2 and Y+1.
.
As for other types of collision you might want to add all the tiles to a collision layer and test the players feet against that collision layer.
If it is a single screen platformer you could consider a single screensized image which you don't have to display but contains the upper most part of any platform (e.g. a 32*1 rect). This would simplify the collision testing although it means you have to check each position.
Hope it helps.
P.S. There must be example paltform code somewhere. Didn't Scott Shaver do some? If not, B2D/B3D code will be similar and the JumpAround source is out there somewhere.

Have you had a look at the code yet, tonyg?

I tried to implement what you said but kept getting index out of bounds errors.

Sorry Amon, other things have taken over. I will try again later but can't promise anything.

I love making platformers... I use bit-shifting (Non of that 2*32 pap) or pixel checking for collisions, as it works for me! :)

I think we went over this at BlitzCoder Amon didnt we? Well, in BlitzBasic anyway! :)

I havent made a full platformer in Max as of yet, but here is a conversion of a Blitz+ one I did yonks ago:-

http://www.syntaxbomb.com/ftp/dabz/Dizzy.zip

*Note: Not the tidiest of Max code in there mind, and the media is a little disorganised, but its easy to see whats going on with collisions.

It shows pixel checking collisions, up/down hills, jumping up and banging your head... No real left/right checking as I do that with if map[(x Shr 5)-1,y shr 5) = wall

I like pixel checking up/down as it frees you from blocky graphics, as well as you can disguise normal objects as bonus ones... etc etc

Anyway, thats my 10p, have fun! :)

Dabz

Here Amon, see if this helps you. This is your code only the changes added:



SuperStrict


Graphics 800 , 600

Global Tiles:TImage = LoadAnimImage("ice_floortiles.png",32,32,0,8)
Global Player:TImage = LoadImage("player.png")


Const MAPWIDTH:Int = 800/32
Const MAPHEIGHT:Int = 600/32

Global Map:Int[MAPWIDTH , MAPHEIGHT]

Global PlayerX:Float 'The players X Location On Screen
Global PlayerY:Float ' The Players Y Location On Screen

Global CheckPlayerPosition:Int = 0 ' A Flag to check the Players Current position. 

Global Direction:Int = -1' The Direction the Player is travelling in

Global Jump:Int = 0 ' Are we Jumping
Const Gravity:Float = 0.2 ' Amount of Gravity to apply to JumpHeight
Global JumpHeight:Float = 5.3' The height The player Jumps in pixels
Global CanJump:Int = 1 ' Whether we can Jump. If we're already jumping we can't jump again ie. double jump.
Global Falling:Int = 0 ' Whether the player is falling. 1 = Falling
'Global Jumping:Int = 0 ' Are we jumping

ReadLevelData() ' We Read the level data

While Not KeyHit(KEY_ESCAPE)
	
	Cls
	
	DrawMap()
	CheckIfPlayerCollideWithTile()
	DrawPlayer()
	MovePLayer()
	DoJump()
	
	
	Flip
	
	
Wend

'######################################################
'#### Function DrawPLayer()							  #
'#### Draws Player to Screen and gets Player Position #
'######################################################
Function DrawPlayer()
	If CheckPlayerPosition = 0 ' We use this to check if there is a number 2 in the tilemap array. If you notice there is a number 2
							   'in the defdata statements. This is used to start the player at that position.		
	For Local x:Int = 0 Until MAPWIDTH ' Loop until MapWidth
		For Local y:Int = 0 Until MAPHEIGHT' Loop Until MapHeight
			Select Map[x,y]' We use a select function to select check data in the MapArray
				Case 2 ' If the data in the map array = 2\/ 
					PlayerX = getX(x) 'we get the location in pixels of the tiles x position and pass it to PlayerX
					PlayerY = getY(y) ' we get the location in pixels of the tiles y position and pass it to PlayerY
					CheckPlayerPosition = 1 ' We switch this to one because we don't want to check the start position of the player anymore
			End Select
		Next
	Next
	EndIf
	DrawText "PlayerX = " +PlayerX , 0 , 20 
	
	DrawImage Player, PlayerX , PlayerY , 0	' Now we have the where the number 2 was in the MapArray and have passed this position
											'to Player X and PlayerY, we use this to draw the player at that location. So if you move the number 2	
											'elsewhere in the defdata statements the player will be drawn according to where it is.
End Function

'#################################################
'###	Function MovePLayer()					 #	
'## 	Moves Player and checks outer boundaries #	
'#################################################
Function MovePLayer()
	
	If KeyDown(KEY_LEFT) And Not KeyDown(KEY_RIGHT)
			Direction = 0 ' set direction to 0. Going Left
			PlayerX:-2 ' Minus 2 from Players X position to move him left
	ElseIf KeyDown(KEY_RIGHT) And Not KeyDown(KEY_LEFT)
			Direction = 1 ' set direction to 1. Going Right
			PlayerX:+2 ' Add 2 to the players X position to move him right
	End If
	
	If PlayerX-32 <=0 ' Boundary checks to prevent our Player Jumping out the screen
		PlayerX:+2
	ElseIf PlayerX >= 800-64 
		PlayerX:-2
	End If
End Function

'##########################################################
'### Function CheckIfPlayerCollideWithTile()			  #
'### Checks to see if the player has collided with a tile #
'### Checks also if the Player is falling                 #
'##########################################################
Function CheckIfPlayerCollideWithTile()
'#Region 
	Select Direction
		Case 1
		If Jump = 0
			If Map[PlayerX/32+1, PlayerY/32] = 1 ' If we put the players X&y position within the map array and divide them by 32
				PlayerX:-2                       ' which is the size of the player and the tiles, we are able to determine which
			EndIf								 ' tile the Player is on or near. if we have a +1 in PlayerX/32+1 or PlayerY/32+1		
		EndIf									 ' it just means we are checking the tiles next to the player. so if we add a +1		
		Case 0									 ' to PlayerY/32 we are checking the tile under the players feet.
		If Jump = 0								 ' In this we are checking the tiles to the right and left and if they = 1 (Tile is present)			
			If Map[PlayerX/32, PlayerY/32] = 1   ' then we stop the player from moving.
				PlayerX:+2
			End If
		EndIf
	End Select
		
'#End Region 

	If Falling = 1 ' If falling = 1 we minus 3.2 from the players Y position making him fall.
		PlayerY:+3.2
		If Map[PlayerX/32,PlayerY/32+1] = 1 ' While he's falling if we check to see if a tile is underneath and if there is
			
			If (PlayerY Mod 32.0) <= 6.4 'checks to see if player is close to top of tile if not keep falling
			                             ' 6.4 is twice the falling distance of 3.2 
				PlayerY = PlayerY - (PlayerY Mod 32) 'subtract the remainder to obtain exact start of tile
				Jump = 0                        ' We stop falling. We reset Jump to 0 and CanJump to 1 and also reset the JumpHeight
				Falling = 0
				CanJump = 1
				JumpHeight = 5.5
			EndIf
		EndIf
	End If

	If Not Map[PlayerX/32+1,PlayerY/32+1] And Not map[PlayerX/32,PlayerY/32+1]  
								' This is used seperately and does nothing apart from enabling me to use the "else bit"
                                ' left of player as well as right of player needs to be checked against 
                                ' the tile so it wont fall of the middle of the tile.
							    ' If there's nothing under the players feet we start falling but only if we're not jumping
		If Jump = 0
			Falling = 1
		EndIf
	End If
End Function

'##############################################
'### Function DoJump()                        #
'### Makes our player jump                    #
'##############################################
Function DoJump()
	If KeyHit(KEY_SPACE) And CanJump = 1 ' If we hit the space button and CanJump = 1
		Jump = 1 ' We enable Jump
		CanJump = 0 ' We Disable CanJump. Can't jump while jumping 
	End If
	
	If Jump = 1 ' If Jump is enabled
		PlayerY:-JumpHeight ' we minus JumpHeight from Players Y Position
		JumpHeight:-Gravity ' We minus Gravity from JumpHeight 
		If JumpHeight <=-1.0 Or PlayerY < 32' If JumpHeight <= -1.0  and reached the top tile
			Falling = 1 ' We beging to fall by setting Falling to 1
		EndIf
	End If
	
	
End Function

'########################################
'### Function DrawMap()                 #
'### We Draw the Map to screen          #
'########################################
Function DrawMap()
	For Local x:Int = 0 Until MAPWIDTH ' we loop until MapWidth
		For Local y:Int = 0 Until MAPHEIGHT ' We loop until MapHeight
			Select Map[x,y] ' We select the data stored in the MapArray
				Case 1 ' if it = 1
					DrawImage Tiles , x*32 , y*32 , 0 ' we draw the tiles to there corresponding position
			End Select
		Next
	Next
End Function

'#######################################################
'### Function ReadLevelData()            			   #
'### We read the data stored in the defdata statements #
'#######################################################
Function ReadLevelData()
	For Local y:Int = 0 Until MAPHEIGHT' We loop through the Y position first until MapHeight
		For Local x:Int = 0 Until MAPWIDTH ' We Loop Until MAPWIDTH
			Local data:Int  ' Setup a local variable to store the data in
			ReadData data ' We read the data from the defdata statements in to the data variable
			Map[x,y] = data ' we assign the data in the data variable to our MapArray
		Next
	Next
End Function

'Function getX:Int(x:Int)
'   Return sizeX * x '+ offsetX
'End Function
'
'Function getY:Int(y:Int)
'   Return sizeX * y '+ offsetX
'End Function


Function getX:Int(x:Int)
   Return 32 * x '+ offsetX
End Function

Function getY:Int(y:Int)
   Return 32 * y '+ offsetX
End Function

DefData 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1
DefData 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
DefData 1,0,0,0,0,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1
DefData 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1


Jesse, DUDE :) You just fixed my platform code worries. :)

I don't fully understand why it works and if you could explain the workings of it I would appreciate it. :)

What i gather from it is that PlayerY mod 32 returns the remainder of PlayerY being divided by 32. And if it is <= 6.4 which is the top of the tile it detects a collision.

If I'm wrong could you explain it please.

Thanks again dude. :)

@dabz

Hey, that bitshifting looks cool. I don't understand it but it looks cool. :)

You are right.
and for the rest(its true when you are less than 6.4 into the tile):
lets assume you are falling to a tile, the tile is at y = 128. you are at position 127, you have to add 3.2 to go to the next position. if you add 3.2 you get y = 130.2 that is below the top of the block. to find out how much you are of the top of the block you get the remainder of division by 32(size of tile) wich in this case will give you 2.2. you subtract 2.2 from where you are and will give you the top of the tile wich is 128. ;)

hope you understand this. I don't thik I am the best at explaining it. maybe somebody can explain it to you better.

I have never made a game like this but I have little experience manipulating tiles. maybe one of this days I will have time to start one(work, you know).

@Dabz - Your getpixel routine is very interesting! I don't know if you could use it for large scrolling worlds, where sprites are moving around on the virtual world outside the area that is rendered, but I like your concept, I may do something with that at some point. Very cool! Thanks for sharing the concept! :)