ActorList

From Director Online Wiki
Jump to: navigation, search

If you add a script or a script instance to the actorList, it will receive a #stepFrame event once per frame. The stepFrame event is sent just before the new frame is displayed (see [FrameEvents] for more information on event timing).

Objects can be added to the actorList, and removed from it, on the fly. This means that the #stepFrame event is a good place to put code that you want to execute regularly for a limited period of time.

Examples

Dragging and dropping a sprite

Place a sprite behavior on the actorList on mouseDown, then use #stepFrame to place the sprite under the cursor. Remove the behavior from the actorList when the user releases the mouse.

Executing code once only

Suppose sprite A needs to communicate with others, which may be in higher-numbered channels. The other sprites may not be instantiated when the behavior on sprite A receive their beginSprite event. Solution: place the behavior on sprite A on the actorList on beginSprite, then execute the code that talks to the other sprites on stepFrame. Now remove the behavior on sprite A from the actorList.

Deleting an instance from the actorList

Sometimes it is useful to remove an object from the actorList during the stepFrame handler itself. This needs to be done carefully. Suppose the actorList looks like this:

 [script("a"), script("b"), script("c")]

Suppose all three scripts contain a stepFrame handler like this:

 on stepFrame(me)
    -- do some stuff
   (the actorList).deleteOne(me)
 end stepFrame

The stepFrame handler in script("b") will not be called until the next frame, after the stepFrame handler in script("c").

Why is this? Director sends the #stepFrame event to each item in the actorList in turn. After script("a") has removed itself from the actorList, script("b") is now the first item. But Director has already sent #stepFrame to the first item, so it now sends it to the second, which happens to be script("c"). In other words, after the first stepFrame event is sent to the actorList, the actorList will look like this:

 [script("b")]

It is only on the next frame that script("b") will receive its #stepFrame event.

This might not be a problem in some cases, but in others it will be important that the stepFrame handlers are called in the correct order. Here is how to ensure that this happens:

 on stepFrame(me)
    -- do some stuff
   RemoveFromActorList(me)
 end stepFrame


 on RemoveFromActorList(anInstance) -----------------------------------
   -- INPUT: <anInstance> is an object instance
   -- ACTION: When the #stepFrame event is sent to the actorList, it is
   --         sent to each instance in the list in turn, as counted by
   --         index number.  If the #stepFrame event is used to remove
   --         instance n from the list, the following instance will
   --         become instance n, but the #stepFrame event will be sent
   --         next to instance n+1, so the following instance will miss
   --         the event.  This handler passes the #stepFrame event
   --         manually to the next instance, if necessary.
   --------------------------------------------------------------------
   tIndex = the actorList.getPos(anInstance)
   if not tIndex then
     -- This instance is not currently on the actorList
     exit
   end if
   (the actorList).deleteAt(tIndex)
   if tIndex > the actorList.count() then
    -- This instance was the last instance on the actorList
   else
    -- The instance now at <tIndex> will not receive the #stepFrame
     -- event automatically.  Send it manually:
     call(#stepFrame, [the actorList[tIndex]])
   end if
 end RemoveFromActorList


You can put the RemoveFromActorList handler in a Movie Script, where it is available for all scripts and instances to use.

MIAWs

Each Movie In A Window or MIAW has its own actorList. The rate at which the #stepFrame event will be sent to the actorList will depend on the MIAW's frameTempo.

LDMs

Linked Director Movies (LDMs or #movie members) also have their own actorLists, but these do not receive a stepFrame event. If you need to use the actorList from within an LDM, you can use...

 tell the stage
   (the actorList).append(me)
 end tell

... where 'me' is a pointer to the object in question. The object will now receive #stepFrame events once per frame, depending on the frameTempo of the stage. Important note: the object will receive the event within the scope of the Stage (or the MIAW, if the LDM is in a MIAW). If the object makes any reference to sprites within the LDM, then you will need to provide it with some means of tell?ing the LDM sprite to perform any actions on these sprites.