Advice for 'player' in a FPS

Blitz3D Forums/Blitz3D Programming/Advice for 'player' in a FPS

Boiled Sweets(Posted 2006) [#1]
How do people recommend a 'player' / object is setup in a first person type game.

In qoob we have a sphere with a camera at the top of it as our player. Graviy is always applied to the player.

However the problem with this is when the 'player' is near an edge they kinda slip of the slide. In fact they can move over the edge slightly then they start to slip off.

How do pro games setup their player? It would easier if the player was a box (or rectangle) but then we cannot use the Blitz collisions....


Ross C(Posted 2006) [#2]
I use a combination of a linepick straight down and blitz collisions. I only apply gravity, if the linepick length a certain distance.

I basically try not allow the blitz collisions to happen below the player, by stopping the gravity when the linepick has reached a certain distance. This distance must be greater than the players entity raduis though :o) Not much tho.


Boiled Sweets(Posted 2006) [#3]
Please excuse the messy test code - like this Ross?

Graphics3D 800,600,16,2

Const c_jumpspeed# = .3
Const c_gravity# = -.016

Global g_game_gravity# = 0
Global g_game_player_jumpspeed# = 0

ground = CreateCube()
ScaleEntity ground, 2,1,2
EntityColor ground, 0,0,255
EntityType ground, 1
EntityPickMode ground, 2

ground1 = CreateCube()
ScaleEntity ground1, 2,1,2
EntityColor ground, 0,0,255
EntityType ground, 1
EntityPickMode ground1, 2
PositionEntity ground1, -4, -4, 0
EntityColor ground, 0,255,0

player = CreateSphere()
PositionEntity player, 0,2,0
EntityColor player, 255,0,0
EntityType player, 2


light=CreateLight()
PositionEntity light, 0, 3, -7
TurnEntity light,45,45,0

cam =  CreateCamera()
PositionEntity cam, -3, 3, -15
PointEntity cam, player
CameraZoom cam,1.6

While Not KeyHit(1)

	If KeyDown(203) MoveEntity player,-.1,0,0
	If KeyDown(205) MoveEntity player,.1,0,0
	If KeyDown(200) MoveEntity player,0,0,.1
	If KeyDown(208) MoveEntity player,-0,0,-.1
	
	If KeyHit(30)
		g_game_player_jumpspeed# = c_jumpspeed#
		g_game_gravity# = c_gravity#
	EndIf
	
	;DebugLog "jumping = " + g_game_player_jumpspeed#
	g_game_player_jumpspeed# =  g_game_player_jumpspeed# + g_game_gravity#
	TranslateEntity player,0, g_game_player_jumpspeed#,0

	If LinePick(EntityX#(player), EntityY#(player), EntityZ#(player), 0, -1, 0) > 0
		g_game_player_jumpspeed# =0
		g_game_gravity# = 0
	Else
		g_game_gravity# = c_gravity#
	EndIf
	
	UpdateWorld	
	RenderWorld

	Text 10,10, "player position " + EntityX#(player) + " " + EntityY#(player) + " " + EntityZ#(player)
	Text 10,30, "linepick        " + LinePick(EntityX#(player), EntityY#(player), EntityZ#(player), 0, -1, 0)
	Text 10,50, "distance        " + EntityDistance#(player, ground)

	Flip

Wend



octothorpe(Posted 2006) [#4]
Or use a cylinder instead of a sphere?


Boiled Sweets(Posted 2006) [#5]
but the collision system does sphere to poly not cylinder to poly.

In fact try the code above - there is a slight problem and that is the ball (player) sometimes moves into the ground a little.

Any thoughts any one?


WolRon(Posted 2006) [#6]
There IS the MeshesIntersect command...


Boiled Sweets(Posted 2006) [#7]
But the MeshesIntersect command is slow!

quote from the manual...

"This is a fairly slow routine - use with discretion... "

I really would appreciate if some one could tell me the BEST way to do this. BEST = fastest & most reliable.

How do you get the linepicks length?


Dreamora(Posted 2006) [#8]
The only fast way is sphere collision (box is quite useless for non-cube stuff so its basically usefull for levels and especially buildings).

In your code above, you don't use collision so far, as adviced.

I didn't have many problems with collision yet and when I had them, then normally because the collision response was not suited for he geometry I tried to apply it to.


Boiled Sweets(Posted 2006) [#9]
Well 50% say don't use collisions and 50% say don't use! HELPFUL!

Of course perhaps the way to prevent (or to limit) the sliding over the edge is to use ellipsoid collisions and set the entityradius to 0.5, 2 to make a taller, thin player with a separate sphere on top (head) that houses the camera and set the collisions with the head sphere so that it cannot pass through the ceiling / walls and the bottom (body) sphere cannot pass through the floor.

ARGH!


Damien Sturdy(Posted 2006) [#10]
Have you tried changnig the collision response type?

There's one that says sliding, and one thats only half-sliding. IM not sure, but i think that one prevents you from sliding down? :)

The other thing to stop you from sliding off edges is to only apply gravity when the player has not collided with the floor.


Boiled Sweets(Posted 2006) [#11]

There's one that says sliding, and one thats only half-sliding. IM not sure, but i think that one prevents you from sliding down? :)


But this will cause a player to be possible stuck over the edge! NOT GOOD!

The other thing to stop you from sliding off edges is to only apply gravity when the player has not collided with the floor.


But imagine a sphere half off the edge, it IS in contact with the floor - therefore gavity will be applied and over it goes. This is not good.


jfk EO-11110(Posted 2006) [#12]
The sliding problems is well known. Using the linepick and only apply gravity may solve the problem in some cases, but not ever time, because this may lead to some kind of flipflop state: one frame it's applied, next frame it's not because the linepick reaches the limit only ever second time, or maybe every third, forth etc, which may result in jittering gravity behaviour when standing on a slope.

There is a method that may look like a hack , but it could work well:

Do a linepick against the ground, as described
apply simple gravity only when one of the following conditions are true:
- pickedNX, NY and NZ signal a totally even ground
- pickedNX, NY and NZ signal a steep slope (here you can define the angle that is required to start sliding!)
- nothing was picked, player is free falling.

when pickedNX etc signal there is a flat slope where you don't want the player to slide, do this instead:

(all movement controls are already done here)
store X,Y,Z
apply gravity
updateworld()
store new X,Y,Z
position player at old_x, y ,old_z


Boiled Sweets(Posted 2006) [#13]
jfk EO-11110

any change of some example code?

I'm amazed there hasn't been a clear example in the past.


Shambler(Posted 2006) [#14]

But imagine a sphere half off the edge, it IS in contact with the floor


Don't forget to use the radius parameter when you are doing the linepick, make it 1/2 the diameter of the sphere to minimise problems when the player moves off an edge.


Damien Sturdy(Posted 2006) [#15]

But imagine a sphere half off the edge, it IS in contact with the floor - therefore gavity will be applied and over it goes. This is not good.



No, if it IS in contact with the floor then gravity will NOT be applied :)

Make the sphere smaller also so you cant tell your about to slip :)

Also,

The problem with the only-apply-gravity-when-not-in-contact method is that you may be able to attach yourself to the side of an object.


Boiled Sweets(Posted 2006) [#16]
Please try the example code I have posted above - it works pretty well without using collisions but imagine the player jumps - gravity is applied and sometimes the player is moved into the floor.

How to prevent this. PLEASE SOMEONE AMEND THE CODE AND REPOST.


jfk EO-11110(Posted 2006) [#17]
Not much sourcecode to show. Just try what I said, you may print pickedNX, pickedNY and pickedNZ to the screen during testing, to get feeling about what slopes you want to filter out from sliding.


Boiled Sweets(Posted 2006) [#18]
My world doesn't have slopes (yet). Its just built of cubes.

The code above works apart from the gravity pulls the player into the ground a little.


Ross C(Posted 2006) [#19]
My code is the same as Jfk's idea. I have an angle the player starts sliding at. I know what your saying though, as i've played the game :o) The problem of the entity sometimes sinking into the ground is a pain. I still have it.

I'll dig out the code i use for controlling the character.


Ross C(Posted 2006) [#20]
Ok, i've looked at your code. You linepick is the same distance as your entityradius. You should change the linepick to be just a little longer.

About the un-evenness of the landing. What you could do is this. You translate the gravity downwards. Check the linepick has hit something. If it has, set the player to the Y co-ord of the PickedY() + the length of the linepick.


Ross C(Posted 2006) [#21]
Try this:

The entity should rest at the same point all the time. Try not to put slopes in ;o) It should handle them ok actually.

Graphics3D 800,600,16,2

Const c_jumpspeed# = .3
Const c_gravity# = -.016

Global g_game_gravity# = 0
Global g_game_player_jumpspeed# = 0

ground = CreateCube()
ScaleEntity ground, 2,1,2
EntityColor ground, 0,0,255
EntityType ground, 1
EntityPickMode ground, 2

ground1 = CreateCube()
ScaleEntity ground1, 2,1,2
EntityColor ground, 0,0,255
EntityType ground, 1
EntityPickMode ground1, 2
PositionEntity ground1, -4, -4, 0
EntityColor ground, 0,255,0

player = CreateSphere()
PositionEntity player, 0,2,0
EntityColor player, 255,0,0
EntityType player, 2


light=CreateLight()
PositionEntity light, 0, 3, -7
TurnEntity light,45,45,0

cam =  CreateCamera()
PositionEntity cam, -3, 3, -15
PointEntity cam, player
CameraZoom cam,1.6

Global pick_length# = 1.1 ; slightly larger than the entityraduis

While Not KeyHit(1)

	If KeyDown(203) MoveEntity player,-.1,0,0
	If KeyDown(205) MoveEntity player,.1,0,0
	If KeyDown(200) MoveEntity player,0,0,.1
	If KeyDown(208) MoveEntity player,-0,0,-.1
	
	If KeyHit(30)
		g_game_player_jumpspeed# = c_jumpspeed#
		g_game_gravity# = c_gravity#
	EndIf
	
	;DebugLog "jumping = " + g_game_player_jumpspeed#
	g_game_player_jumpspeed# =  g_game_player_jumpspeed# + g_game_gravity#
	TranslateEntity player,0, g_game_player_jumpspeed#,0

	If LinePick(EntityX#(player), EntityY#(player), EntityZ#(player), 0, -pick_length, 0) > 0
		g_game_player_jumpspeed# =0
		g_game_gravity# = 0
		PositionEntity player,EntityX#(player,True),PickedY()+pick_length,EntityZ(player,True),True
	Else
		g_game_gravity# = c_gravity#
	EndIf
	
	UpdateWorld	
	RenderWorld

	Text 10,10, "player position " + EntityX#(player) + " " + EntityY#(player) + " " + EntityZ#(player)
	Text 10,30, "linepick        " + LinePick(EntityX#(player), EntityY#(player), EntityZ#(player), 0, -2, 0)
	Text 10,50, "distance        " + EntityDistance#(player, ground)

	Flip

Wend



Vorderman(Posted 2006) [#22]
Posted example + code for you here -
http://www.blitzbasic.com/Community/posts.php?topic=57283


Ross C(Posted 2006) [#23]
Isn't using real physics a bit overkill? Looks nice tho :o)


Vorderman(Posted 2006) [#24]
Isn't using real physics a bit overkill?


See my answer in the other thread.