TGC Codebase Backup



3D Dark Physics with Jump,gravity and camera collision character controller by Fitz marc ade

19th Jul 2008 5:06
Summary

Dark Physics Plugin required. A WIP of using Dark Physics Character controller in 3rd person Camera view. While Dark Physics is able to sort the Collision of the Character Controll



Description



Code
                                    ` This code was downloaded from The Game Creators
                                    ` It is reproduced here with full permission
                                    ` http://www.thegamecreators.com
                                    
                                    REM Project: 3D Dark Physics with Jump,gravity and camera collision character controller demo.
REM Created: 18/07/2008 04:02am GMT
REM Author: FITZMARCADE and whoever came up with the jumping character controller demo?
REM ***** Main Source File *****
REM Contact: fitzmarcade@inbox.com

`found the code for Dark physics jumping character controller on the codebase section of forums. -
`I already had the collision codes which i had used for standard DBP sliding & ramp collisions. - 
`Just altered it for camera, so i tweaked a bit and added camera collision and made some changes as-
`Dark physics does not support camera commands as far as far as i know ...

`I'm sure somebody out there recognises the original code. Just that i've searched the forums for Dark Physics-
`camera collision help and noticed several other people are having similar problems, so i tried to problem solve -
`it. It's not perfect & I havent tried it with `x` and `dbo` meshes/maps yet! However with a little tweaking -
`i'm sure this will benefit somebody like my self for a 3rd person platform game or RPG.

`Anyway's hope this helps somebody out there?

`Use W.S.A.D or Curser keys to move character controller, mouse to look around, use mouse wheel to zoom in and out.
`and Spacebar To Jump. (still a WIP however)...

global Playr as integer
global px# as integer
global py# as integer
global pz# as integer

`pretty standand initialisation routine
sync on
sync rate 60
backdrop on
color backdrop 0,rgb(0,0,0)
set image colorkey 0,0,0

phy start
`scaled of 1 DBP point = 1 cm - the standard is one Metre
`so gravity has to be scaled by 100
phy set gravity 0.0,-98,0.0
autocam off

set camera range 0,0.1,10000

hide mouse
set ambient light 40

automatic camera collision 0,2,1
`variables
sw=screen width() : sh=screen height()
`character position variables
px# = 0 : py# = 6: pz# = 0
`cx#=0:cy#=0:cz#=0
`how long charecter hill jump for and the speed at which they jump
jumpspeed = -300 : jumptime = 30
`camera
`camheight = 30
`camdist=-20
Playr = 3

d# = 80.0
h# = 60.0
s# = 10.0

`Make a simple scene
cLevel1()

make object box Playr,4,15,8
color object Playr,RGB(255,0,255)

`phy make capsule character controller ID, x#, y#, z#, radius#, height#, up, step#, slope limit#
phy make capsule character controller Playr, px#,py#,pz#, 4,8, 1, 1.5, 45.0
`position object Playr,px,py+20,pz
`main loop
do
`this bit just checks mouse position and keeps it in the screen - helps if using a window
mx=mousex()
my=mousey()
   if mx => sw-2 then mx=mx-sw
      if mx <= 1 then mx=sw-mx
         if my => sh-2 then my=my-sh
            if my <= 1 then my=sy-my
position mouse mx,my

`make charachter fall
oldjgy# = object position y(Playr)
phy set character controller displacement Playr, 98, 0
phy move character controller Playr, 0.1
phy move character controller Playr, -0.1
`check position and rotate charachter with mouse
move=0
grx#=object angle x(Playr)
gry#=object angle y(Playr)
grz#=object angle z(Playr)
gry#=wrapvalue(gry#+ (mousemovex()/2))
`yrotate object Playr,gry#
oldgry#=gry#
move=0
`obviously positions camera to character controller position
`position camera object position x(Playr),object position y(Playr)-1,object position z(Playr)
`yrotate camera 0,camera angle y (0)+45
`this bit moves charachter with wsad or cursor keys
`left
   if keystate(30)=1 or keystate(203)=1
      phy set character controller displacement Playr, 0, 0
      yrotate object Playr,wrapvalue(gry#-90)
      phy move character controller Playr, 50.0
      yrotate object Playr,oldgry#
      move=1
   endif
`right
   if keystate(32)=1 or keystate(205)=1
      phy set character controller displacement Playr, 0, 0
      yrotate object Playr,wrapvalue(gry#+90)
      phy move character controller Playr, 50.0
      yrotate object Playr,oldgry#
      move=1
   endif
`forward
   if keystate(17)=1 or keystate(200)=1
      phy set character controller displacement Playr, 0, 0
      phy move character controller Playr, 50.0
      move=1
   endif
`back
   if keystate(31)=1 or keystate(208)=1
      phy set character controller displacement Playr, 0, 0
      phy move character controller Playr, -40.0
      move=1
   endif
   
`check we want to jump
   if spacekey()=1 and jump=0 then  startgy#=object position y(Playr):jump=1 :oldgy#=0
`if spacekey()=1 and jump=0 then  startgy#=object position y(camObj):jump=1 :oldcy#=0
   if jump>0
`this checks to see if characher has a restricted jump ( platform above the head )
   if object position y(Playr)=oldgy# then jump=jumptime-1
`if object position y(camObj)=oldcy# then jump=jumptime-1
      oldgy#=object position y(Playr)
`oldcy#=object position y(camObj)
`move charachter up
      phy set character controller displacement Playr, 0,jumpspeed
`phy set character controller displacement camObj, 0,jumpspeed
`displacement only seems to work when characher is moving - so move it a wee bit then back a wee bit
      phy move character controller Playr, 0.1
      phy move character controller Playr, -0.1

      jump=jump+1 `incrament timer
         if jump=jumptime then jump=-1
   endif
   `this is a check that the jump has finished before you can start a new jump
   if jump<0
      jump=jump-1
         if jump<(0-jumptime)
            jgy#=object position y(Playr)
               if jgy# = oldjgy# then jump=0
         endif
   endif
`documentation states for smooth movement you should allways call this comand - even if not moving
   if move=0 then phy move character controller Playr, 0.0
`if move=0 then phy move character controller camObj,0.0

`mousewheel for zooming in/out view of character controller.
mwheel=MOUSEMOVEZ()
   IF mwheel >0 THEN d# = d#+1
      IF mwheel <0 THEN d# = d#-1
         if d# > 200 then d# =200
            if d# < 30 then d# = 30
`camera up and down
crx#=camera angle x()
crx#=wrapvalue(crx#+ (mousemovey()/2))

`ya1#=ya1#+MOUSEMOVEX()*0.1
`ya1#=WRAPVALUE(ya1#)

px#=object position x(Playr)
py#=object position y(Playr)
pz#=object position z(Playr)

`position camera object position x(Playr),object position y(Playr)+50,object position z(Playr)

`position camera px#,py#+40,pz#
set camera to follow 0,px#,py#,pz#,gry#,d#,h#,s#,1
rotate object Playr,0,gry#,0
`SET CAMERA TO OBJECT ORIENTATION Playr
`camCollision()
gosub camCol

`move camera camdist
   if crx#> 45 and crx#<270 then crx#=45
   if crx#<300 and crx#>269 then crx#=300
xrotate camera crx#

phy update
sync
loop


camCol:
`object position variables for camCollision routine
x#=OBJECT POSITION X(Playr)
y#=OBJECT POSITION Y(Playr)
z#=OBJECT POSITION Z(Playr)
a#=OBJECT ANGLE Y(Playr)
`radius of collision
radius#=2
`Number of raycast checks for each side/angle (NB i sugest you keep this between 4 and 8 for speed reasons).
checks=4
IF checks<4 THEN checks=4
IF checks>4 THEN checks=4
angwidth=360/checks
DIM ang#(checks-1,2)
DIM sort#(checks-1,2)
`camera variables
cx#=CAMERA POSITION X()
cy#=CAMERA POSITION Y()
cz#=CAMERA POSITION Z()
FOR x=0 TO checks-1
   chx#=NEWXVALUE(cx#,x*angwidth,90)
   chz#=NEWZVALUE(cz#,x*angwidth,90)
   `here is a for/next loop for the levels wall objects & platform stored as `w` variable.
   ` floor isn't needed for camCollision as camera is above Playr object.
   for w = 11 to 15
   ang#(x,1)=INTERSECT OBJECT(w,cx#,cy#,cz#,chx#,cy#,chz#)
   next w
   `this was supposed to give the user the debug info for distance to wall (not finished yet!)
   IF ang#(x,1)=0 THEN ang#(x,1)=999
   ang#(x,2)=x*angwidth
   sort#(x,1)=ang#(x,1)
   sort#(x,2)=ang#(x,2)
NEXT x
FOR x=0 TO checks-2
FOR y=x+1 TO checks-1
   IF ang#(x,1)>ang#(y,1)
      temp#=ang#(x,1)
      temp2#=ang#(x,2)
      ang#(x,1)=ang#(y,1)
      ang#(x,2)=ang#(y,2)
      ang#(y,1)=temp#
      ang#(y,2)=temp2#
   ENDIF
NEXT x
NEXT y
PRINT "Camera Distance to Wall=",ang#(0,1)
`here we use the cam angles to move camera when collision is detected.
prev=WRAPVALUE(ang#(0,2)-90)/angwidth
nxt=WRAPVALUE(ang#(0,2)+90)/angwidth
newd#=radius#-ang#(0,1)
newa#=WRAPVALUE(ang#(0,2)-180)
newd1#=radius#-sort#(prev,1)
newa1#=WRAPVALUE(sort#(prev,2)-180)
newd2#=radius#-sort#(nxt,1)
newa2#=WRAPVALUE(sort#(nxt,2)-180)
IF ang#(0,1)<radius# AND ang#(0,1)>0.0
   repx#=NEWXVALUE(cx#,newa#,newd#)
   repz#=NEWZVALUE(cz#,newa#,newd#)
   POSITION CAMERA repx#,cy#,repz#
ENDIF
cx#=CAMERA POSITION X()
cz#=CAMERA POSITION Z()
IF sort#(prev,1)<radius# AND sort#(prev,1)>0.0
   repx1#=NEWXVALUE(cx#,newa1#,newd1#)
   repz1#=NEWZVALUE(cz#,newa1#,newd1#)
   POSITION CAMERA repx1#,cy#,repz1#
ENDIF
cx#=CAMERA POSITION X()
cz#=CAMERA POSITION Z()
IF sort#(nxt,1)<radius# AND sort#(nxt,1)>0.0
   repx2#=NEWXVALUE(cx#,newa2#,newd2#)
   repz2#=NEWZVALUE(cz#,newa2#,newd2#)
   POSITION CAMERA repx2#,cy#,repz2#
ENDIF
RETURN

`simple level
function cLevel1()
   make object box 10,500,5,500:position object 10,0,-5,0:color object 10,RGB(0,64,0)
   make object box 11,5,300,500:position object 11,-250,5,0:color object 11,RGB(128,64,0)
   make object box 12,500,300,5:position object 12,0,5,250:color object 12,RGB(128,64,0)
   make object box 13,5,300,500:position object 13,250,5,0:color object 13,RGB(128,64,0)
   make object box 14,500,300,5:position object 14,0,5,-250:color object 14,RGB(128,64,0)
   make object box 15,70,5,100:position object 15,50,35,80:color object 15,RGB(0,0,255)
   for sB = 10 to 15
       phy make rigid body static box sB
   next sB
   `automatic camera collision 0,0.1,0
endfunction