Creating Behaviors on the Fly

From Director Online Wiki
Jump to: navigation, search

To add a behavior instance to a sprite on the fly, you need to:

  • Create an instance of the behavior script
  • Add that instance to the sprite's scriptInstanceList
  • Set any properties that would have been set via the [getPropertyDescriptionList]] handler
  • Optionally, send a #beginSprite event to the sprite manually

Example

Here's a generic new() handler that will do all of this for you automatically, so long as you send it the right parameters:


-- PROPERTY DECLARATIONS --
property spriteNum
-- CONSTRUCTOR --
on new(me, aSprite, aPropList) ----------------------------------------
  -- INPUT: <aSprite> should be a sprite reference or spriteNum.  If
  --         not, it is assumed that this behavior is attached directly
  --         to a sprite at author-time, and no action is taken.
  --        <aPropList> may be a property list containing data similar
  --         to what the scriptList of the sprite would store if the
  --         behavior had been dropped on the sprite.
  -- ACTION: Creates an instance of this behavior and attaches it to
  --         sprite(aPropList.spriteNum). 
  ---------------------------------------------------------------------
 
  -- Check for a valid sprite
  case ilk(aSprite) of
    #integer:
      if aSprite < 1 or spriteNum > the lastChannel then
        -- Open the debugger window.  (Non fatal exceptions may be
        -- handled by an xCeption() handler in a Movie Script).
        return xCeption(#channel, "spriteNum out of range "&aSprite)
      end if
     
      spriteNum = aSprite
      aSprite   = sprite(spriteNum)
     
    #sprite:
      spriteNum = aSprite.spriteNum
     
    otherwise:
      -- Standard behavior?
      return me
  end case
 
  if ilk(aPropList, #propList) then
    -- Adopt properties in aPropList as if they were getPDL parameters
    i = aPropList.count()
   
    repeat while i
      vProp  = aPropList.getPropAt(i)
      vValue = aPropList[i]
     
      me[vProp] = vValue -- no test for correct type
     
      i = i - 1
    end repeat
  end if
 
  -- Add this behavior on the fly to the sprite...
  aSprite.scriptInstanceList.append(me)
  if me.handler(#beginSprite) then
    -- ... and initialize it
    me.beginSprite()
  end if
end new

Creating an instance on the fly

You can add this new() handler to any behavior. To add an instance of the behavior to a given sprite on the fly, you simply need to call the script like this:

script("My Behavior").new(sprite(1), [#customProperty: "custom value"])

This would have the same effect as dropping the behavior on the sprite at author-time, assuming it had a getPropertyDescriptionList handler similar to this:

on getPropertyDescriptionList(me)
  vPropertyList [:]
   
  vPropertyList[ \
#customProperty] = [ \
 #comment: "User defined string", \
 #format:  #string, \
 #default: "custom value"]
  return vPropertyList
end getPropertyDescriptionList

Points to note

  • In the new() handler above, #beginSprite is sent only to the new behavior instance, not to the sprite as a whole. Other behaviors already on the sprite will not receive this custom #beginSprite event. You may wish to change this.
  • There is no need to declare the properties defined in the getPropertyDescriptionList handler or the new handler above, so long as you refer to them using the me.propertyName syntax.

See also