
The secret tool to define collision of the avatar against anything is the method modelsUnderRay of the Director API. Its declaration is:
alist = myworld.modelsUnderRay(locationVector , directionVector , 5, #detailed)
For each object found we have a array with properties that can be called by name:
alist[i].name - the name of the object found
alist[i].distance - the distance from the position
of the avatar to the point of
intersection with the object.
alist[i].isectposition - is a vector representing the
position of the intersection.
alist[i].isectNormal - is the normal vector to the mesh
at the point of intersection.
Do you remember what is a normal to a surface? OK. Congratulations. Good hight school :-)
The idea is to create a method seekfloor that has the parameters:
This method returns an array with 3 elements:
This "return" is received at each loop and we need to translate and rotate the avatar.
Play the demo. All the codes are after the demo. Walking, look back to see that you are on the floor, going up or down.
OK.Play the demo (remember: the code is in this page, after the demo)
THE CODE:
The setupscript is the same.
In the avatarobj script we have the new method:
property fwvect
property upvect
property distanceforward
property steer
property ang, xvect,avatarheight
global myworld
on new me
upvect = vector(0, 1,0)
fwvect = vector(0,0,1)
xvect = vector(1,0,0)
distanceforward = 0
steer = 0
myworld.model("avatar").visibility = #none
myworld.model("avatar").translate(vector(0,0,0),#world) -- put it at a height above the ground
--for collision versus terrain
xvect = vector(1,0,0)
ang = 0
avatarheight = 15
--
return me
end
on control me
if keypressed(126) then
acc = 0.025
else
acc = 0
end if
if keypressed(123) then
turn = 2
else
if keypressed(124) then
turn = -2
else
turn = 0
end if
end if
distanceforward = distanceforward + acc - 0.015
if distanceforward < 0 then distanceforward = 0
if keypressed(125) then distanceforward = - 0.8
if distanceforward > 0.8 then distanceforward = 0.8
steer = (steer + turn)*0.8
if steer < -5.0 then steer = -5.0
if steer > 5.0 then steer = 5.0
myworld.model("avatar").transform.rotate(myworld.model("avatar").worldposition, upvect, steer)
rotator = transform()
rotator.rotate(vector(0,0,0), upvect, steer)
fwvect = rotator*fwvect
movement = ( fwvect*distanceforward )
myworld.model("avatar").translate(movement ,#world)
--for collision versus terrain
floordetails = seekfloor("avatar", "land", "world", avatarheight, upvect)
ang = 0
if floordetails[1] = 0 then
myworld.model("avatar").translate(-movement ,#world)
else
if floordetails[2] <> 0 then
xvect = floordetails[2]
ang = floordetails[3]
end if
end if
myworld.model("avatar").transform.rotate(myworld.model("avatar").worldposition, xvect, ang)
end
on seekfloor modelname, floorname, worldname, modelheight, directionvector
flag = 0
tiltangle = 0
tiltvector = 0
alist = myworld.modelsUnderRay(myworld.model(modelname).worldposition - directionvector*100 ,directionvector,5, #detailed)
repeat with i = 1 to count(alist)
if alist[i].model.name contains floorname then
a = alist[i].isectposition
av = vector(0,(-myworld.model(modelname).worldposition.y + alist[i].isectposition.y +modelheight ), 0)
myworld.model(modelname).translate(av, #world)
ay = -directionvector
tiltangle = -ay.anglebetween(alist[i].isectnormal)
tiltvector = alist[i].isectnormal.perpendicularto(ay)
flag = 1
exit repeat
end if
end repeat
return [flag, tiltvector, tiltangle]
end
The cameraobj script and all the other are the same of the previous lesson.
PREVIOUS LESSON NEXT LESSON T. CONTENTS HOMEPAGE
