
The code of this part is a simplification of a code by: Tom Higgins from Macromedia(available, with inspired demo, in the Macromedia site).
We will make the bullet go ahead from the avatar, in the direction he is walking. This direction we know: is fwvect.
Look the new avatarobj script (new code in bold face):
property fwvect
property upvect
property distanceforward
property steer
property ang, xvect,avatarheight
property pBullet
property pBulletList
property pGun
property val
--old code
global myworld
on new me
upvect = vector(0,1,0)
fwvect = vector(0,0,1)
distanceforward = 0
steer = 0
myworld.model("avatar").visibility = #none
myworld.model("avatar").translate(vector(0,0,0),#world)
xvect = vector(1,0,0)
ang = 0
avatarheight = 40
myworld.model("logo").addmodifier(#collision)
myworld.model("logo").collision.enabled = true
myworld.model("logo").collision.resolve = true
myworld.model("logo").collision.mode = #box
pBullet = myworld.model("bullet")
pBulletList = []
pGun = myworld.model("gun")
val=0
return me
end
on control me
if keypressed("r") then
val=0
end if
pBullet.transform=pGun.transform
if keypressed(49) AND val=0 then --49 is apace bar
me.firegun()
end if
--old code
if keypressed(126) then
acc = 2
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.3
if distanceforward < 0 then distanceforward = 0
if keypressed(125) then distanceforward = - 2
if distanceforward > 2 then distanceforward = 2
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)
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
--NEW
on fireGun (me)
val=val+1
-- clone the original bullet object
newBullet = pBullet.clone("bullet"&val)
if(val>1) then
myworld.model("bullet"&val).visibility = #none
end if
if(val=1) then
myworld.model("bullet1").addmodifier(#collision)
myworld.model("bullet1").collision.enabled = true
myworld.model("bullet1").collision.resolve = true
myworld.model("bullet1").collision.setCollisionCallback(#putDetails, me)
end if
bulletDirection = fwvect --bullet has the direction of avatar
-- spawn a script object that represents the bullet
thisBullet = new(script "bulletobj", newBullet, bulletDirection)
-- add that object to the bullet list
pBulletList.add(thisBullet)
end
on putDetails me, collisionData
if(collisionData.modelB.name="logo") then
--BOOM!!!!!!!!!!!!!!!!!
myworld.model("logo").visibility = #none
end if
end
on deleteBulletModel (me, thisBullet, thisObject)
beep
-- delete the referenced bullet model object
thisModelName = thisBullet.name
myworld.deleteModel(thisModelName)
end
-- old code
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
We have a totaly new script:bulletobj:
property pMyBullet
property pOriginalTransform
property pDestinationTransform
property pInterpolationPctg
on new (me, thisBulletModel, thisBulletDirection)
pMyBullet = thisBulletModel
pInterpolationPctg = 0
-- store a copy of the bullet's origin point transform
pOriginalTransform = pMyBullet.transform.duplicate()
-- move the bullet to a final possible position
pMyBullet.translate( (1000*thisBulletDirection), #world )
-- grab the final transform
pDestinationTransform = pMyBullet.transform.duplicate()
-- reset the bullet to its original transform
pMyBullet.transform = pOriginalTransform
-- register for stepFrame events in order to animate the bullet along its path
(the actorList).add(me)
-- return an object reference
return me
end new
on stepFrame (me)
-- calculate the new interpolation percentage
pInterpolationPctg = pInterpolationPctg + 5
-- if we haven't reached the end of the flight then interpolate the bullet
-- otherwise kill the bullet
if (pInterpolationPctg <= 100) then
-- make a copy of the original transform
currentTransform = pOriginalTransform.duplicate()
-- interpolate the current transform towards the final by the appropriate amount
currentTransform.interpolateTo(pDestinationTransform,pInterpolationPctg)
-- push this new current transform onto the bullet model
pMyBullet.transform = currentTransform.duplicate()
else
-- remove this item from the actorList
thisPosn = (the actorList).findPos(me)
(the actorList).deleteAt(thisPosn)
-- message the sprite to kill the bullet model and to remove this object
-- from its list of bullets
sendAllSprites(#deleteBulletModel,pMyBullet,me)
end if
end
We preserve most of the code from Tom Higgins. Perhaps, if we make a new code, we would do it a little different. But it's a good idea to copy good code from the masters :-)
Play the demo(again!). You need to destroy the plaque with the logo. To shoot press the space bar.To shoot again you need to recharge the bazooka pressing the r key!!!! You only can do this after the beep!!!! The demo has sound! Walk as usual, using the arrow keys.
PREVIOUS LESSON NEXT LESSON T. CONTENTS HOMEPAGE
