Jumping again

Blitz3D Forums/Blitz3D Programming/Jumping again

Ruz(Posted 2004) [#1]
I have been trying to get jumping working in my level properly. I tried various methods from the code archives and got a bit lost , but tried using line pick . I found it to be very slow and jerky .

I ended using entity collided to determine if you were still attached to the floor and if so you are able to jump.
This works really well

What I want to know is how to determine if you are collided only with the floor, not the walls.

Problem is now you can climb the walls by pressing jump.
I did work around this by separating the walls from the floor, but its a real pain.


Shambler(Posted 2004) [#2]
You need to check the collision normals, specifically the CollisionNY component.

I'm suprised a line pick didn't work.

I use line pick since it immediately removes your jumping when touching the wall problem plus that single line pick can be used for things like crouching/knowing if we can jump or not/knowing when we have hit the floor after a fall, and knowing if the triangle under the player is too steep to stand on.

Oh, and knowing WHAT we are standing on :)

LinePick, its the command that keeps on giving.


fredborg(Posted 2004) [#3]
If CollisionNY()>0.9
I Can Jump!
End If


Ruz(Posted 2004) [#4]
Yeah i am not sure why linepick behaved the way it did. i may look in to it again soon.

Its also didn't like to work when walking up slopes, you just ground to a halt.


Thanks for that shambler and fredborg, I will look into it later today .
But its valentines day and the missus needs me he he


Ross C(Posted 2004) [#5]
Hey Ruz, i wrote this a wee while ago as an example. It works pretty well. It's a wee bit messy and uses linepicks. Only short ones tho. If you keep them small, they are pretty fast.

Spacebar to jump and left and right to turn, and up and down to move forward and back. The code basically linepicks down and check the length of the pick. If it return <0.95, then the player has hit the ground. The minimum distance the pick returns, must be roughly the same as the players entity radius.

Try it out.

;linepick example by RossC

Graphics3D 800,600
SetBuffer BackBuffer()


Global camera=CreateCamera()
Global light=CreateLight()
Global player=CreateCone()
EntityType player,1
EntityRadius player,1
EntityColor player,50,70,255
PositionEntity player,0,0.5,0

PositionEntity camera,0,2,-6

Global tex=CreateTexture(64,64,1+8)
SetBuffer TextureBuffer(tex)
For loop=0 To 3000
	Color Rnd(190,255),Rnd(190,255),Rnd(190,255)
	Rect Int(Rnd(0,63)),Int(Rnd(0,63)),1,1
Next
Color 255,255,255

SetBuffer BackBuffer()

Global plane=CreatePlane()
EntityType plane,2
EntityColor plane,200,100,120
EntityTexture plane,tex
EntityPickMode plane,2

Global cube=CreateCube()
PositionEntity cube,0,1,10
EntityPickMode cube,2
EntityType cube,2

Global cube1=CreateCube()
PositionEntity cube1,0,3,12
EntityPickMode cube1,2
EntityType cube1,2

Global cube2=CreateCube()
PositionEntity cube2,0,5,14
EntityPickMode cube2,2
EntityType cube2,2

Global cube3=CreateCube()
PositionEntity cube3,0,7,20
ScaleEntity cube3,4,0.2,4
EntityPickMode cube3,2
EntityType cube3,2


Global cube4=CreateCube()
PositionEntity cube4,-2,9,14
EntityPickMode cube4,2
EntityType cube4,2

Global cube5=CreateCube()
PositionEntity cube5,-4,11,12
EntityPickMode cube5,2
EntityType cube5,2

Global cube6=CreateCube()
PositionEntity cube6,-6,13,10
EntityPickMode cube6,2
EntityType cube6,2

Global cube7=CreateCube()
PositionEntity cube7,0,13,20
ScaleEntity cube7,4,0.2,4
EntityPickMode cube7,2
EntityType cube7,2

Global sphere=CreateSphere(10)
ScaleEntity sphere,10,1,10
EntityPickMode sphere,2
EntityType sphere,2
PositionEntity sphere,-2,0,19

Collisions 1,2,2,2; set up collisions between the ground and the player

Global jump_force#
Global jump_flag=0; set jump flag to 'no jump'
Global gravity#=0.9; set gravity value

While Not KeyHit(1)

	
	LinePick(EntityX(player,True),EntityY(player,True),EntityZ(player,True),0,-30,0); do a linepick straight down form the players location
	
	If jump_flag=0 Then
		If EntityY#(player,True)-PickedY()>1.05 Then; WARNING. THIS NUMBER MUST BE SLIGHTLY LARGER THAN THE PLAYERS ENTITYRADIUS.
		; ABOVE. if the players y position is greater than a distance of 1.05, then make the player fall.
		; Since the players entity radius is 1, This number must be slightly greater than 1, so that the collision
		; system doesn't work.
			jump_flag=1; set jump flag to jump
			jump_force=0.02; set jump force to 0.02. You cannot set this to 0. It must always be slightly more
		End If
	End If


	If KeyHit(57) And jump_flag=0 Then; if user presses spacebar
		jump_flag=1; set jump flag to 'jump'
		jump_force=0.4; set jumping force. make larger for higher jump
	End If
		
	
	If KeyDown(200) Then MoveEntity player,0,0,0.1
	If KeyDown(208) Then MoveEntity player,0,0,-0.1
	If KeyDown(203) Then TurnEntity player,0,1,0
	If KeyDown(205) Then TurnEntity player,0,-1,0	
	
	If jump_flag=1 Then; if jump flag set then 'jump'
		update_jump()
	End If
	update_camera()
	
	UpdateWorld
	RenderWorld
	Text 0,0," Press Space to jump. Arrow keys to move!"
	;DebugLog(" pickedy="+PickedY())
	Flip
Wend
End

Function update_camera()
	RotateEntity camera,EntityPitch(player),EntityYaw(player),EntityRoll(player); make the camera equal to the rotations of the camera
	PositionEntity camera,EntityX(player),EntityY(player)+2,EntityZ(player); position the camera at the x and z pos of the player
	MoveEntity camera,0,0,-7; move the camera back from the player by 7 units
	PointEntity camera,player
End Function

Function update_jump()

	jump_force=jump_force*gravity; apply gravity to the jumping force

	MoveEntity player,0,jump_force,0; move the player
	If jump_force>0 And jump_force<0.05 Then; when players upward speed reaches alomost zero, reverse it
											; make smaller to keep player in the air for longer
		jump_force=jump_force*-1; reverse the jumping force
		gravity=gravity+(2*(1-gravity)); turn gravity around
	End If
	If jump_force<-0.5 Then jump_force=-0.5; stop the player from falling to quick
	If EntityCollided(player,2) Then; if the player has collided with the ground
		If EntityY(player,True)-PickedY()<=1 Then; WARNING. THIS NUMBER MUST BE THE SAME AS THE PLAYER'S ENTITYRADIUS
			jump_force=0; reset the jumping force
			jump_flag=0; reset jump flag back to zero (not jumping)
			gravity=gravity-(2*(gravity-1)); reset gravity
		End If
	End If
End Function



jfk EO-11110(Posted 2004) [#6]
I double that, a short distance linpick is the best way.

p=linepick(x,y,z,0,-.91,0,0); assuming your player is 1.8 blitz units tall.
if p<>0 then jump

collision will prevent climbing up walls in the same time. plus you can check pickedNX etc. to limit the legal slope.


Ruz(Posted 2004) [#7]
I tried that rossc , had a few problems. it did work , but it wasn't very smooth and occasionally the character leapt in to outer space for some reason ( in my demo at least)yours works fine obviously
its probably just somethung silly I have done.
I will try again tomorrow.
Thanks for that too jfk. I squirrel way all these code snippets and try my best to resolve the issues
you know you have
linepick(x,y,z,0,-.91,0,0)
could you then say
If PickedY(entity)>1 then blahh


jfk EO-11110(Posted 2004) [#8]
?
well, something like

picnic=linepick(entityX(Player,1),entityY(Player,1),entityZ(Player,1),0,-.91,0,0)

if picnic<>0 ; picnic has the entity handle or 0
 pnx#=pickedNX() ; gives normals of last pick action
 pny#=pickedNY()
 pnz#=pickedNZ()
 surf=PickedSurface() ; use this for various footstep sounds
 if keydown(any) then  ; also add a check for pnx, pny pnz here
   your jump procedure
 endif
endif


text the values of pnx etc to the screen to see how this works. I don't remember exactly right now, some values between 0 and 1.0 representing the normals or picked face angles.


Ruz(Posted 2004) [#9]
Hey i kind of understand that ,I will look at it further tomorrow.
pickedNY()seems like a very handy command

but for my situation isn't it just PickedY() that i need?
ie if the line pick for the floor( PickedY())is true then my jump flag is =1

I am at the stage where little things are starting to bug me.
Like you solve one problem and up pops another
By seperating the walls from the floor i have ballsed up my line pick for the flexmesh.