Hey all. When I was first trying to figure out sliding collision, I had a heck of a time finding anything incredibly helpful on the boards here. As I have finally produced a relatively functional collision system, I'd like to contribute the code to the boards somewhere that it should be easy for others to find.
This code is not perfect, but it will get you past the most important collision scenarios you'll encounter while in the beginning stages of your program.
REM *** Include File: Movement.dba ***
REM Created: 4/14/2013 9:36:01 PM
REM
REM Included in Project: C:\Program Files (x86)\The Game Creators\Dark Basic Professional Online\Projects\Rework Collision\Rework Collision.dbpro
REM
function MoveButtons(playerID)
if keystate(17) = 1 then MoveForward(playerID, 3)
if keystate(31) = 1 then MoveBackward(playerID, 3)
if keystate(16) = 1 then StrafeLeft(playerID, 3)
if keystate(18) = 1 then StrafeRight(playerID, 3)
if keystate(30) = 1 then MoveRotate(playerID, -5)
if keystate(32) = 1 then MoveRotate(playerID, 5)
endfunction
rem ----------------------------------------------------------------------------------------------------------------------------------------------------------------
function MoveRotate(objectID, angle#)
yA# = object angle Y(objectID)
yrotate object objectID, wrapvalue(ya# + angle#)
VerticalBump(objectID, .1)
endfunction
rem ----------------------------------------------------------------------------------------------------------------------------------------------------------------
function MoveForward(objectID, distance#)
if distance# > 0
sourceX# = object position X(objectID)
sourceY# = object position Y(objectID)
sourceZ# = object position Z(objectID)
rem ------------------------------------------TEST CODE-------------------------------------
move object objectID, distance#
destX# = object position X(objectID)
destY# = object position Y(objectID)
destZ# = object position Z(objectID)
CollisionBump(objectID, sourceX#, sourceY#, sourceZ#)
if object collision(objectID, 0) <> 0
repeat
inc x
move object objectID, -distance#/10
VerticalBump(objectID, 1)
if x > 10
position object objectID, sourceX#, sourceY#, sourceZ#
VerticalBump(objectID, .5)
print "Collision Breakdown: Object Reset!"
exit
endif
until object collision(objectID, 0) = 0
endif
VerticalBump(objectID, .19)
rem ------------------------------------TEST CODE------------TEST CODE----------------------------------
else
MoveBackward(objectID, -distance#)
endif
endfunction
rem ----------------------------------------------------------------------------------------------------------------------------------------------------------------
function CollisionBump(objectID, sourceX#, sourceY#, sourceZ#)
destX# = object position X(objectID)
destY# = object position Y(objectID)
destZ# = object position Z(objectID)
if object collision(objectID, 0) <> 0
colY# = get object collision y()
colX# = get object collision x()
colZ# = get object collision z()
dec destX#, colX#
dec destY#, colY#
dec destZ#, colZ#
position object objectID, destX#, destY#, destZ#
VerticalBump(objectID, .19)
endif
endfunction
rem ----------------------------------------------------------------------------------------------------------------------------------------------------------------
function StrafeBump(objectID, distance#)
yA# = object angle y(objectID)
yrotate object objectID, wrapvalue(yA# + 90)
move object objectID, distance#
if object collision (objectID, 0) <> 0
endif
endfunction
rem ----------------------------------------------------------------------------------------------------------------------------------------------------------------
function VerticalBump(objectID, distance#)
move object up objectID, distance#
if object collision(objectID, 0) = 0
colY# = get object collision y()
position object objectID, object position x(objectID), object position y(objectID) - colY#, object position z(objectID)
else
move object down objectID, distance#
if object collision(objectID, 0) = 0
colY# = get object collision y()
position object objectID, object position x(objectID), object position y(objectID) - colY#, object position z(objectID)
endif
endif
endfunction
rem ----------------------------------------------------------------------------------------------------------------------------------------------------------------
function MoveBackward(objectID, distance#)
yrotate object objectID, wrapvalue(object angle y(objectID) - 180)
MoveForward(objectID, distance#)
yrotate object objectID, wrapvalue(object angle y(objectID) - 180)
endfunction
rem ----------------------------------------------------------------------------------------------------------------------------------------------------------------
function StrafeRight(objectID, distance#)
yA# = object angle y(objectID)
yrotate object objectID, wrapvalue(yA#+90)
MoveForward(objectID, distance#)
yrotate object objectID, yA#
endfunction
rem ----------------------------------------------------------------------------------------------------------------------------------------------------------------
function StrafeLeft(objectID, distance#)
yA# = object angle y(objectID)
yrotate object objectID, wrapvalue(yA#-90)
MoveForward(objectID, distance#)
yrotate object objectID, yA#
endfunction
rem -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Function ApplyGravity(objectID, gravity#)
xPos# = object position x(objectID)
yPos# = object position y(objectID)
zPos# = object position z(objectID)
if gravity# > .1 or gravity# < -.1
if gravity# > 0
move object down objectID, .1
if (object collision(objectID, 0) <> 0)
move object up objectID, .1
else
ApplyGravity(objectID, gravity# - .1)
endif
endif
if gravity# < 0
move object down objectID, -.1
if (object collision(objectID, 0) <> 0)
move object up, -.1
else
ApplyGravity(objectID, gravity# + .1)
endif
endif
endif
endfunction
In order to make it work, ensure that you've set collision "on" on your objects and simply include these two functions in your main loop:
MoveButtons(playerID)
ApplyGravity(playerID, gravity#)
playerID being the object you'd like to apply WASDQE movement con collision.
Also, keep gravity# over .1 or under -.1
Happy Programming!
P.S. For anyone trying to understand the code above, all of the trickery happens within the REM'd bounds labeled "TEST CODE"
Ask not for whom the bell tolls;
It tolls for ye!