Platform Collision Test with Pushable Objects

Blitz3D Forums/Blitz3D Programming/Platform Collision Test with Pushable Objects

Physt(Posted 2003) [#1]
I added pushable objects. It's almost right however you can sometime get stuck in moveable objects or at times quantum tunnel right through them. :( Has to be a simple fix. Any suggestions?


Arrow keys = move
left ctrl = jump
+ and - change viewport size

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

; Left Ctrl Key = jump 
; Arrow Keys = move 

;Include "viewport.bb"

Global viewportSize# = 1.0

; DEFINES
Global GRAVITY# = -0.0108
Global FLOOR_FRICTION# = .7
Global camera


Type actor
	Field mesh
	Field x#
	Field y#
	Field z#
	Field xvel#
	Field yvel#
	Field zvel#
	Field speed#
	Field isOnground#
	Field isOnObject#
End Type

frameTimer=CreateTimer(30)



WaitTimer(frameTimer) 




Global jumpheight# = 0.35
Global speed# = 0.07


Const numplatforms=6

Graphics3D 640,480,16,1

Gosub InitGame
Gosub GameLoop

End


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

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

grid1=CreateGridTexture(32,64,128)
grid2=CreateGridTexture(240,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(-20, -25 , 0, 10,1,40 , grid2)
platform(2)=CreatePlatform(-10,-30, 10,10,1,10 , grid2)
platform(3)=CreatePlatform(-5,-40, 15,10,5,10 , grid2)
platform(4)=CreatePlatform(-16,-20,  7,10,1,10 , grid2)
platform(5)=CreatePlatform(-16,-15, 15,5,1,5 , grid2)
platform(6)=CreatePlatform(6, -40, 12,5,20,5 , grid2)

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


playerActor.actor = New actor
playerActor\Mesh = player
playerActor\x# = 10
playerActor\y# = -20
playerActor\z# = 10
playerActor\speed# = 0.07 



AddCan(-13, -11, 17)
AddCan(-11, -11, 17)
AddCan(-10, -11, 17)
AddCan(-9, -11, 17)
AddCan(-8, -11, 17)
AddCan(8, 20, 14.6)

AddCan(13, -11, 17)
AddCan(11, -11, 17)
AddCan(10, -11, 17)
AddCan(9, -11, 17)
AddCan(8, -11, 17)
AddCan(8, 20, -14.6)


Return

.GameLoop

While Not KeyDown(1)
	WaitTimer(frameTimer) 
	AdjustViewport()
	ControlActor(playerActor)
	UpdateAllActorCollisions(playerActor)
	UpdateAllActors()
	UpdateWorld()
	PostUpdateAllActors()
	FollowCam(camera, player)
	
	RenderWorld
	;Text 10,10, EntityX(playerActor\mesh) + ", " + EntityY(playerActor\mesh) + ", " + EntityZ(playerActor\mesh)
	Flip
Wend
Return

Function adjustviewport()

		If KeyHit(74) Then
			ShrinkViewport(camera)
		End If 
	
		If KeyHit(78) Then
			EnlargeViewport(camera)
		End If 
End Function 

Function UpdateAllActors()

	For a.actor = Each actor
		a\yvel# = a\yvel# + GRAVITY#
		a\x# = a\x# + a\xvel#
		a\y# = a\y# + a\yvel# 
		a\z# = a\z# + a\zvel#
		a\xvel# = a\xvel# * FLOOR_FRICTION#
		a\zvel# = a\zvel# * FLOOR_FRICTION#
		PositionEntity a\mesh, a\x#, a\y#, a\z#
	Next

End Function 

; reset actor postions based on collision results. called after UpdateWorld()
Function PostUpdateAllActors()

	For a.actor = Each actor
		a\x# = EntityX(a\mesh)
		a\y# = EntityY(a\mesh)
		a\z# = EntityZ(a\mesh)
		;PositionEntity a\mesh, a\x#, a\y#, a\z#
	Next

End Function 

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

Function ControlActor(a.actor)

	dx=KeyDown(203)-KeyDown(205) ; left / right cursors
	dy=KeyDown(208)-KeyDown(200) ; up / down cursors
	TurnEntity a\mesh, 0, dx*3, 0
	
	TFormVector 0, 0, dy, a\mesh, 0
	a\xvel# = a\xvel# - (TFormedX() * a\speed#)
	a\yvel# = a\yvel# - (TFormedY() * a\speed#)
	a\zvel# = a\zvel# - (TFormedZ() * a\speed#)
	
	If a\IsOnground And KeyDown(29) Then 
		a\yvel# = a\yvel# + jumpheight#	
	End If
	
End Function 


Function UpdateAllActorCollisions(playerActor.actor)

	For a.actor = Each actor
		collide = CountCollisions (a\mesh)
		a\isOnground = False
		a\isOnObject = False
		If collide > 0
			For i = 1 To collide
				entity = CollisionEntity(a\mesh, i) 
				et = GetEntityType(entity)
				nx# = CollisionNX(a\mesh,  i)
				ny# = CollisionNY(a\mesh,  i)
				nz# = CollisionNZ(a\mesh,  i)
				If ny# = 1
					a\yvel# = 0
					a\yvel# = a\yvel# - GRAVITY#
					a\isOnground = True
					If et = 1 Then 	
						a\isOnObject = True
					End If 
				End If
				If ny# = -1 Then 
					a\yvel# = -a\yvel# * .5
				End If 
								
				entity = CollisionEntity(a\mesh, i) 
				If playerActor\isOnground = True And entity <> playerActor\mesh Then 
					If et = 1 Then 
					 	AddPlayerVelocityToActor(playerActor, entity)
					End If 
				End If 
				
			Next 
			
			
		End If 
	Next 


End Function 


Function FollowCam(camera, target)
	PositionEntity camera, EntityX(target), EntityY(target)+2.5, EntityZ(target)
	RotateEntity camera ,EntityPitch(target), EntityYaw(target)+4, EntityRoll(target)
	MoveEntity camera, 0, 0, -5.8
	PointEntity camera, target
End Function 


Function AddPlayerVelocityToActor(playerActor.actor, entity)


	; find the actor in the actor types with the entity that matches this one
	e.actor = First actor
	done = False
	While e <> Null And done = False
		If e\mesh = entity Then 
			If playerActor\isOnObject = False Then 
				e\xvel# = playerActor\xvel#
				e\zvel# = playerActor\zvel#
				done = True
			End If
		End If 
		e.actor = After(e)
	Wend 
	

End Function 


Function AddCan(argX#, argY#, argZ#)

	can.actor = New actor
	;can\Mesh = CreateCylinder(32)
	can\Mesh = CreateCube()
	FitMesh can\Mesh, -1, -1, -1, 2, 2, 2, False
	EntityType can\Mesh,1
	can\x# = argX#
	can\y# = argY#
	can\z# = argZ#

End Function 




Function ShrinkViewport(camera)
	If viewportSize#> .1 Then
		viewportSize#= viewportSize#- .1
		SetCameraViewport(camera)
	End If 
	

End Function


Function EnlargeViewport(camera)

	If viewportSize#< 1 Then
		viewportSize#= viewportSize#+ .1
		SetCameraViewport(camera)
	End If 
	
End Function 


Function SetCameraViewport(camera)

	; clear the screen
	
	width = GraphicsWidth()
	height = GraphicsHeight()
	newWidth = Int(GraphicsWidth() * viewportSize#)
	newHeight = Int(GraphicsHeight() * viewportSize#)
	xoffset = (width/2) - (newWidth/2) 
	yoffset = (height/2) - (newHeight/2)
	
	Color 32, 32, 32
	Flip
	Rect 0, 0, width, yoffset 
	Rect 0, yoffset+newHeight, width, height 
	Rect 0, yoffset, xoffset, newHeight
	Rect xoffset+newWidth, yoffset, width, newHeight
	Flip
	Rect 0, 0, width, yoffset 
	Rect 0, yoffset+newHeight, width, height 
	Rect 0, yoffset, xoffset, newHeight
	Rect xoffset+newWidth, yoffset, width, newHeight	

	CameraViewport camera, xoffset, yoffset, newWidth , newHeight	

End Function 

Function SetCameraFOV(Camera, FOV#) 
	CameraZoom Camera, 1.0 / Tan(FOV#/2.0) 
End Function 




Tin-cat(Posted 2007) [#2]
dig dig dig... >.>


<.<


Beaker(Posted 2007) [#3]
Can you stop bumping 4 year old threads?


Tin-cat(Posted 2007) [#4]
*sigh*
forums make me sad.. So much useful information gets lost and eventually expires.


Vertigo(Posted 2007) [#5]
I agree with Tin-Cat... there really should be a better way of archiving "useful" threads... Such as maybe a digg system or something on the forums where users can mark things as important?


fox95871(Posted 2009) [#6]
Expires how? They don't eventually get deleted do they?


Gabriel(Posted 2009) [#7]
I think this is still relevant:
Can you stop bumping 4 year old threads?

Except that this thread is now five years old.


fox95871(Posted 2009) [#8]
So what if it's old if it could help someone.


Gabriel(Posted 2009) [#9]
So what if it's old if it could help someone.

Every thread in the entire forum MIGHT help someone, but you can't bump them all constantly just in case. If someone needs help, they'll find it with the search function, read it and learn what they need. Bumping five year-old threads for no reason is just rude to the people who currently have an issue they want help with.