Platform Collisions

BlitzMax Forums/BlitzMax Programming/Platform Collisions

Twinprogrammer(Posted 2012) [#1]
Hello,

I finished making my map editor(thanks to all of the people who helped me with my previous topic, Platform Issues...). Now, I'm putting the maps I made into my game and realized, I don't know how to detect map collisions. Can anyone tell me how to detect collisions from a map array(Like: Map[MapWidth, MapHeight]) ? Also, How would I be able to find out what the tile is(like a floor or empty space) ?

Last edited 2012


Nate the Great(Posted 2012) [#2]
so if you have an array set up as a grid and you have a way to access each block in that array (for instance you may have a function getblock:int(x,y) that turns x and y coords into a block type that is returned) so now you just need to check all blocks within a certain distance/box around your player because those are the blocks the player could be colliding with. Now you do a box-box (aabb) collision between your player and any solid blocks around it, if your players box and the block's box are overlapping, move them so they don't overlap. There may be a few issues you need to work out depending on player to block size ratio but this should be a good start and the issues that arrise have pretty obvious solutions. This is the system I am using right now at least! Hope it helped and I would be glad to clarify anything that isnt clear!


Twinprogrammer(Posted 2012) [#3]
Could you give a code example ?


Amon(Posted 2012) [#4]

SuperStrict

Graphics 800 , 600

Global Tiles:TImage = LoadImage("tile.png") 
Global Player:TImage = LoadImage("player1632.png") 

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

Global Map:Int[MAPWIDTH , MAPHEIGHT]

Global PlayerX:Float
Global PlayerY:Float

Global Player_Width:Int = 16
Global Player_Height:Int = 32

Global CheckPlayerPosition:Int = 0

Global Direction:Int = -1

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

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 
							   		
	For Local x:Int = 0 Until MAPWIDTH
		For Local y:Int = 0 Until MAPHEIGHT
			Select Map[x, y]
				Case 2
					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()					 #	
'## 	Moves Player and checks outer boundaries #	
'#################################################
Function MovePLayer()
	
	If KeyDown(KEY_LEFT) And Not KeyDown(KEY_RIGHT)
			Direction = 0
			PlayerX:-2
	ElseIf KeyDown(KEY_RIGHT) And Not KeyDown(KEY_LEFT)
			Direction = 1
			PlayerX:+2
	End If
	
	If PlayerX - 32 <= 0
		PlayerX:+2
	ElseIf PlayerX >= 800 - 32
		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 - Player_Width) / 32 + 1, PlayerY / 32]= 1
				PlayerX:-2
			EndIf
		EndIf
		If Jump = 1 and PlayerX >= 784 - 32
			If Map[(PlayerX - Player_Width) / 32 + 1, PlayerY / 32]= 1
				PlayerX:-2
			EndIf
		End If
		Case 0
		If Jump = 0
			If Map[(PlayerX + Player_Width) / 32, PlayerY / 32]= 1
				PlayerX:+2
			End If
		EndIf
	End Select
		
'#End Region 

	If Falling = 1
		PlayerY:+3.2
		If Map[(PlayerX + Player_Width) / 32, PlayerY / 32 + 1]= 1 or Map[(PlayerX - Player_Width * 2) / 32 + 1, PlayerY / 32 + 1]= 1
			
			If (PlayerY mod 32.0) <= 6.4
			                             
				PlayerY = PlayerY - (PlayerY mod 32) 
					
						Jump = 0                        
						Falling = 0
						CanJump = 1
						JumpHeight = 5.5
								
			EndIf
		EndIf
	End If
	
	If not Map[(PlayerX + Player_Width) / 32, PlayerY / 32 + 1]and not Map[(PlayerX - Player_Width * 2) / 32 + 1, PlayerY / 32 + 1]
		If Jump = 0
			Falling = 1
		End If
	End If
	
	
		
End Function

'##############################################
'### Function DoJump()                        #
'### Makes our player jump                    #
'##############################################
Function DoJump()
	If KeyHit(KEY_SPACE) and CanJump = 1
		Jump = 1
		CanJump = 0
	End If
	
	If Jump = 1
		PlayerY:-JumpHeight
		JumpHeight:-Gravity
		If JumpHeight <= - 1.0 or PlayerY < 32
			Falling = 1
		EndIf
	End If
	
	
End Function

'########################################
'### Function DrawMap()                 #
'### We Draw the Map to screen          #
'########################################
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()            			   #
'### We read the data stored in the defdata statements #
'#######################################################
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 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, 2, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1
DefData 1, 0, 1, 0, 1, 1, 0, 1, 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, 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


Hope this helps! to make it work you need to have a 16x32 image for the player and a 32x32 image for the tile.


Twinprogrammer(Posted 2012) [#5]
This works, but when the player goes out of the boundaries(Like jumping from too high of a distance), I get an array exception. Is there a way to fix
this ?


Amon(Posted 2012) [#6]
Yep! Just cap the players y position and do not allow it to go below 0.

If PlayerY <=0 Then PlayerY = 0

Last edited 2012


therevills(Posted 2012) [#7]
Over on the Monkey forum, Jesse posted this great article about platformers:

http://higherorderfun.com/blog/2012/05/20/the-guide-to-implementing-2d-platformers/


Twinprogrammer(Posted 2012) [#8]
Wow, that was a good article. Thanks for the help guys.