FPSTEST and Stairs / Ramps

Blitz3D Forums/Blitz3D Programming/FPSTEST and Stairs / Ramps

I am a bit confused. I am using Rob Cumming's FPSTEST with a level I have exported to B3D from Cartography Shop 4.1. I am able to walk around the level and the collision with various objects and the flooris working but stairs and ramps are not working at all. The player (camera) just stops when it enounetrs a ramp or stairs. The code used to check for steps and flooring is:

;steps and floor collisions
pick=LinePick (EntityX(player),EntityY(player),EntityZ(player),0,-playerheight,0)
If pick
PositionEntity player,EntityX(player),PickedY()+playerheight#,EntityZ(player)
vy=0
EndIf
vy=vy-.2
vy=vy*0.9

HelP()

What sort of collision are you using for the player. I've noticed that if you aren't usine a sphere (or very close to a perfect sphere) that the players won't slide over tiny "rifts" in geometry. Of course also for stairs, each step must be smaller than the radius of the sphere.

OKay, here is my sample project. Any advice is greatly appreciated!

http://www.geocities.com/stevev4v/test.zip

Use WASD to walk around. :)

Thanks!

vy=vy*0.9
Why are you making y velocity increasingly smaller(or am I reading that incorrectly?)?

Not sure, as I said in my first post, this is a pared-down version of a demo released by Rob Cummings called FPSTEST. This version that is in my zip archive just has the shooting code removed as my game doesn't use any of that. I didn't develop this source and that is probably why I cannot understand why ramps and stairs do not work.

There are several methods you can use to implement gravity, and there are seeral examples, just like the on you mentioned. Personally I think this one is probably not the one with no complication. Maybe you better start with your very own system, so you always know what's going on.

Try something like

translateentity player,0,-.1,0

And of course, this is only a beginning, later you probably will use things like
grav#=-.1
...
while gameloop
if linepick(entityx(player),entityy(player),entityz(player),0,-player_height#,0)<> floor then
translateentity player,0,grav#,0
if grav#>-1.5 then grav=grav*1.1 ; acceleration while falling
else
grav#=-.1
endif
...

this way it will be easier to implement an independent jumping function, btw.

An other thing is, sometimes your level design doesn't fit with the desired Player collision radius, eg. the steps of a stairway could be too big. In such a case I'd suggest not to waste too much time and simply put an invisible (entityalpha) quad onto the stairs, so it will become a ramp.

;a;fps level, graphics & code by rob cummings (rob@...)
;job offers welcome as always
;
;you may learn from this and use the code however you may not
;re-use graphics without permission.
;unoptimised clean code, minimal comments


;framerate variables
Const FPS=85
Const debug=0

;collision variables
Global col_level=1,col_player=2,col_bullet=3

;player variables
Global pitch#,yaw#,mxspd#,myspd#,vx#,vy#,vz#,camera,player,gun,pick,gunsight,guntarget,hand

;other vars
Global firetex,firetexpos#,bob#,target,scorchsprite,plasmasprite,shockwavesprite,recoil#

Global cameraheight#=5	;height of player eyes
Global playerheight#=6		;height of collision sphere
Global playerradius#=3		;radius of collision sphere


xres=800:yres=600:depth=32:mode=1

Graphics3D xres,yres,depth,mode
HidePointer

;setup
camera=CreateCamera()
CameraRange camera,0.2,400
CameraFogMode camera,0


;hud
tex=LoadTexture("target.png",2)
TextureBlend tex,2
target=CreateSprite()
EntityTexture target,tex
EntityFX target,1
EntityOrder target,-1
EntityBlend target,3
EntityParent target,camera
MoveEntity target,0,0,12
EntityAlpha target,0.8

;player
player=CreatePivot()
hand=CreatePivot()
EntityParent hand,camera
MoveEntity hand,.8,-.8,.8

lite = CreateLight(1) ; change this to 2 or 3 to see different lights 
LightRange lite,15000

LightColor lite,255,255,255

;level
level=LoadAnimMesh("testlevel1.b3d")

;level collisions
EntityType level,col_level,1
ScaleEntity level,.03,.03,.03

;set up picking - this is because shooting and stair climbing needs pickable geometry. You can use picks for other stuff too
ent = level ; specify your level
While ent
	EntityPickMode ent,2
	ent = NextChild(ent)
Wend




;other collisions
EntityType player,col_player
EntityRadius player,playerradius,playerradius/2
Collisions col_player,col_level,2,2

PositionEntity player,0,10,0
PositionEntity level,0,0,0
ResetEntity player


;mainloop with standard timing code
period=1000/FPS
time=MilliSecs()-period
While Not KeyHit(1)
	Repeat
		elapsed=MilliSecs()-time
	Until elapsed

	ticks=elapsed/period
	tween#=Float(elapsed Mod period)/Float(period)

	For k=1 To ticks
		time=time+period
		If k=ticks Then CaptureWorld

		;basic game tasks
		UpdateWorld
		UpdatePlayer

		
	Next

	RenderWorld
	
	;hit spacebar to save a screenshot
	If KeyHit(57) n=n+1 : SaveBuffer(BackBuffer(),n+".bmp")
	
	Flip
Wend
End


Function UpdatePlayer()



	
	;look
	mxspd=MouseXSpeed()*0.25
	myspd=MouseYSpeed()*0.25
	MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
	pitch=pitch+myspd
	yaw=yaw-mxspd
	If pitch<-90 Then pitch=-90
	If pitch>90 Then pitch=90
	RotateEntity camera,pitch,yaw,0
	RotateEntity player,0,yaw,0
	
	;movement
	If KeyDown(17)
		vz=vz+0.04
	ElseIf KeyDown(31)
		vz=vz-0.04
	EndIf
	vz=vz*0.9
	If KeyDown(30)
		vx=vx-0.04
	ElseIf KeyDown(32)
		vx=vx+0.04
	EndIf
	vx=vx*0.9	

	;steps and floor collisions
	pick=LinePick (EntityX(player),EntityY(player),EntityZ(player),0,-playerheight,0)
	If pick
		PositionEntity player,EntityX(player),PickedY()+playerheight#,EntityZ(player)
		vy=0
	EndIf
	vy=vy-.2
	vy=vy*0.9
	

		
	;move player pivot
	MoveEntity player,vx,0,vz
	TranslateEntity player,0,vy,0

	;move camera + player meshes smoothly
	PositionEntity camera,EntityX(player),EntityY(camera),EntityZ(player)
	TranslateEntity camera,0,(EntityY(player)-(EntityY(camera)-cameraheight))*0.1,0

		
End Function

Function NextChild(ent)
	If CountChildren(ent)>0
		Return GetChild(ent,1)
	EndIf

	Local foundunused=False
	Local foundent = 0, parent,sibling
	While foundunused=False And ent<>0
		parent = GetParent(ent)
		If parent<>0
			If CountChildren(parent)>1
				If GetChild(parent,CountChildren(parent))<>ent
					For siblingcnt = 1 To CountChildren(parent)
						sibling = GetChild(parent,siblingcnt)
						If sibling=ent
							foundunused = True
							foundent = GetChild(parent,siblingcnt+1)
						EndIf
					Next
				EndIf
			EndIf
		EndIf
		ent = parent
	Wend
	Return foundent
End Function

Fixed version up! the old version had bad code for setting up pickable geometry. This version solves the problem and adds a comment. I am also changing the original source to reflect this now...

:)

Oh yeah - thanks to beaker for the nextchild function which makes looping through children very easy.

Thanks VERY much! I really appreciate you taking the time to help me out. I really do. :)

Cheers.
Steve