Platform Collision Test Code

Blitz3D Forums/Blitz3D Programming/Platform Collision Test Code

Physt(Posted 2003) [#1]
Hi All,

I've been playing with the Blitz collision system to see how it works and have come up with the little snippet you see below. My question is, does the collision and sliding in this feel correct for a platform style game?

I haven't added any time dependent code so it will run at different speeds on different machines. I'm not really concerned with the camera following, just the collision of the cylinder against the rest of the world. I'm just curious what others think. Thanks for your comments.

left alt key = jump
arrow keys = move

Ken

; platformer collision test
; Kenneth "Physt" Lemieux
; kenlem@...
; No Rights Reserved

;left alt key = jump 
;arrow keys = move 

Global gravity# = -0.02
Global speed# = 0.09

Global x# = 10 
Global y# = 50
Global z# = 10

Global platvel# = .025

Graphics3D 640, 480

GameLoop()

Function GameLoop()

	
	
	frametimer = CreateTimer(60)

	light=CreateLight()
	RotateEntity light,45,45,0

	camera=CreateCamera()
	PositionEntity camera, 10, 10, 10

	player = CreateCylinder(32)
	FitMesh player, -1, -1, -1, 2, 2, 2, False
	
	level = CreateCube()
	
	grid=CreateTexture(64,64,9)
	SetBuffer TextureBuffer(grid)	
	Color 32,64,128
	Rect 0, 0, 64,64, 1
	Color 255,255,255
	Rect 0, 0, 64,64, 0
	
	SetBuffer BackBuffer()


	ScaleTexture grid, .1, .1
	EntityTexture level, grid
	FitMesh level, -40, -40, -40, 80, 80, 80, True 
	FlipMesh(level)
	
	platform1 = CreateCube()
	FitMesh platform1, -10, -25, -10, 10, 1, 10, False
	EntityTexture platform1, grid

	
	
	platform2 = CreateCube()
	FitMesh platform2 , -10, -30,  10, 10, 1, 10, False
	EntityTexture platform2 , grid

	
	platform3 = CreateCube()
	FitMesh platform3 , -15, -35,  10, 10, 1, 10, False
	EntityTexture platform3 , grid
	
	platform4 = CreateCube()
	FitMesh platform4 , -16, -20,  7, 10, 1, 10, False
	EntityTexture platform4 , grid

	

	EntityType player,1
	EntityType level, 2
	EntityType platform1, 2
	EntityType platform2, 2
	EntityType platform3, 2
	EntityType platform4, 2

	Collisions 1, 2, 2, 2

	While Not KeyDown(1)
	
		; left
		If KeyDown(203) Then	
			TurnEntity player, 0, 3, 0
		End If 
	
		; right
		If KeyDown(205) Then
			TurnEntity player, 0, -3, 0 
		End If 
		
		; down
		If KeyDown(208) Then 
			TFormVector 0, 0, 1, player, 0
			xvel# = xvel# - (TFormedX() * speed#)
			yvel# = yvel# - (TFormedY() * speed#)
			zvel# = zvel# - (TFormedZ() * speed#)
		End If 
		
		; up arrow forward
		If KeyDown(200) Then 
			TFormVector 0, 0, 1, player, 0
			xvel# = xvel# + (TFormedX() * speed#)
			yvel# = yvel# + (TFormedY() * speed#)
			zvel# = zvel# + (TFormedZ() * speed#)
		End If 
		
		collide = CountCollisions (player)
		If collide > 0 Then 
			For i = 1 To collide
				NY# = CollisionNY(player,  i)
				If NY# > 0  Then	
					yvel# = yvel# - gravity#
					If KeyDown(29) Then
						yvel# = yvel# + .60
						If yvel# < .4 Then
							yvel# = 0
						End If
					End If  	
				Else If NY#=-1 Then 
					;yvel# = -yvel# * .5
					yvel# = 0
				End If
			Next  
		End If 
 		
		
		yvel# = yvel# + gravity#	
		x# = x# + xvel#
		y# = y# + yvel# 
		z# = z# + zvel#
		xvel# = xvel# * .7
		zvel# = zvel# * .7
		PositionEntity player, x#, y#, z#
		
		UpdateWorld()

			
		PositionEntity camera, EntityX(player), EntityY(player)+2, EntityZ(player)
		RotateEntity camera ,EntityPitch(player), EntityYaw(player)+4, EntityRoll(player)
		MoveEntity camera, 0, 0, -5
		PointEntity camera, player
		
		x# = EntityX(player)
		y# = EntityY(player)
		z# = EntityZ(player)
		
		RenderWorld()
		Flip
	Wend

End Function 




SSS(Posted 2003) [#2]
feels fine


EOF(Posted 2003) [#3]
Felt a little slow. I upped the speed a little and tweaked the gravity. Also, I have added an extra (small) platform and changed the colours to make them easier to spot !_!
Just about feels right for me now:

; platformer collision test
; Kenneth "Physt" Lemieux
; kenlem@...
; No Rights Reserved

; Left Ctrl Key = jump 
; Arrow Keys = move 

Global gravity# = -0.035
Global jumpheight#=0.85
Global speed# = 0.14
Global x#=10 , y#=50 , z#=10

Const numplatforms=5

Graphics3D 640, 480

Gosub InitGame
Gosub GameLoop

End


; *********
.InitGame
; *********
frametimer = CreateTimer(60)

light=CreateLight() : RotateEntity light,45,45,0
camera=CreateCamera() : PositionEntity camera, 10, 15, 10
player = CreateCylinder(32)
FitMesh player, -1, -1, -1, 2, 2, 2, False

grid1=CreateGridTexture(32,64,128)
grid2=CreateGridTexture(140,72,20)
SetBuffer BackBuffer()

level = CreateCube() : EntityTexture level, grid1
FitMesh level, -40, -40, -40, 80, 80, 80, True 
FlipMesh level

Dim platform(numplatforms)
platform(1)=CreatePlatform(-10,-25,-10,10,1,10 , grid2)
platform(2)=CreatePlatform(-10,-30, 10,10,1,10 , grid2)
platform(3)=CreatePlatform(-15,-35, 10,10,1,10 , grid2)
platform(4)=CreatePlatform(-16,-20,  7,10,1,10 , grid2)
platform(5)=CreatePlatform(-16,-15, 15,5,1,5 , grid2)

EntityType player,1 : EntityType level, 2
For d=1 To numplatforms
	EntityType platform(d), 2
Next
Collisions 1, 2, 2, 2
Return

; *********
.GameLoop
; *********
While Not KeyDown(1)

	WaitTimer frametimer
	
	dx=KeyDown(203)-KeyDown(205) ; left / right cursors
	dy=KeyDown(208)-KeyDown(200) ; up / down cursors
	TurnEntity player, 0, dx*3, 0
	
	TFormVector 0, 0, dy, player, 0
	xvel# = xvel# - (TFormedX() * speed#)
	yvel# = yvel# - (TFormedY() * speed#)
	zvel# = zvel# - (TFormedZ() * speed#)
	
	collide = CountCollisions (player)
	If collide > 0
		For i = 1 To collide
			NY# = CollisionNY(player,  i)
			If NY# > 0
				yvel# = yvel# - gravity#
				If KeyDown(29) ; left ctrl
					yvel# = yvel# + jumpheight#
					If yvel# < .4 Then yvel# = 0
				End If  
			EndIf
			If NY#=-1 Then yvel#=0
		Next  
	End If 

	yvel# = yvel# + gravity#
	x# = x# + xvel#
	y# = y# + yvel# 
	z# = z# + zvel#
	xvel# = xvel# * .7
	zvel# = zvel# * .7
	PositionEntity player, x#, y#, z#
	
	UpdateWorld

	PositionEntity camera, EntityX(player), EntityY(player)+2.5, EntityZ(player)
	RotateEntity camera ,EntityPitch(player), EntityYaw(player)+4, EntityRoll(player)
	MoveEntity camera, 0, 0, -5.8
	PointEntity camera, player
	x# = EntityX(player)
	y# = EntityY(player)
	z# = EntityZ(player)

	RenderWorld

	Flip
Wend
Return

Function CreateGridTexture(r,g,b)
	tex=CreateTexture(64,64,9)
	SetBuffer TextureBuffer(tex)
	Color r,g,b : Rect 0, 0, 64,64, 1
	Color 255,255,255 : Rect 0, 0, 64,64, 0
	ScaleTexture tex, .1, .1
	Return tex
End Function

Function CreatePlatform(x#,y#,z#,w#,h#,d#,tex)
	plat=CreateCube()
	FitMesh plat, x, y, z, w, h, d, False
	EntityTexture plat, tex
	Return plat
End Function



BlitzSupport(Posted 2003) [#4]
Apart from the camera view (separate issue really though), that feels just right to me. One bug though: walk under the first platform and jump, so you hit it. After that, you can't jump any higher :)


Physt(Posted 2003) [#5]
Right. Ignore the camera. I'm really just interested in the motion of the cylinder.

Which bit of code does the bug show up in, mine of the one Syntax posted? He has a small typo. If NY#=-1 Then yel#=0
should yvel#=0

I'm still working it to make it right. I don't think I understood that the collision normal is the normal of the collision and not the normal of the surface collided with.

Also, added in the correct constant for gravity but it then feels way to slow. I'll post and update when I can. Thanks for the feedback.


SSS(Posted 2003) [#6]
the collision normal is the normal of the polygon that the object colided with.


Physt(Posted 2003) [#7]
Thanks.


EOF(Posted 2003) [#8]
He has a small typo
Oops. Corrected :-)