Hey, I see a bunch of posts out there that have sliding collision with two .x files and so I thought I would make my own.
This function is called objectCollisionHandler(objectNum, mapNum, radius#, floor#, ceiling#). This function takes in these five arguments and automatically processes sliding collision data for an object against another .x object. THUS, you can have your character run around a map without him running through walls or floors.
Here is the function:
function objectCollisionHandler(objectNum, mapNum, radius#, floor#, ceiling#)
`Step 1: collect current position
positionX# = object position x(objectNum)
positionY# = object position y(objectNum)
positionZ# = object position z(objectNum)
`Step 2: Check the Vectors
vectorRight# = INTERSECT OBJECT(mapNum, positionX#, positionY#, positionZ#, positionX#+radius#, positionY#, positionZ#)
vectorLeft# = INTERSECT OBJECT(mapNum, positionX#, positionY#, positionZ#, positionX#-radius#, positionY#, positionZ#)
vectorForward# = INTERSECT OBJECT(mapNum, positionX#, positionY#, positionZ#, positionX#, positionY#, positionZ#+radius#)
vectorBackward# = INTERSECT OBJECT(mapNum, positionX#, positionY#, positionZ#, positionX#, positionY#, positionZ#-radius#)
vectorForwardRight# = INTERSECT OBJECT(mapNum, positionX#, positionY#, positionZ#, positionX#+radius#, positionY#, positionZ#+radius#)
vectorForwardLeft# = INTERSECT OBJECT(mapNum, positionX#, positionY#, positionZ#, positionX#-radius#, positionY#, positionZ#+radius#)
vectorBackwardRight# = INTERSECT OBJECT(mapNum, positionX#, positionY#, positionZ#, positionX#+radius#, positionY#, positionZ#-radius#)
vectorBackwardLeft# = INTERSECT OBJECT(mapNum, positionX#, positionY#, positionZ#, positionX#-radius#, positionY#, positionZ#-radius#)
vectorUp# = INTERSECT OBJECT(mapNum, positionX#, positionY#, positionZ#, positionX#, positionY#+ceiling#, positionZ#)
vectorDown# = INTERSECT OBJECT(mapNum, positionX#, positionY#, positionZ#, positionX#, positionY#-floor#, positionZ#)
`Step 2 and a half: Check these values for zero and re-assign values if necessary
if vectorRight# = 0 THEN vectorRight# = radius#
if vectorLeft# = 0 THEN vectorLeft# = radius#
if vectorForward# = 0 THEN vectorForward# = radius#
if vectorBackward# = 0 THEN vectorBackward# = radius#
if vectorForwardRight# = 0 THEN vectorForwardRight# = radius#
if vectorForwardLeft# = 0 THEN vectorForwardLeft# = radius#
if vectorBackwardRight# = 0 THEN vectorBackwardRight# = radius#
if vectorBackwardLeft# = 0 THEN vectorBackwardLeft# = radius#
if vectorUp# = 0 THEN vectorUp# = ceiling#
if vectorDown# = 0 THEN vectorDown# = floor#
`Step 3: Get info from the vector data
if vectorRight# <= radius# THEN additionValueX# = (radius# - vectorRight#)
if vectorLeft# <= radius# THEN additionValueXTwo# = radius# - vectorLeft#
if vectorForward# <= radius# THEN additionValueZ# = (radius# - vectorForward#)
if vectorBackward# <= radius# THEN additionValueZTwo# = radius# - vectorBackward#
if vectorForwardRight# = 0 THEN additionValueForwardRight# = radius# - vectorForwardRight#
if vectorForwardLeft# = 0 THEN additionValueForwardLeft# = radius# - vectorForwardLeft#
if vectorBackwardRight# = 0 THEN additionValueBackwardRight# = radius# - vectorBackwardRight#
if vectorBackwardLeft# = 0 THEN additionValueBackwardLeft# = radius# - vectorBackwardLeft#
if vectorUp# <= ceiling# THEN additionValueY# = (ceiling# - vectorUp#)
if vectorDown# <= floor# THEN additionValueYTwo# = floor# - vectorDown#
`Step 3 and a half: Re-assign for the closest vector
if additionValueX# > additionValueXTwo# THEN finalValueX# = additionValueX#*-1 ELSE finalValueX# = additionValueXTwo#
if additionValueY# > additionValueYTwo# THEN finalValueY# = additionValueY# ELSE finalValueY# = additionValueYTwo#
if additionValueZ# > additionValueZTwo# THEN finalValueZ# = additionValueZ#*-1 ELSE finalValueZ# = additionValueZTwo#
if additionValueForwardRight# > additionValueBackwardLeft#
finalValueDiagOne# = additionValueForwardRight#*-1
addOnX# = finalValueDiagOne#/2
addOnZ# = finalValueDiagOne#/2
ELSE
finalValueDiagOne# = additionValueBackwardLeft#
addOnX# = finalValueDiagOne#/2
addOnZ# = finalValueDiagOne#/2
endif
if additionValueForwardLeft# > additionValueBackwardRight#
finalValueDiagTwo# = additionValueForwardLeft#
addOnX# = finalValueDiagTwo#/2
addOnZ# = (finalValueDiagTwo#/2)*-1
ELSE
finalValueDiagTwo# = additionValueBackwardRight#
addOnX# = (finalValueDiagOne#/2)*-1
addOnZ# = finalValueDiagOne#/2
endif
`Step 4: Apply info from the vector data to the object's position
posX# = object position x(objectNum)
posY# = object position y(objectNum)
posZ# = object position z(objectNum)
position object objectNum, posX#+finalValueX#+addOnX#, posY#+finalValueY#, posZ#+finalValueZ#+addOnZ#
endfunction
Now, I made it a function so everybody could adopt it in their video game. Now I'll explain how to use the function.
You first have an object, let's say a cube: make object cube 1, 100. Then you move that cube through 3-D space with this function:
function controlObject(objectNum,speed,turn)
if upkey() = 1 THEN move object objectNum, speed
if downkey() = 1 THEN move object objectNum, speed * -1
if rightkey()=1 THEN turn object right objectNum, turn
if leftkey() = 1 THEN turn object left objectNum, turn
endfunction
Easy, right? Now you would apply gravity to your object (that is, if you want gravity in your game). So let's create another function that does that:
function gravityForObject(objectNum, gravityValue)
posX# = object position x(objectNum)
posY# = object position y(objectNum)
posZ# = object position z(objectNum)
position object objectNum, posX#, posY#-gravityValue, posZ#
endfunction
Are you still following? Now that we have moved our object in 3-D space we can now use the almighty objectCollisionHandler() function. What the function does is take an object and then checks the collision is has with the map (another .x object), then it repositions the object to produce sliding collision.
Here are the arguments you would pass to objectCollisionHandler():
objectNum : This is the number of the object you wish to have collision data applied to.
mapNum: This is the number of the object that is the map, this is used to test against the object's position.
radius#: This is the number that says how far away your object will be from the walls of the map.
floor#: This is the number that says how high your object will be from the ground.
ceiling#: This is the number that says how far away your object will be from the ceiling.
Now we need to re-position the camera to be in first person view. That is, in the same position of the object:
function positionCameraAsObject(objectNum, cameraNum)
objPosX# = object position x(objectNum)
objPosY# = object position y(objectNum)
objPosZ# = object position z(objectNum)
objRotX# = object angle x(objectNum)
objRotY# = object angle y(objectNum)
objRotZ# = object angle z(objectNum)
position camera cameraNum, objPosX#, objPosY#, objPosZ#
rotate camera cameraNum, objRotX#, objRotY#, objRotZ#
endfunction
Now that we have moved our object, applied gravity to it, re-positioned it using objectCollisionHandler(), and have moved the camera to be in the same area of the object, we can now use sync to draw everything on the screen.
Here is the mainLoop() function that brings it all together:
function mainLoop()
sync on : sync rate 30 : color backdrop 0 : autocam off
make object cube 1, 20
load object "colltest.x", 2
do
`controlCamera()
controlObject(1,10,3)
`controlObject(objectNum,speed,turn)
positionCameraAsObject(1, 0)
`positionCameraAsObject(objectNum, cameraNum)
gravityForObject(1, 25)
`gravityForObject(objectNum, gravityValue)
objectCollisionHandler(1, 2, 50, 100, 0)
`objectCollisionHandler(objectNum, mapNum, radius#, floor#, ceiling#)
sync
loop
endfunction
As you can see, I have typed out each function twice, the first time with the arguments in them, then the second time as a remark that shows what each argument is.
I hope everyone is with me on this so far.
Now here is the entire source code:
Rem Project: Sliding Collision Function
Rem Created: 9/8/2005 5:47:33 PM
Rem ***** Main Source File *****
global speed as integer
global rotateSpeed as integer
speed = 10
rotateSpeed = 3
mainLoop()
function controlCamera()
if upkey() = 1 THEN move camera speed
if downkey() = 1 THEN move camera speed*-1
if rightkey() = 1 THEN turn camera right rotateSpeed
if leftkey() = 1 THEN turn camera left rotateSpeed
endfunction
function objectCollisionHandler(objectNum, mapNum, radius#, floor#, ceiling#)
`Step 1: collect current position
positionX# = object position x(objectNum)
positionY# = object position y(objectNum)
positionZ# = object position z(objectNum)
`Step 2: Check the Vectors
vectorRight# = INTERSECT OBJECT(mapNum, positionX#, positionY#, positionZ#, positionX#+radius#, positionY#, positionZ#)
vectorLeft# = INTERSECT OBJECT(mapNum, positionX#, positionY#, positionZ#, positionX#-radius#, positionY#, positionZ#)
vectorForward# = INTERSECT OBJECT(mapNum, positionX#, positionY#, positionZ#, positionX#, positionY#, positionZ#+radius#)
vectorBackward# = INTERSECT OBJECT(mapNum, positionX#, positionY#, positionZ#, positionX#, positionY#, positionZ#-radius#)
vectorForwardRight# = INTERSECT OBJECT(mapNum, positionX#, positionY#, positionZ#, positionX#+radius#, positionY#, positionZ#+radius#)
vectorForwardLeft# = INTERSECT OBJECT(mapNum, positionX#, positionY#, positionZ#, positionX#-radius#, positionY#, positionZ#+radius#)
vectorBackwardRight# = INTERSECT OBJECT(mapNum, positionX#, positionY#, positionZ#, positionX#+radius#, positionY#, positionZ#-radius#)
vectorBackwardLeft# = INTERSECT OBJECT(mapNum, positionX#, positionY#, positionZ#, positionX#-radius#, positionY#, positionZ#-radius#)
vectorUp# = INTERSECT OBJECT(mapNum, positionX#, positionY#, positionZ#, positionX#, positionY#+ceiling#, positionZ#)
vectorDown# = INTERSECT OBJECT(mapNum, positionX#, positionY#, positionZ#, positionX#, positionY#-floor#, positionZ#)
`Step 2 and a half: Check these values for zero and re-assign values if necessary
if vectorRight# = 0 THEN vectorRight# = radius#
if vectorLeft# = 0 THEN vectorLeft# = radius#
if vectorForward# = 0 THEN vectorForward# = radius#
if vectorBackward# = 0 THEN vectorBackward# = radius#
if vectorForwardRight# = 0 THEN vectorForwardRight# = radius#
if vectorForwardLeft# = 0 THEN vectorForwardLeft# = radius#
if vectorBackwardRight# = 0 THEN vectorBackwardRight# = radius#
if vectorBackwardLeft# = 0 THEN vectorBackwardLeft# = radius#
if vectorUp# = 0 THEN vectorUp# = ceiling#
if vectorDown# = 0 THEN vectorDown# = floor#
`Step 3: Get info from the vector data
if vectorRight# <= radius# THEN additionValueX# = (radius# - vectorRight#)
if vectorLeft# <= radius# THEN additionValueXTwo# = radius# - vectorLeft#
if vectorForward# <= radius# THEN additionValueZ# = (radius# - vectorForward#)
if vectorBackward# <= radius# THEN additionValueZTwo# = radius# - vectorBackward#
if vectorForwardRight# = 0 THEN additionValueForwardRight# = radius# - vectorForwardRight#
if vectorForwardLeft# = 0 THEN additionValueForwardLeft# = radius# - vectorForwardLeft#
if vectorBackwardRight# = 0 THEN additionValueBackwardRight# = radius# - vectorBackwardRight#
if vectorBackwardLeft# = 0 THEN additionValueBackwardLeft# = radius# - vectorBackwardLeft#
if vectorUp# <= ceiling# THEN additionValueY# = (ceiling# - vectorUp#)
if vectorDown# <= floor# THEN additionValueYTwo# = floor# - vectorDown#
`Step 3 and a half: Re-assign for the closest vector
if additionValueX# > additionValueXTwo# THEN finalValueX# = additionValueX#*-1 ELSE finalValueX# = additionValueXTwo#
if additionValueY# > additionValueYTwo# THEN finalValueY# = additionValueY# ELSE finalValueY# = additionValueYTwo#
if additionValueZ# > additionValueZTwo# THEN finalValueZ# = additionValueZ#*-1 ELSE finalValueZ# = additionValueZTwo#
if additionValueForwardRight# > additionValueBackwardLeft#
finalValueDiagOne# = additionValueForwardRight#*-1
addOnX# = finalValueDiagOne#/2
addOnZ# = finalValueDiagOne#/2
ELSE
finalValueDiagOne# = additionValueBackwardLeft#
addOnX# = finalValueDiagOne#/2
addOnZ# = finalValueDiagOne#/2
endif
if additionValueForwardLeft# > additionValueBackwardRight#
finalValueDiagTwo# = additionValueForwardLeft#
addOnX# = finalValueDiagTwo#/2
addOnZ# = (finalValueDiagTwo#/2)*-1
ELSE
finalValueDiagTwo# = additionValueBackwardRight#
addOnX# = (finalValueDiagOne#/2)*-1
addOnZ# = finalValueDiagOne#/2
endif
`Step 4: Apply info from the vector data to the object's position
posX# = object position x(objectNum)
posY# = object position y(objectNum)
posZ# = object position z(objectNum)
position object objectNum, posX#+finalValueX#+addOnX#, posY#+finalValueY#, posZ#+finalValueZ#+addOnZ#
endfunction
function gravityForObject(objectNum, gravityValue)
posX# = object position x(objectNum)
posY# = object position y(objectNum)
posZ# = object position z(objectNum)
position object objectNum, posX#, posY#-gravityValue, posZ#
endfunction
function controlObject(objectNum,speed,turn)
if upkey() = 1 THEN move object objectNum, speed
if downkey() = 1 THEN move object objectNum, speed * -1
if rightkey()=1 THEN turn object right objectNum, turn
if leftkey() = 1 THEN turn object left objectNum, turn
endfunction
function positionCameraAsObject(objectNum, cameraNum)
objPosX# = object position x(objectNum)
objPosY# = object position y(objectNum)
objPosZ# = object position z(objectNum)
objRotX# = object angle x(objectNum)
objRotY# = object angle y(objectNum)
objRotZ# = object angle z(objectNum)
position camera cameraNum, objPosX#, objPosY#, objPosZ#
rotate camera cameraNum, objRotX#, objRotY#, objRotZ#
endfunction
function mainLoop()
sync on : sync rate 30 : color backdrop 0 : autocam off
make object cube 1, 20
load object "colltest.x", 2
do
`controlCamera()
controlObject(1,10,3)
`controlObject(objectNum,speed,turn)
positionCameraAsObject(1, 0)
`positionCameraAsObject(objectNum, cameraNum)
gravityForObject(1, 25)
`gravityForObject(objectNum, gravityValue)
objectCollisionHandler(1, 2, 50, 100, 0)
`objectCollisionHandler(objectNum, mapNum, radius#, floor#, ceiling#)
sync
loop
endfunction
It took me two days to create this code. The trick I use is the command: "INTERSECT OBJECT()" This shoots a vector out from any position TO any other position. Therefore I use it to detect any collision with an object to any other .x object (the map) and then re-position the object based on that vector data given to me by the command "INTERSECT OBJECT()"
Pretty cool, huh?
Now I don't have any attached media because I tried attaching some last time but it didn't work. So what you'll have to do is copy/paste my source code into your dbpro and use your own map. The map file is loaded in the mainLoop() function:
function mainLoop()
sync on : sync rate 30 : color backdrop 0 : autocam off
make object cube 1, 20
load object "colltest.x", 2
Right here, load object "colltest.x" is where you would type in whatever .x object you have to use as a map.
Alright everybody, thanks for your time in parsing through this post.
bye
help support me by clicking ads on my website:
www.lazyoaks.net