2d Platform Collisions

Blitz3D Forums/Blitz3D Programming/2d Platform Collisions

Genexi2(Posted 2004) [#1]
Oooooook, I wasnt exactly sure what forum to place this under (I was thinkin' it may be a lil' too much to put in the beginner's forum), so I slapped this under B3d since thats basically what I'm coding it in.

Anyway, I got back onto working this Metroid Clone (style of gameplay and all, making all the media myself here), and although my map editor is coming along fine (it could use a bazillion more things but I'll work on that later), I'm having problems with coding the game itself, basically the collision aspect.

My current setup is to have a Rectangular collision check for each side of my sprite (top, bottom, left, right) to check what actions should occur if a specific tile hits one of the collision rects and all, and well, this aint working to well.

For now I'm trying to get the collisions to work with 2 kinds of tiles, "block" tiles, and "diagonal" tiles (going at a 45 degree angle)....

For anyone who's interested in helping, heres the code :

AppTitle "Demo"
Graphics 640,480,0,2
Graphics 320,240,0,3

Global tiletext = 1

Global leftkey = KeyDown(203)
Global rightkey = KeyDown(205)
Global firekey = KeyHit(57)
Global jumpkey = KeyHit(31)

Global tilew = 16
Global tileh = 16
Global tilen = 16

Global tile = LoadAnimImage("tiles.png", tilew, tileh, 0, tilen)
;Global bground = LoadImage("bg2.png")
;Global fground = loadimage("fg.png")

Global mx
Global my
Global mz

Global gx
Global gy

Global mapx = 0
Global mapy = 0

Global mapdx# = 0
Global mapdy# = 0

Global mapsx = 40
Global mapsy = 30

Global mapox = 0
Global mapoy = 0

Global mouse1 = MouseDown(1)
Global mouse2 = MouseDown(2)
Global mouse3 = MouseDown(3)


Global filename 
Global configname

Dim map(mapsx, mapsy)



Type player
	Field x, y, dx#, dy#, jump
	; x = x pos, y = y pos, dx# = x velocity, dy# = y velocity, jump = flag to check jump status
End Type	


HidePointer



ClearALL()


CreatePlayer()
LoadMap()

SetBuffer BackBuffer()
While Not KeyHit(1)
	Cls
	
	If KeyHit(2)
		tiletext = -tiletext
	EndIf
	
	DrawMap()
	UpdatePlayer()
	
	
	
	Flip
Wend
	









Function CheckKeyboard()

	leftkey = KeyDown(203)
	rightkey = KeyDown(205)
	firekey = KeyHit(2)
	jumpkey = KeyHit(57)

	p.player = First player	
	
	If leftkey And p.player\dx > (-2)
		p.player\dx = p.player\dx - 0.05
	ElseIf rightkey And p.player\dx < (2)
		p.player\dx = p.player\dx + 0.05
	EndIf	
	
	
	If leftkey = 0 And rightkey = 0
		If Sgn(p.player\dx) = 1
			p.player\dx = p.player\dx - 0.1
		Else
			p.player\dx = p.player\dx + 0.1
		EndIf			 
	EndIf
	
	If jumpkey And p.player\jump = 1
		p.player\jump = 0
		p.player\dy = -4
	EndIf	



End Function




Function CreatePlayer()

	p.player = New player
	p.player\x = 160
	p.player\y = 120
	p.player\dx = 0
	p.player\dy = 1

End Function


Function UpdatePlayer()

	CheckKeyboard()
	
	p.player = First player
	

	
	Color 255,255,255 ;player
	Rect p.player\x-8, p.player\y-16,16,32
	
	Color 100,255,0 ; top collision
	Rect p.player\x-8, p.player\y-16,16,2,0
	
	Color 200,200,100 ; bottom collision
	Rect p.player\x-8, p.player\y+15,16,2,0 
	
	Color 150,150,150 ; left collision
	Rect p.player\x-8, p.player\y-15,2,30, 0
	
	Color 150,150,190 ; right collision
	Rect p.player\x + 6, p.player\y-15,2,30,0
	
	
	; move the player by its velocities
	p.player\x = p.player\x + p.player\dx
	p.player\y = p.player\y + p.player\dy
	 

	

	; This loops through all the tiles on the map and checks them against the player for collisions
	For y = 0 To mapsy 
		For x = 0 To mapsx 	
			If RectsOverlap(p.player\x-8, p.player\y-16,16,2,x*tilew, y*tileh, tilew, tileh) ;top collision rect
				If map(x,y) <> 0
				p.player\y = p.player\y+2
					p.player\dy = 0
				EndIf
		
			ElseIf RectsOverlap(p.player\x-8 , p.player\y+15,16,2,x*tilew, y*tileh, tilew, tileh) ;bottom collision rect
				If map(x,y) = 1
					 p.player\dy = 0
					 p.player\jump = 1
				EndIf	
			ElseIf RectsOverlap(p.player\x-8, p.player\y-15,2,30,x*tilew, y*tileh, tilew, tileh) ;left collision rect
				If map(x,y) = 3
					p.player\y = p.player\y-2
				Else If map(x,y) <> 0
					p.player\dx = 0
					p.player\x = p.player\x + 1	
				EndIf
			ElseIf RectsOverlap(p.player\x + 6, p.player\y-15,2,30,x*tilew, y*tileh, tilew, tileh) ;right collision rect
				If map(x,y) <> 0
					p.player\dx = 0
					p.player\x = p.player\x - 1	
				EndIf
				
				
			EndIf		
		Next
	Next
	
	
	If p.player\dy < 2 Then p.player\dy = p.player\dy + 0.1


End Function







Function DrawMap()


	
	For y = 0 To mapsy 
		For x = 0 To mapsx 	
			If map(x,y) <> 0
				DrawImage tile, ((x*tilew)-(mapx * tilew)), ((y*tileh)-(mapy * tileh)), map(x,y)-1
				
				If tiletext = 1
					Text tilew*x, tileh*y, map(x,y)
				EndIf
			EndIf
		Next
	Next

				
End Function







Function LoadMap()
	
		filename = OpenFile("test.gen2")
		mapsx = ReadInt(filename)
		mapsy = ReadInt(filename)
		tilew = ReadInt(filename)
		tileh = ReadInt(filename)
		tilen = ReadInt(filename)
		
		Dim map(mapsx, mapsy)
		
		For y = 0 To mapsy
			For x = 0 To mapsx	
				map(x,y) = ReadInt(filename) 
			Next
		Next	
		
End Function


Function ClearALL()
	Delete Each player  
End Function


End 


It's currently got alot of unused variables atm, but I'll get them to do their crap once I get this player collision handling down...
(then whenever I feel like it, do the impossible, AI pattern movements & collisions!)
(Note to self : Edit map file format to use bytes to save tile-frame's instead)

Oh yeah, I zipped the files up as well for anyone who wants to be able to run the thing (its only a 9k file) : www3.sympatico.ca/farmersxfive/blitz/demo.zip