SHOOTING - PART 2

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