platform tile collision help

BlitzMax Forums/BlitzMax Beginners Area/platform tile collision help

jkrankie(Posted 2008) [#1]
i'm a bit stick with this platform tile thing, and i can't understand why the following produces such weird results.
normally i'm loading in a level from a file, but i've changes this so that it runs as-is.

basically, the little white square doesn't do what it ought to and i wondered if any of you lot could help me make it work properly.


SuperStrict

'make level
Local tileArray:Int[10, 8] ;

For Local i:Int=0To 9
	For Local o:Int=0 To 7
		If i=0 Or i=9
			tileArray[i,o]=1
		Else If o=0 Or o=7
			tileArray[i,o]=1
		Else
			tileArray[i,o]=0
		End If
	Next
Next
tilearray[4,4]=1
tilearray[5,4]=1

'variables
Graphics 640, 480, 0, 60
Local tilesize:Int = 64
Local x:Float = 2 * tileSize, y:Float = 2 * tileSize
Local xVel:Float = 0
Local falling:Int = True
Local gravity:Float = 0.1
Local yVel:Float = 0
Local hit:Int = False

While Not KeyHit(KEY_ESCAPE) 
	For Local i:Int = 0 To 9
		For Local o:Int = 0 To 7
'draw tiles			
			If tileArray[i, o] = 0
				SetColor 0, 100, 255
				DrawRect i * tilesize, o * tilesize, tilesize, tilesize
			Else If tileArray[i, o] = 1
				SetColor 255, 0, 0
				DrawRect i * tilesize, o * tilesize, tilesize, tilesize
			End If
'wall collisions		
'left
			If rectsOverlap(i * tileSize, o * tileSize, tileSize, tileSize, x, y, 1, 19) And tileArray[i, o] = 1
				If x > (i * tileSize) 
					x = (i * tileSize) + 65
				End If
			End If
'right
			If rectsOverlap(i * tileSize, o * tileSize, tileSize, tileSize, x + 20, y, 1, 19) And tileArray[i, o] = 1
				If x + 20 > (i * tileSize) 
					x = (i * tileSize) - 22
				End If
			End If
'bott
			If rectsOverlap(i * tileSize, o * tileSize, tileSize, tileSize, x + 20, y + 20, 1, 1) And tileArray[i, o] = 1
				If falling = True
					If y + 20 > o
						falling = False
						yVel = 0
						y = (o * tileSize) - 20
					End If
				End If
			End If
'top
			 If rectsOverlap(i * tileSize, o * tileSize, tileSize, tileSize, x, y, 1, 1) And tileArray[i, o] = 1
				If falling = True
					If y > o
						hit = True
						yVel = -yVel
						y = (o * tileSize) + 65
					End If
				End If 
			End If
'collide only with tile 0
			If hit = False
				If rectsOverlap(i * tileSize, o * tileSize, tileSize, tileSize, x, y, 20, 20) And tileArray[i, o] = 0
					falling = True
				End If
			End If
		Next
	Next
	hit = False
	
'move player	
	If KeyDown(KEY_LEFT) x:-2
	If KeyDown(KEY_RIGHT) x:+2
	If KeyHit(KEY_UP) And falling = False
		yVel:-6
		falling = True
	End If
		
	If falling = True
		yVel:+gravity
	Else
		yVel = 0
	End If
	y:+yVel
	
	SetColor 255, 255, 255
	DrawRect x, y, 20, 20
	
	Flip;Cls
Wend

Function rectsOverlap:Int(x1:Float, y1:Float, w1:Float, h1:Float, x2:Float, y2:Float,  ..
					  w2:Float,h2:Float)
	If x1 > (x2 + w2) Or (x1 + w1) < x2 Then Return False
	If y1 > (y2 + h2) Or (y1 + h1) < y2 Then Return False
	Return True 
End Function



cheers
charlie


Jesse(Posted 2008) [#2]
I don't know what you are doing. Your code is a bit confusing. Why are you adding 65 and subtracting 20 for x and for y on collition? you are not stoping the jump on collition. You yust have it move around the obstacle. is that what you really want to do?
can you explain in detail what it should do?

if you need help trying to understand stuff you should look around the forum there are quite a few sample programs you can look at. I'll post a couple of links maybe they can help you.
http://www.blitzmax.com/Community/posts.php?topic=71890#804268
http://www.blitzmax.com/Community/posts.php?topic=75339#843433


Czar Flavius(Posted 2008) [#3]
You really need to use named constants instead of those numbers, and changing the order of drawing and processing user input will stop the square from going beserk when you try to move right into the wall.


jkrankie(Posted 2008) [#4]
what i'm trying to do is just get the basics for collision detection in a simple platform game. are there any for idiots style guides for this?

Cheers
Charlie


tonyg(Posted 2008) [#5]
Jump and Run
Look at Tutorial 2 specifically for collisions.


Amon(Posted 2008) [#6]
Try this code which shows platform collision.

Thanks go to TonyG, Jesse and others for their help in getting it working.

Just run it in blitzmax.

SuperStrict

Graphics 800 , 600

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 
	
	DrawRect PlayerX, PlayerY, 32, 32
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
					DrawRect x * 32, y * 32, 32, 32
			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, 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, 0, 0, 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



jkrankie(Posted 2008) [#7]
cool, thanks guys.

Cheers
Charlie