Hi,
I am working on the player physics part of a game of mine and I recently started to rewrite that engine to use a "real" dark physics body instead of the character controller, which I had lots of trouble with to work the way I wanted.
So using my old Newton FPS engine that I wrote for the darkAI competition, I started to convert the newton code into DarkPHysics code for use with this new game.
However I have trouble with the acceleration and deceleration of the player body.
Here is my code:
` setup
Sync On
Sync Rate 60
Hide Mouse
Set Camera FOV 80.0
Set Camera Range 1, 2000
Color Backdrop RGB(67, 140, 165)
AutoCam Off
Phy Start
Phy Set Gravity 0, -98, 0
GoSub map_Load
` Player Engine
GoSub player_Setup
Do
` HUD
Set Cursor 0, 0
Print "Alone - Player Physics Engine v0.03"
Print
Print "FPS: ", Screen FPS()
Print
Print "WASD - Move"
Print "Mouse - Look around"
Print "Ctrl - Crouch (v0.2 only)"
Print "Space - Jump"
Print "Q - Lean Left (v0.2 only)"
Print "E - Lean Right (v0.2 only)"
Print
print "+------------------------------"
print "| DEBUG"
print "|------------------------------"
print "| Camera: ", Int(Camera Position X()), ", ", Int(Camera Position Y()), ", ", Int(Camera Position Z())
print "| Player: ", Int(Object Position X(player.ObjID)), ", ", Int(Object Position Y(player.ObjID)), ", ", Int(Object Position Z(player.ObjID))
Print "| "
print "| AccelX: ", AccellerationX#
print "| AccelZ: ", AccellerationZ#
print "+------------------------------"
` Player Engine
GoSub player_Update
Phy Update
Sync
Loop
Function FreeObj() : Repeat : Inc o, 1 : Until Not Object Exist(o)
EndFunction o
Function phyFreeMaterial() : Repeat : Inc id, 1 : Until Phy Get Material Exist( id ) = 0
EndFunction id
map_Load:
` Create a simple box and texture as floor
CLS RGB(128,128,128)
For x =0 To 5 : For y =0 To 5
Dot x*2, y*2, RGB(255,255,255)
Next : Next
Get Image 1, 0, 0, 10, 10
Make Object Box 1, 10000, 1, 10000 : Position Object 1, 0, -1, 0
Texture Object 1, 1 : Phy Make Rigid Body Static Box 1
` Add some dynamic boxes to jump on or push around
levels = 2 : xcount = 2 : zcount = 2 : size = 50
for l=0 to levels-1
for x=-xcount to xcount
for z=-zcount to zcount
boxId = freeobj()
make object cube boxID, size
position object boxID, (x*(size*2)), (l*(size*2)), (z*(size*2))
phy make rigid body dynamic box boxID
phy set rigid body mass boxID, 50
next z
next x
next l
` Make a stair like thingie
for x = 1 to 20
o = freeobj()
Make Object Box o, 100, 5, 25
Position Object o, -400, (x*5), (x*25)
Phy Make Rigid Body Static Box o
next
RETURN
player_Setup:
` Setup Player Array
Type tPlayer
Mass# as float
xAng# as float
yAng# as float
zAng# as float
xPos# as float
yPos# as float
zPos# as float
xSiz# as float
ySiz# as float
zSiz# as float
rSiz# as float
InitialWalkSpeed# as float
InitialJumpSpeed# as float
rotationSpeed# as float
jumpSpeed# as float
WalkSpeed# as float
cameraOffset# as float
moveX# as float
moveZ# as float
moveDirX# as float
moveDirZ# as float
CurrentVelocityX# as float
CurrentVelocityY# as float
CurrentVelocityZ# as float
leanRight_max as integer
leanLeft_max as integer
ObjID as integer
Material as integer
isRunning as boolean
isCrouching as boolean
isJumping as boolean
isOnGround as boolean
EndType
Global player As tPlayer
` Set Values
player.xpos# = -200
player.ypos# = 100
player.zpos# = -400
player.InitialWalkSpeed# = 100.0
player.rotationSpeed# = 3.0
player.cameraOffset# = 0.0
player.ysiz# = 50.0
player.rsiz# = player.ysiz#
player.mass# = 70.0
player.JumpSpeed# = 5000.0
` Make Player Material
player.Material = PhyFreeMaterial()
Phy Make Material player.Material, "Player"
Phy Set Material Dynamic Friction player.Material, 0.1
Phy Set Material Static Friction player.Material, 0.1
Phy Set Material Restitution player.Material, 0.1
Phy Build Material player.Material
` Make Player Object
player.ObjID = FreeObj()
Make Object Sphere player.ObjID, player.rsiz#
Hide Object player.ObjID
` Make Player Body
Phy Make Rigid Body Dynamic Sphere player.ObjID, player.Material
Phy Set Rigid Body Position player.ObjID, player.xpos#, player.ypos#, player.zpos#
Phy Set Rigid Body Mass player.ObjID, player.mass#
Phy Wake Up Rigid Body player.ObjID
RETURN
player_Update:
` Rotate Camera Using Mouse
player.xang# = WrapValue( ( player.xang# + (MouseMoveY()*player.rotationSpeed#) ) )
player.yang# = WrapValue( ( player.yang# + (MouseMoveX()*player.rotationSpeed#) ) )
If player.xang# <= 290 And player.xang# >= 180 Then player.xang# = 290
If player.xang# >= 70 And player.xang# <= 180 Then player.xang# = 70
` Movement Using WASD Keys
player.MoveX# = 0.00
player.MoveZ# = 0.00
If KeyState(17) Or KeyState(31) ` W and S - Forward and Backwards
player.moveDirX# = Sin( player.yAng# )
player.moveDirZ# = Cos( player.yAng# )
Inc player.MoveX#, player.MoveDirX# * ( KeyState(17) - KeyState(31) )
Inc player.MoveZ#, player.MoveDirZ# * ( KeyState(17) - KeyState(31) )
EndIf
If KeyState(30) Or KeyState(32) ` A and D - Left and Right
player.moveDirX# = Sin( player.yAng# + 90.0 )
player.moveDirZ# = Cos( player.yAng# + 90.0 )
Inc player.MoveX#, player.MoveDirX# * ( KeyState(32) - KeyState(30) )
Inc player.MoveZ#, player.MoveDirZ# * ( KeyState(32) - KeyState(30) )
EndIf
` Run With Shift Key
If KeyState(42)
player.WalkSpeed# = player.InitialWalkSpeed# * 3.0
player.isRunning = 1
Else
player.WalkSpeed# = player.InitialWalkSpeed#
player.isRunning = 0
EndIf
` Set Player Accelleration
length# = SQRT( (player.MoveX#^2) + (player.MoveZ#^2) )
player.MoveX# = player.MoveX# / length#
player.MoveZ# = player.MoveZ# / length#
player.CurrentVelocityX# = Phy Get Rigid Body Angular Velocity X( player.ObjID )
player.CurrentVelocityY# = Phy Get Rigid Body Angular Velocity Y( player.ObjID )
player.CurrentVelocityZ# = Phy Get Rigid Body Angular Velocity Z( player.ObjID )
goalVelocityX# = player.MoveX# * player.WalkSpeed#
goalVelocityZ# = player.MoveZ# * player.WalkSpeed#
`AccellerationX# = 2.0 * (goalVelocityX#-player.CurrentVelocityX#)
`AccellerationZ# = 2.0 * (goalVelocityZ#-player.CurrentVelocityZ#)
AccellerationX# = goalVelocityX#
AccellerationZ# = goalVelocityZ#
If AccellerationX# > 200.0 Then AccellerationX# = 200.0
If AccellerationX# < -200.0 Then AccellerationX# = -200.0
If AccellerationZ# > 200.0 Then AccellerationZ# = 200.0
If AccellerationZ# < -200.0 Then AccellerationZ# = -200.0
Phy Add Rigid Body Force player.ObjID, AccellerationX#, 0.0, AccellerationZ#, 1
` Spacekey to jump
AccelY# = 0.0
If KeyState(57) And KeyState57Pressed =0
KeyState57Pressed =1
player.xpos# = Object Position X( player.ObjID )
player.ypos# = Object Position Y( player.ObjID )
player.zpos# = Object Position Z( player.ObjID )
NULL = Phy Ray Cast All Shapes( player.xpos#, player.ypos#, player.zpos#, 0, -1, 0 )
dist# = Phy Get Ray Cast Distance()
If dist# < 5.0
AccelY# = ( player.jumpSpeed# - player.CurrentVelocityY# )
Phy Add Rigid Body Force player.ObjID, 0.0, AccelY#, 0.0, 1
EndIf
EndIf
If KeyState(57)=0 Then KeyState57Pressed =0
` Get Player Position
player.xpos# = Object Position X( player.ObjID )
player.ypos# = Object Position Y( player.ObjID )
player.zpos# = Object Position Z( player.ObjID )
` Update Player
player.xpos# = player.xpos# + player_LeanX#
player.zpos# = player.zpos# + player_LeanZ#
player.ypos# = player.ypos# + humancalc# + player_Crouch# + player.CameraOffset#
Rotate Camera player.xang#, player.yang#, player.zang#
Rotate Listener player.xang#, player.yang#, player.zang#
Position Camera player.xpos#, player.ypos#, player.zpos#
Position Listener player.xpos#, player.ypos#, player.zpos#
RETURN
If anyone have any ideas on how I can improve the acceleration and deceleration of the player, that would be great.
Basically, I want the player to instantly move at the speed given when a movement button is pressed, and when the movement button is released; instantly decelerate to 0.0 so the player halts.
And while I'm at it:
Anyone know how it would be possible to walk up stairs using the above code/method?
I found it hard to walk up the stair, because if the velocity is too high, the player will just bounce on the first stair step and fly over the stair. If it is too low the player is unable to move up the stair.
Thanks for your interest.
I allways afraided from a clowns. aww..