Basically what this does is take an object and break each limb into it's own piece, and make a collision object so the limb can be bashed around.
REM Project: Destructable
REM Created: 5/6/2007 7:08:56 PM
REM
REM ***** Main Source File *****
REM
type destobj
x as float
y as float
z as float
ax as float
ay as float
az as float
mx as float
my as float
mz as float
tx as float
ty as float
tz as float
o as integer
l as integer
mode as string
endtype
dim dest(100) as destobj
type lvl
o as integer
maxl as integer
endtype
global level as lvl
`load a basic level with multiple limbs
level.o = nextobj()
load object "samplescene.x",level.o
autocam off
`make the level destructable
makedestructable(1,11)
`make your player
p = nextobj()
make object sphere p, 10
position object p, 0,5,0
sync on
do
ox# = object position x(p)
oy# = object position y(p)
oz# = object position z(p)
if upkey() = 1 then move object p, 1
if leftkey() =1 then turn object left p, 5
if rightkey()=1 then turn object right p, 5
move object p, -25
position camera object position x(p), object position y(p) + 5, object position z(p)
move object p, 25
point camera object position x(p), object position y(p) + 5, object position z(p)
for x = 1 to level.maxl
o = dest(x).o
if dest(x).mode = "sit"
if object collision(o,p) = 1
`if you touch the invisible collision object, send the limb flying
dest(x).mx = (object position x(p) - ox#)/1
dest(x).my = (object position y(p) - oy#)/1 + 1.5
dest(x).mz = (object position z(p) - oz#)/1
dest(x).tx = rnd(20) - 10
dest(x).ty = rnd(20) - 10
dest(x).tz = rnd(20) - 10
dest(x).mode = "fly"
endif
endif
if dest(x).mode = "fly"
` make the necessary adjustments if the limb is flying
dest(x).my = dest(x).my - .1
dest(x).ax = dest(x).ax + dest(x).tx: dest(x).ay = dest(x).ay + dest(x).ty: dest(x).az = dest(x).az + dest(x).tz
dest(x).x = dest(x).x + dest(x).mx: dest(x).y = dest(x).y + dest(x).my: dest(x).z = dest(x).z + dest(x).mz
offset limb level.o, dest(x).l, dest(x).x, dest(x).y, dest(x).z
rotate limb level.o, dest(x).l, dest(x).ax, dest(x).ay, dest(x).az
endif
next x
set cursor 0,0
print screen fps()
wait 30
sync
loop
function makedestructable(obj,groundlimb)
`first make an invisible object for each limb
`to be used later for collision
obj = level.o
perform checklist for object limbs obj
lnum = checklist quantity() - 1
level.maxl = lnum
for l = 1 to lnum
if l <> groundlimb
dest(l).o = nextobj()
make object from limb dest(l).o, obj,l
color object dest(l).o, rgb(255,0,0)
hide object dest(l).o
endif
next l
for l = 1 to lnum
if l <> groundlimb
`the limb's center of rotation starts at 0,0,0, but we don't want this
`now use the vertex data for each limb to find the average center of the limb
`and use this to move the faces of the limb around the point 0,0,0
lock vertexdata for limb obj,l
num = get vertexdata vertex count()
for n = 0 to num-1
x#=x#+get vertexdata position x(n)
y#=y#+get vertexdata position y(n)
z#=z#+get vertexdata position z(n)
next n
x# = x#/num
y# = y#/num
z# = z#/num
for n = 0 to num-1
set vertexdata position n, get vertexdata position x(n) - x#, get vertexdata position y(n) - y#, get vertexdata position z(n) - z#
next n
unlock vertexdata
offset limb obj, l,x#,y#,z#
`now offset the limb to move it back to its original position
`only with its center of rotation in the middle of the limb
`instead of at 0,0,0
dest(l).l = l
dest(l).x = x#:dest(l).y = y#:dest(l).z = z#
dest(l).ax = 0:dest(l).ay = 0:dest(l).az = 0
dest(l).mx = 0:dest(l).my = 0:dest(l).mz = 0
dest(l).tx = 0:dest(l).ty = 0:dest(l).tz = 0
dest(l).mode = "sit"
endif
next l
endfunction
function nextobj()
n = 1
while object exist(n) = 1
n = n + 1
endwhile
endfunction n
This could be useful if you only want to make a collision check on one object for your environment.
I'll include the object I used to make it.