Hi Veron!
You may be having issues related to a lack of horizontal collision. I suspect that the problem your experiencing is being caused by reaching the surface when the surface height is between the camera and the point CameraHeight# below the camera, the equivalent of...
The code I've posted thus far has really only dealt with the issues of gravity and climbing, and has kept pretty narrowly to vertical issues. There's a lot more to movement. For example, in the code posted so far, once you jump you can move in mid-air - including changing direction. You need code that records direction and velocity at the time of the jump and which slows that horizontal velocity during the jump. No matter how fast you're going horizontally when your feet leave the ground, if you fall long enough, you'll end up going straight down.
You also need some overhead collision code. In the code I've posted, if you walk under the ramp you snap up on top of it. You need code to check for overhead objects.
In this code, there are platforms that you can jump or step between. The motion walking down the platforms is pretty smooth because the gravity code takes care of the height change, but walking up them, the camera just snaps to the new height. You need to write some code to graduate the height adjustment going up the platforms.
` Simple Gravity & Climbing Demo by Jane Doe 20/2/09.
set display mode 1024, 768, 32
sync on
sync rate 0
autocam off
hide mouse
hide light 0
set ambient light 100
set camera range 0, 0.01, 250.0
` Make textures.
ink rgb(255, 0, 0), 0
box 0, 0, 7, 7
RedTexture = 1
get image RedTexture, 0, 0, 7, 7
ink rgb(255, 255, 0), 0
box 0, 0, 7, 7
YellowTexture = 2
get image YellowTexture, 0, 0, 7, 7
ink rgb(0, 255, 0), 0
box 0, 0, 7, 7
GreenTexture = 3
get image GreenTexture, 0, 0, 7, 7
ink rgb(255, 0, 255), 0
box 0, 0, 7, 7
MagentaTexture = 4
get image MagentaTexture, 0, 0, 7, 7
ink rgb(128, 0, 255), 0
box 0, 0, 7, 7
PurpleTexture = 4
get image PurpleTexture, 0, 0, 7, 7
` Make the object array.
dim ObjectArray(4)
` Build area.
GroundObject = 1
make object box GroundObject, 20.00, 1.00, 20.00
texture object GroundObject, RedTexture
ObjectArray(0) = GroundObject
RampObject = 2
make object plain RampObject, 5.00, 15.00
texture object RampObject, YellowTexture
xrotate object RampObject, 60.0
position object RampObject, 2.10, 3.45, 0.00
ObjectArray(1) = RampObject
LadderObject = 3
make object box LadderObject, 1.00, 10.0, 0.50
texture object LadderObject, GreenTexture
position object LadderObject, -2.50, 5.00, 0.00
ClimbingZone = 4
make object box ClimbingZone, 1.00, 10.0, 2.50
texture object ClimbingZone, MagentaTexture
set object diffuse ClimbingZone, rgb(64, 0, 64)
set object emissive ClimbingZone, rgb(64, 0, 64)
set object ambience ClimbingZone, rgb(0, 0, 0)
set object specular ClimbingZone, rgb(128, 128, 128)
ghost object on ClimbingZone
set object cull ClimbingZone, 0
position object ClimbingZone, -2.50, 5.00, 0.00
CollisionSphere = 5
make object sphere CollisionSphere, 0.1
hide object CollisionSphere
BoxObject1 = 6
make object box BoxObject1, 2.5, 10.0, 2.5
texture object BoxObject1, PurpleTexture
position object BoxObject1, -7.50, -1.50, -7.00
ObjectArray(2) = BoxObject1
BoxObject2 = 7
instance object BoxObject2, BoxObject1
position object BoxObject2, -7.50, -2.50, -4.50
ObjectArray(3) = BoxObject2
BoxObject3 = 8
instance object BoxObject3, BoxObject1
position object BoxObject3, -7.50, -3.50, -2.50
ObjectArray(4) = BoxObject3
position camera 0, -5.75, 20.00, 6.00
point camera 0, -1.50, 2.00, 2.20
CameraHeight# = 1.5 ` This is effectively the distance from the bottom of the feet to the eyes.
Gravity# = 1.0
FirstCycle = 1
do
ProgramCycleTime = timer()
ElapsedProgramCycleTime# = (ProgramCycleTime - PreviousProgramCycleTime) / 1000.0
PreviousProgramCycleTime = ProgramCycleTime
rotate camera 0, camera angle x(0) + (mousemovey() / 2.0), camera angle y(0) + (mousemovex() / 2.0), 0.0
` If the "W" key is pressed, move forward.
if keystate(17) = 1 then move camera 0, 0.01
` If the "S" key is pressed, move backward.
if keystate(31) = 1 then move camera 0, -0.01
` If the space bar is pressed, jump.
if spacekey() = 1 and NowJumping = 0 and NowClimbing = 0
CurrentVelocity# = 7.5
NowJumping = 1
endif
` If the "Z" key is pressed and the camera is in the climbing zone, move up.
if keystate(44) = 1 and NowClimbing = 1
position camera 0, camera position x(0), camera position y(0) + 0.01, camera position z(0)
endif
` If the "X" key is pressed and the camera is in the climbing zone, move down.
if keystate(45) = 1 and NowClimbing = 1
position camera 0, camera position x(0), camera position y(0) - 0.01, camera position z(0)
` Make sure we don't go too far down.
if camera position y(0) < GroundHeight# + CameraHeight#
position camera 0, camera position x(0), GroundHeight# + CameraHeight#, camera position z(0)
endif
endif
` Keep the camera within the bounds of the playground.
if camera position x(0) > 10.0 then position camera 0, 10.0, camera position y(0), camera position z(0)
if camera position x(0) < -10.0 then position camera 0, -10.0, camera position y(0), camera position z(0)
if camera position z(0) > 10.0 then position camera 0, camera position x(0), camera position y(0), 10.0
if camera position z(0) < -10.0 then position camera 0, camera position x(0), camera position y(0), -10.0
if NowClimbing = 0 and FirstCycle = 0 then gosub GravityProc
position object CollisionSphere, camera position x(0), camera position y(0), camera position z(0)
NowClimbing = object collision(CollisionSphere, ClimbingZone)
text 10, 10, "W key to move forward."
text 10, 30, "Space Bar to jump."
if NowClimbing = 1
text 10, 50, "Z key to climb up."
text 10, 70, "X key to climb down."
endif
sync
FirstCycle = 0
loop
end
` ==================================================================================================
GravityProc:
` Determine which surface is highest under the camera.
SurfaceHeight# = -10000.0
for Counter = 0 to 4
ObjectNumber = ObjectArray(Counter)
Altitude# = 10000.0 - intersect object(ObjectNumber, camera position x(0), 10000.0, camera position z(0), camera position x(0), -10000.0, camera position z(0))
if Altitude# = 10000.0 then Altitude# = -10000.0
if Altitude# > SurfaceHeight# then SurfaceHeight# = Altitude#
next Counter
` Apply gravity for this programme cycle.
` Note: Earth gravity (1G) is 9.76 metres per second per second.
dec CurrentVelocity#, 9.76 * Gravity# * ElapsedProgramCycleTime#
` Check for terminal velocity (assuming that terminal velocity is 50 metres per second per second).
if CurrentVelocity# < -50.0 then CurrentVelocity# = -50.0
` Determine drop length and end Y position for this programme cycle.
` Note that the drop length may be going up.
DropLength# = CurrentVelocity# * ElapsedProgramCycleTime#
DropPositionY# = camera position y(0) - CameraHeight# + DropLength#
if DropPositionY# > SurfaceHeight#
` If the drop position is higher than the surface height, raise or lower the camera the drop
` length.
position camera 0, camera position x(0), camera position y(0) + DropLength#, camera position z(0)
else
` If there is a collision, position the camera/character.
position camera 0, camera position x(0), SurfaceHeight# + CameraHeight#, camera position z(0)
CurrentVelocity# = 0.0
NowJumping = 0
endif
return
Note that I changed the way the height determinations are done. This is more practical when you have a bunch of them to do.
Keep working at it. Add horizontal collision and address these other issues. I’ve no doubt you’ll have your movement system looking sharp in no time!
- Jane