Code archives/Miscellaneous/Platform movement with slopes

This code has been declared by its author to be Public Domain code.

Download source code

Platform movement with slopes by mutantleg2010
Well i've been struggling for long to get some accurate slopes in games, somehow i just didn't feel the gravity in the castle demo was good enough for a game, dunno.

(It's still a WIP though as a third person perspective game would need to change movement based on the camera angle (like in mario 64) and other features but apart from that it works nicely )

OK so one sacrifice is to eliminate sticking to walls it uses two update worlds, but i doubt that will be a huge performance hit. There are also some slight errors but nothing that could hurt gameplay significantly
; slopes for 3d platformers
; by mutantleg (mutantleg@gmail.com)
; 2010 jan 21

Graphics3D 640,480,32,2


SetBuffer BackBuffer()
;--------------------------------------------

cam = CreateCamera()
MoveEntity cam, 0,15,-20
TurnEntity cam, 20, 0, 0

light = CreateLight(1)


wrld = CreateCube()
ScaleMesh wrld, 30, 1, 8
RotateMesh wrld, 0,0, 5
EntityType wrld, 2

wall = CreateCube()
ScaleMesh wall, 1, 10, 8
MoveEntity wall, 6, 0,0
EntityAlpha wall, 0.5
EntityType wall, 2
EntityColor wall, 64, 12, 128

bigslp = CreateCube()
ScaleMesh bigslp, 5, 5, 8
RotateMesh bigslp, 0, 0, 45
MoveEntity bigslp, -6, -3 ,0
EntityColor bigslp, 0, 128, 128
EntityType bigslp, 2

;make sure polygon picking mode is turned on as well for meshes to collide with 
EntityPickMode wrld, 2, True
EntityPickMode bigslp, 2, True
EntityPickMode wall, 2, True


p1 = CreateCube()
EntityType p1, 1
EntityColor p1, 255,0,0
MoveEntity p1, 0, 15,6


Collisions 1,  2, 2, 2


;you can often get in trouble because by default blitz thinks youre using integers
;so i just pre declare some floats first here
grav# = 0.0
ny# = 0.0
dist# = 0.0
onground = 0

;-------------------------------main loop start
Repeat
;--------------------------------------





;get ground vector
pickground = LinePick(EntityX(p1), EntityY(p1), EntityZ(p1), 0, -3, 0)

;align to ground vector if found ground
If pickground <> 0 Then 
	AlignToVector p1, PickedNX(), PickedNY(), PickedNZ(),2
Else
	AlignToVector p1, 0, 1, 0, 2
EndIf


;move left/right (A D or arrows)
;note there is still a error if you move into the wall from a slope climbing up
; (just move right without jumping to see what i mean)
;but linepicking before moving would might result in that you wont be able to climb some slopes
;so im not sure how to fix it

If KeyDown(32) Or KeyDown(205) Then
	 MoveEntity p1, 0.4,0,0
EndIf

If KeyDown(30) Or KeyDown(203) Then
	 MoveEntity p1, -0.4,0,0
EndIf


;jumping (hold space)

If KeyDown(57) Then
	If onground = 1 Then grav = 0.75
EndIf

;limit height of jump if space not held down
If onground = 0 And grav > 0 And (Not(KeyDown(57))) Then
	grav = grav * 0.75
EndIf



UpdateWorld()

MoveEntity cam, (EntityX(p1) - EntityX(cam)) * 0.1, 0 ,0 

;apply gravity
TranslateEntity p1, 0, grav, 0

;update now at gravity -- so this is one disadvantage of blitz and updating all movement data all at once
;as we need a seperate vector for gravity and movement to not stick to walls (comment out one updateworld to see what i mean)
UpdateWorld() 


;note this check is actually for disabling a sliding collision 
;if you want sliding only the    If grav > -1.0 grav = grav - 0.03   part is needed
;its made this way cuz i wanted to do surfaces with different sliding velocity but i gave up on that
;check if gravity needs to be changed (luckily picking doesnt wait for updateworld)
picked = LinePick(EntityX(p1), EntityY(p1), EntityZ(p1),  0, -10 + grav, 0)

dist# = EntityY(p1) - PickedY() 

If (dist > 1.5) ;dont increase gravity if the ground isnt below this distance -- this value is the radius of the object with some trial and error tweaking
	If grav > -1.0 grav = grav - 0.03
	onground = 0
Else
	onground = 1
EndIf
;


;test if hit ground -- need to check collision vector y -- aka don't reset gravity if we only hit a wall
If CountCollisions(p1) > 0
	For i = 1 To CountCollisions(p1)
		ent = CollisionEntity(p1, i)
		If GetEntityType(ent) = 2 Then
			ny = CollisionNY(p1, i) 
			;0 means a completely vertical wall and 1 means a completely horizontal ground
			;so changing this value is changing when to slide -- so with 0.1 you wont slide on very steep surfaces either
			If   ny > 0.3
				grav = 0
			EndIf
		EndIf ;gettype
	Next 
EndIf

RenderWorld()

Text 16, 16, "Picked: " + picked + " pickedy " + PickedY()
Text 16, 32, "Dist: " + dist + "  p1 y " + EntityY(p1)
Text 16, 48, "Grav: " +grav + " onground " + onground + " ny " + ny
;Text  16,16, "p2 pos: [" + ox +"] [" + oy + "] [" + oz + "] "
;Text  16,32, "p2 new pos: [" + EntityX(p2) +"] [" + EntityY(p2) + "] [" + EntityZ(p2) + "] "

Flip()

Until KeyHit(1)
End
;-------------------------------main loop end

Comments

None.

Code Archives Forum