I'm a little stuck. I've been combining the two examles of this and the one that comes with DBPro. and when you fire you can't move at all for a moment, then the bulelt goes winging off. I've attached the code I'm working on below. Oh and MY jumping is very jerky. Can anyone help please?
`Main Source File
remstart
=========================================================================================
* A basic sliding collision algorythm. A joint product of the efforts of G-Man and *
* Lost In Thought. Feel free to use this code as you wish, but credits would cerainly *
* be appreciated. *
* *
* Before you ask, no, there isn't any jump code... We have to let something for you to *
* figure out! :-) *
* *
* Revision History: *
* 1.) Initially coded 12-26-04 GM/LIT *
* *
* Known Bugs/Issues: *
* 1.) No Jumping *
* 2.) Ocasional glitches when falling *
=========================================================================================
remend
`First set up some of the screen particulars
Sync On : Sync Rate 0
Autocam Off : Hide Mouse
fog off
`Set up the Camera's view frustrum
Set Camera Range 0.1, 50000
`this global variable holds the player's movement rate
`in quants per second. This equates roughly to inches
`per second
Global MovePerSec As Float
global jumping as byte
`set the movement rate to 20 feet per second
MovePerSec = 240
`This next variable determines If a reticle will be drawn on the screen
Global UseReticle As Boolean
`we'll set it to the default value, switching the reticle on. A value of
`0 would switch it off
UseReticle = 1
`This variable holds the height from the floor to the player's eye
`this is again in quants, with 1 quant equating roughly to an inch
Global EyeHeight As Integer
`set the eye height to 64 inches
EyeHeight = 64
`This next variable set the mouse's sensitivity for the mouse look
Global MouseSens As integer
`we'll set the default mouse sensitivity value to 3. Valid values range from 1
`(very sensitive)upwards growing less sensitive with each increase
MouseSens = 3
`This variable is used to determine if the character is jumping or falling
Global Airborn as Boolean
`This variable contains the speed at which the player will fall in inches per second
Global Gravity as Float
Gravity = 256
`now we load the map. Swap the name of your map file in here
LoadMap:
gosub _load_game
gosub _setup_game
Load Object "SacredPlace.dbo", 1
`we set collision to polygons here. Normally collsion is set to boxes or spheres
`but because we are gouing to be walking around inside the map, we'd be colliding
`all of the time using either of those methods because the collision horizon is set
`to the model's maximum extents
Set Object Collision To Polygons 1
`we will create an Object to do our colliding for the Camera. We'll use a sphere and position it around
`the Camera. Because its polygons all face out, it won't be rendered by the Camera.
`normally, this would be your player model
`first let's create a global variable to hold the Object number
Global ColliderObjNum As Integer
`...and fill it
ColliderObjNum = 50
`now we'll create the actual collider Object
Make Object Sphere ColliderObjNum, EyeHeight/2
`set up its collision method
Set Object Collision On ColliderObjNum
Hide Object ColliderObjNum
`now we'll place the Camera
Position Camera 0, 0, 0, 0
`then place the collider Object around the Camera
Position Object ColliderObjNum, 0, 0, 0
`at this point we'll set the ambient light level so we can see where we're going
`this will probably need to be tweaked to your liking
Set Ambient Light 25
Fog Color RGB(128,128,128)
Fog Distance 5000
Fog On
`this is our main loop
MainLoop:
Do
`call our sliding collision function
gosub _control_gunandbullet
gosub _control_enemies
if Airborn=0 then CheckCollision()
if Airborn=1 then Fall()
`render our scene
Sync
Loop
End
_control_gunandbullet:
rem Control gun firing
if mouseclick()=1 and bullet=-50
bullet=100
play sound GunSnd
position object BulletObj,camera position x(0),camera position y(0),camera position z(0)
rotate object BulletObj,camera angle x(0),camera angle y(0),0
move object BulletObj,0.2
rem *ADDCODE* TUT9B
endif
rem Control life of bullet
if bullet>0
rem If bullet collides with BSP world
if bulletimpact=1
rem End bullet on wall
position sound ImpactSnd,object position x(BulletObj), object position y(BulletObj), object position z(BulletObj)
play sound ImpactSnd
bulletimpact=0
bullet=0
else
rem Move bullet
dec bullet
move object BulletObj,0.5
endif
rem *ADDCODE* TUT9C
rem Bullet dies
if bullet=0
rem *ADDCODE* TUT9D
endif
else
rem Gun recharge phase
if bullet>-50 then dec bullet
endif
return
_control_enemies:
rem Variable for finding closest enemy
cdist#=9999.99
rem Handle enemies within world
for ene=EneObj to EneObj+4
rem If enemy alive
if object visible(ene)=1
rem Kill this enemy
killenemy=0
rem Move enemy on a slow curve for appearance of intelegence
if object angle z(ene)=0
yrotate object ene,wrapvalue(object angle y(ene)+2)
endif
if object angle z(ene)=1
yrotate object ene,wrapvalue(object angle y(ene)-2)
endif
if object angle z(ene)=2
move object ene,0.05
else
move object ene,0.02
endif
rem Switch direction of curve based on a random value
if rnd(200)=1 then zrotate object ene,rnd(1)
rem Handle gravity for enemy
position object ene,object position x(ene),object position y(ene)-0.01,object position z(ene)
rem Work out angle and distance between enemy and player
dx#=camera position x(0)-object position x(ene)
dy#=camera position y(0)-object position y(ene)
dz#=camera position z(0)-object position z(ene)
dist#=abs(sqrt(abs(dx#*dx#)+abs(dy#*dy#)+abs(dz#*dz#)))
viewa#=wrapvalue(atanfull(dx#,dz#))
obja#=wrapvalue(object angle y(ene))
if viewa#>180 then viewa#=viewa#-360
if obja#>180 then obja#=obja#-360
rem If enemy 'facing player' and 'on similar height' and 'close', zoom in
if abs(viewa#-obja#)<10.0 and abs(dy#)<5.0 and dist#<30.0
if object angle z(ene)<>2 then play sound EnemygunSnd
rotate object ene,0,viewa#,2
set object speed ene,200
else
set object speed ene,100
endif
rem If enemy gets too close to player, player dies
if dist#<2.0
play sound DieSnd
for x=0 to 100
point camera object position x(ene), object position y(ene)+(x/20.0), object position z(ene)
sync
next x
restart=1
killenemy=1
endif
rem If enemy and bullet in same space, enemy dies
if bullet>0
if object collision(BulletObj,ene)>0
play sound EnemydieSnd
play object ene,26,26+50
set object speed ene,100
bulletimpact=1
endif
endif
rem Closest enemy emits the enemy sound
if dist#<cdist#
cdist#=dist#
position sound EnemySnd,object position x(ene), object position y(ene), object position z(ene)
position sound EnemygunSnd,object position x(ene), object position y(ene), object position z(ene)
position sound EnemydieSnd,object position x(ene), object position y(ene), object position z(ene)
endif
rem Hide enemy when die animation over
if object frame(ene)>26+25 and object visible(ene)=1
killenemy=1
endif
if killenemy=1
hide object ene : dec aliensleft
killenemy=0
endif
rem If enemy alive ENDIF
endif
next ene
return
_control_stats:
rem *ADDCODE* TUT9A
return
_setup_game:
rem Setup sky model
set object SkyObj,1,0,0,0,0,0,0
scale object SkyObj,200000,200000,200000
rem Setup gun for player
lock object on GunObj
scale object GunObj,2,2,4
rotate object GunObj,270,0,0
position object GunObj,1,-1,2
disable object zdepth GunObj
rem Create object for bullet
BulletObj=3303 : make object cube BulletObj,0.1
rem Create simple sprite based crosshair
sprite 1,(screen width() / 2)-16,(screen height() / 2)-16, CrossHairImg
set sprite 1,0,1
rem Place enemies throughout world and set BSP collision for them
aliensleft=0
restore EnemyPosData
for ene=EneObj to EneObj+4
read ex#,ey#,ez#
position object ene,ex#,ey#,ez#
yrotate object ene,180 : fix object pivot ene
inc aliensleft
next ene
rem Start the enemy presence sound
loop sound EnemySnd
scale listener 0.1
rem Trigger player initialisation
restart=1
return
_load_game:
rem Load BSP world and sky model
SkyObj=102 : load object "modelsskysky01.x",SkyObj
rem Load model for gun
GunObj=202 : load object "modelsgungun.x",GunObj
rem Load models for enemies
EneObj=1010
for ene=EneObj to EneObj+4
load object "modelsenemyH-Alien Psionic.dbo",ene
loop object ene,0,25
next ene
rem Load all sounds
GunSnd=1 : load sound "soundsgun9.wav",GunSnd
ImpactSnd=2 : load 3dsound "soundsimpact.wav",ImpactSnd
DieSnd=3 : load sound "soundsdie.wav",DieSnd
EnemySnd=11 : load 3dsound "soundsenemy.wav",EnemySnd
EnemygunSnd=12 : load 3dsound "soundsgun5.wav",EnemygunSnd
EnemydieSnd=13 : load 3dsound "soundsenemydie.wav",EnemydieSnd
rem Load images
FireImg=100 : load image "imagesfire.bmp",FireImg
CrossHairImg=200 : load image "imagescrosshair.bmp",CrossHairImg
return
rem Enemy position data within level
EnemyPosData:
data -9.27,9.98,-2.78
data -16.54,-0.22,19.18
data 2.0,9.0,25.0
data -2.0,-9.0,25.0
data 2,4.0,10.0
return
Function Fall()
`This function handles falling. During a fall, the user can not control
`the character's actions until they land.
`We'll start by collecting the collider's current position
ox#=Object Position x(ColliderObjNum)
oy#=Object Position y(ColliderObjNum)
oz#=Object Position z(ColliderObjNum)
`We'll calculate how far we're going to fall based upon the frame rate
Delta#=Gravity/Screen FPS()
`We'll figure out the Y value we're falling to
ny#=EyeHeight + (oy#-Intersect Object(1, ox#, oy#, oz#, ox#, -1000, oz#))
`We check if the player is done falling
If (oy#-ny#)<=Delta#
`If the difference between the old Y position and the new Y position is equal to or
`less than the amount we are going to let the player fall this iteraction, then
`the fall is done.
`Position the camera and collider at the final position
Position Object ColliderObjNum, ox#, ny#, oz#
Position Camera 0, ox#, ny#, oz#
`Shut off the AirBorn flag
Airborn = 0
Else
`Since the player is not done falling, we'll drop the player's Y value
`according to the calculated amount
Position Object ColliderObjNum, ox#, oy#-delta#, oz#
Position Camera 0, ox#, oy#-delta#, oz#
EndIf
`we'll draw the reticle during the fall
If UseReticle = 1
circle screen width()/2,screen height()/2,8
EndIf
EndFunction
Function CheckCollision()
`This is the meat of the sliding collision routine. It is based on a simple premise.
`any move the player makes through the map will be composed of an X and Z component.
`If the player attempts to make a move that causes a collision with the map, we will
`seperate the requested move into these two components and give them the portion of
`the move that does not create a collsion condition. If neither portion of the move
`can be allowed, the player will be simply halted. This final case could only occur
`If the player's move was exactly aligned with either the X or Z axis.
Moving = 0
`Begin Routine
`First we need to record the current Camera position before attempting the move
ox#=Object Position x(ColliderObjNum)
oy#=Object Position y(ColliderObjNum)
oz#=Object Position z(ColliderObjNum)
`next we need to know how fast the machine is running so that
`we can move our player at a consistent speed
Delta#=MovePerSec/Screen FPS()
`Because the collider could pass through a wall without triggering a collision
`condition If the allowable move is too large, we need to ensure that the delta
`pacing formula does not allow it to exceed the collider's size.
If Delta#>EyeHeight
Delta#=EyeHeight
EndIf
`accept the user's input
Rotate Object ColliderObjNum, Object Angle x(ColliderObjNum)+(MouseMovey()/MouseSens),Object Angle y(ColliderObjNum)+(MouseMovex()/MouseSens),0
`this code constitutes the mouselook functionality
If Object Angle x(ColliderObjNum)>90 then XRotate Object ColliderObjNum,90
If Object Angle x(ColliderObjNum)<-90 then XRotate Object ColliderObjNum,-90
cx#=Object Angle x(ColliderObjNum)
cy#=Object Angle y(ColliderObjNum)
cz#=Object Angle z(ColliderObjNum)
Rotate Camera cx#, cy#, cz#
Rotate Object ColliderObjNum, cx#, cy#, cz#
If UseReticle = 1
circle screen width()/2,screen height()/2,8
EndIf
k$=upper$(Inkey$())
`This code constitutes the movement functionality
If UpKey()=1 or k$="W"
`move the player forward
XRotate Object ColliderObjNum,0
Move Object ColliderObjNum,Delta#
XRotate Object ColliderObjNum,cx#
EndIf
If DownKey()=1 or k$="S"
`move the player backwards
XRotate Object ColliderObjNum,0
Move Object ColliderObjNum,0-Delta#
XRotate Object ColliderObjNum,cx#
EndIf
If LeftKey()=1 or k$="A"
`strafe left
XRotate Object ColliderObjNum,0
YRotate Object ColliderObjNum,cy#-90
Move Object ColliderObjNum,Delta#
YRotate Object ColliderObjNum,cy#
XRotate Object ColliderObjNum,cx#
EndIf
If RightKey()=1 or k$="D"
`strafe right
XRotate Object ColliderObjNum,0
YRotate Object ColliderObjNum,cy#-90
Move Object ColliderObjNum,0-Delta#
YRotate Object ColliderObjNum,cy#
XRotate Object ColliderObjNum,cx#
EndIf
if spacekey()=1
` EyeHeight = EyeHeight + 10
oy# = ((oy# + ny#) + eyeheight)+ 10
Airborn=1
jumping=1
endif
`with that done, we'll record the collider's new X/Z position
nx#=Object Position x(ColliderObjNum)
nz#=Object Position z(ColliderObjNum)
`retrieve the floor height at the new position
ny#=EyeHeight + (oy#-Intersect Object(1, nx#, oy#, nz#, nx#, -1000, nz#))
`there appears to be an inconsistancy in the way DBPro registers collsions
`in certain circumstances. The following code remedies that situation
`To fix the west wall problem check to see if the distance to collision
`is less than half the collider's size and if it is then nx# = ox#
if nx# > ox#
newxwest# = intersect object(1,nx#,ny#,nz#,nx#+(EyeHeight/2),ny#,nz#)
endif
if newxwest# > 0
if newxwest# < object size x(ColliderObjNum)/2
nx# = ox#
endif
endif
`now that we're done moving the collider around, we'll check to see if there's
`a collision
if object collision(ColliderObjNum,0) <> 0
`The player's requested move caused a collision, so we'll try to give them
`as much of their move as we can without allowing them to collide
`So first off we'll see if using the old X value eliminates the collision condition
position object ColliderObjNum, ox#, ny#, nz#
if object collision(ColliderObjNum, 0)<>0 or (Object Collision(ColliderObjNum, 0)<> BulletObj)
`Using the old X value did not eliminate the collision. Now we'll try the
`old Z value.
Position object ColliderObjNum, nx#, ny#, oz#
If (Object Collision(ColliderObjNum, 0)<>0) or (Object Collision(ColliderObjNum, 0)<> BulletObj)
`Using the old Z value did not eliminate the collision, so now we'll
`see if the new Y value is the one causing the problem.
Position Object ColliderObjNum, nx#, oy#, nz#
If Object Collision(ColliderObjNum, 0)<>0 or (Object Collision(ColliderObjNum, 0)<> BulletObj)
`Ok, nothing we've tried will eliminate the collision condition, so
`we'll just put the player back where they started from.
ny#=oy#
nx#=ox#
nz#=oz#
Else
`The new Y value, was the problem, so we'll just set the Y value back to OY#
ny#=oy#
EndIf
Else
`The New Z value was the problem so we'll set it back to OZ#
nz#=oz#
EndIf
else
`The new X value was the culprit, so we'll set it back to OX#
nx# = ox#
endif
EndIf
if (oy#-ny#) > EyeHeight
`If the Y value is lower than the current Y value, by more than the Eyeheight,
`we need to start the falling process. To do that, we'll reset ny# to oy# because
`the falling routine will handle changing it. Also, we'll set the AirBorn flag to 1
`to tell the program to use the falling routine.
AirBorn = 1
ny#=oy#
`=========================================================================
`NOTE: If the player is going to be damaged by falls, here is where that
`damage is best calculated.
`=========================================================================
`Before we leave, let's just check and make sure that we can
`safely allow the player to fall at this location.
CheckFall()
EndIF
`move the Camera and collider to the final adjudicated position
Position Camera 0, nx#, ny#, nz#
Position Object ColliderObjNum, nx#, ny#, nz#
EndFunction
Function CheckFall()
`this function checks to see if the place you are going to fall to is going to
`create a collision.
ox#=Object Position x(ColliderObjNum)
oy#=Object Position y(ColliderObjNum)
oz#=Object Position z(ColliderObjNum)
`to do that, we'll determine where the final resting location is after the fall is
`complete
ny#=EyeHeight + (oy#-Intersect Object(1, ox#, oy#, oz#, ox#, -1000, oz#))
`We'll quickly position the collider there
position object ColliderObjNum, ox#, ny#, oz#
`then see if there is a collision at the proposed location
if object collision(ColliderObjNum,0) <> 0
`If there is a collision, we'll simply turn off the AirBorn flag
Airborn=0
EndIf
EndFunction