TGC Codebase Backup



complete sliding collision system using Sparky's by Milkman

8th Jan 2006 20:15
Summary

This is my sliding collision system that using sparky's dll to handle all collision.



Description

let me give a short explaination of what you need to do to get my system working.

first, load your level as a normal object. then, set it up with sparky's by using then command:

setupterraincollision object,group,freeobject

the object is the object number of your level, the group you can leave as 0, and the free object is just any object not currently in use.

ok, so you've got your level set up, so lets make an object to collide with that level and set up collision for it.

make object cube cubeobject,size
setupcollision(cubeobject,45,size/2,16)
setcollisionon(cubeobject)

that's all you need to set up collision on a cube. cubeobject is the object number of your cube, size is the size of the cube, obviously.
there are 4 parameters for the setupcollision() function. the first is the object number to set up collision with, so we will put cubeobject. the second is the steepest climbable slope, which we will set as 45. this means that we can climb up any slope less than 45 degrees, but any slope steeper than that will cause us to slide down it, and is unclimbable. the third parameter is the radius of collision for the object. we will set that to half the size of the cube. the fourth and final parameter to set up collision is the number of sliding collision checks. 16 works fine for the test level i've provided, but depending on level geometry you may want to adjust this. the higher the number checks, the more accurate the collision, but also the slower.

so once youve set up your level and object to collide with it, you can enter the main loop. once in the main loop, you can move the object horizontally and vertically. after moving it horizontally, you will want to update the collision horizontally. this can be done like this:

updatehorizontalcollision(object)

this automatically repositions the object provided (if it was set up for collision) horizontally to avoid collision, sliding automatically.

once you've moved horizontally, you will want to move vertically to apply gravity and such. do this, then update the vertical collision like so:

updateverticalcollision(object)

this will automatically reposition your object to keep it on top of the level and not let it fall through.

with the combination of updating the vertical and horizontal collision, your object will automatically slide vertically and horizontally and reposition itself right where it needs to be.



Code
                                    ` This code was downloaded from The Game Creators
                                    ` It is reproduced here with full permission
                                    ` http://www.thegamecreators.com
                                    
                                    
function void()
   global dim collision() as collision
   if memblock exist(1)=1 then delete memblock 1
endfunction

function findobject(object)
   for x=1 to array count(collision(0))
      if collision(x).object=object then number=x
   next x
endfunction number

function setupcollision(object,slope#,radius#,checks)
   if array count(collision(0))=0 then global dim collision() as collision
   array insert at bottom collision(0)
   number=array count(collision(0))
   collision(number).ox=object position x(object)
   collision(number).oy=object position y(object)
   collision(number).oz=object position z(object)
   collision(number).object=object
   collision(number).hradius=radius#
   collision(number).vradius=radius#*tan(slope#)
   collision(number).slope=slope#
   collision(number).checks=checks
   collision(number).anglesize=360/checks
endfunction

function destroycollision(object)
   array delete element collision(0),findobject(object)
endfunction

function setcollisionon(object)
   collision(findobject(object)).enabled=1
endfunction

function setcollisionoff(object)
   collision(findobject(object)).enabled=0
endfunction

function getongroundstate(object)
   onground=collision(findobject(object)).onground
endfunction onground

function getverticalslope(object)
   slope#=collision(findobject(object)).vslope
endfunction slope#

function gethorizontalslope(object)
   slope#=collision(findobject(object)).hslope
endfunction slope#

function updatehorizontalcollision(object)
   number=findobject(object)
   ox#=collision(number).ox
   oy#=collision(number).oy
   oz#=collision(number).oz
   x#=object position x(collision(number).object)
   y#=object position y(collision(number).object)
   z#=object position z(collision(number).object)

   if collision(number).enabled
      cd#=collision(number).hradius*2
      for x=0 to collision(number).checks-1
         a#=x*collision(number).anglesize
         if intersectobject(0,0,x#,oy#,z#,newxvalue(x#,a#,collision(number).hradius),oy#,newzvalue(z#,a#,collision(number).hradius),0)>0
            d#=getcollisiondistance()
            if d#<cd#
               cd#=d# : ca#=a#
               cx#=getstaticcollisionx()
               cz#=getstaticcollisionz()
               collision(number).hslope=acos(getcollisionnormaly())
            endif
         endif
      next x
      if cd#<collision(number).hradius
         ta#=wrapvalue(ca#-180)
         position object collision(number).object,newxvalue(cx#,ta#,collision(number).hradius),oy#,newzvalue(cz#,ta#,collision(number).hradius)
      else
         collision(number).hslope=0
      endif
   endif

   collision(number).ox=object position x(collision(number).object)
   collision(number).oy=object position y(collision(number).object)
   collision(number).oz=object position z(collision(number).object)
endfunction

function updateverticalcollision(object)
   number=findobject(object)
   ox#=collision(number).ox
   oy#=collision(number).oy
   oz#=collision(number).oz
   x#=object position x(collision(number).object)
   y#=object position y(collision(number).object)
   z#=object position z(collision(number).object)

   if collision(number).enabled
      if oy#-y#>=0
         if intersectobject(0,0,ox#,oy#,oz#,ox#,y#-collision(number).vradius,oz#,0)>0
            cy#=getstaticcollisiony()
            collision(number).vslope=acos(getcollisionnormaly())
            position object collision(number).object,ox#,cy#+collision(number).vradius,oz#
            if collision(number).vslope<collision(number).slope then collision(number).onground=1 else collision(number).onground=0
         else
            collision(number).vslope=0
            collision(number).onground=0
         endif
      else
         if intersectobject(0,0,ox#,oy#,oz#,ox#,y#+collision(number).vradius,oz#,0)>0
            cy#=getstaticcollisiony()
            collision(number).vslope=acos(getcollisionnormaly())
            collision(number).onground=0
            position object collision(number).object,ox#,cy#-collision(number).vradius,oz#
         else
            collision(number).vslope=0
            collision(number).onground=0
         endif
      endif
   endif

   collision(number).ox=object position x(collision(number).object)
   collision(number).oy=object position y(collision(number).object)
   collision(number).oz=object position z(collision(number).object)
endfunction

type collision
   enabled as boolean
   object as integer
   hradius as float
   vradius as float
   checks as integer
   anglesize as float
   slope as float
   ox as float
   oy as float
   oz as float
   onground as boolean
   hslope as float
   vslope as float
endtype