Creating Objects with Scripts

In order to create an object, Director 'compiles' the script-text of a script cast member (parent script, behaviour or movie script) into a 'script object'. Most of the time, you will be making new instances of this script object using the new keyword. For example:

-- Create a script object

ScriptObject = script("ScriptName")

-- create a new instance of this script object

InstanceObject = ScriptObject.new()

Usually, these two steps are compressed into single line:

InstanceObject = script("ScriptName").new()

When you create an object using the new function, Director will automatically pass a reference to the newly created object as the first parameter. By convention, this parameter is called 'me' - but you could label it anything you want. This reference acts like a pointer to the object and is used to address messages to the object.

By default, Director will return this reference to the newly created object when you use the new constructor. Be aware, however, that you can over-ride this behaviour by writing your own on new constructor.

on new (me)

  if SomeCondition() return me

  else return #Error

end

Note that you can also bypass the new constructor by using the Lingo function rawNew() which will create an instance without calling the new method of the script. This is only useful when dealing with ancestors (see later).

Creating Objects with Behaviours

If you are using behaviours, you don't have to explicitly create new instances of the behaviour script object: Director does this for you. When the playback head arrives at a frame with a new sprite, Director looks at the sprite's scriptList property. This is a list of script cast members and their starting parameters (a property list). Although you typically add scripts to this list by dragging 'behaviours' onto sprites and set the starting parameters using the getPropertyDescriptionList dialog, any sort of script cast member and starting parameters can be added using the setScriptList function.

Director then loops through this list and does the following with each item in the scriptList:

  • create a new instance of the script (you can trap this by including an On new method in your script); then
  • converts the 'starting parameter' string into a list and then assigns the property/values to the new object; and finally
  • calls the beginSprite method of this new object

If you were to reproduce how this works in lingo, you would write something like this:

  repeat with j = 1 to sprite(1).scriptList.count

    scrpAndParams= sprite(1).scriptList[j]

    scriptRef = value(scrpAndParams[1]).script

    startingParamers = value(scrpAndParams[2])

    newObject = scriptRef.new()

    repeat with i = 1 to startingParamers.count

      thisProp = startingParamers.getPropAt(i)

      thisValue = startingParamers.getAt(i)

      newObject.setAProp(thisProp, thisValue)

    end repeat

    sprite(1).scriptInstanceList.append(newObject)

    

  end repeat

  call(#beginSprite, sprite(1).scriptInstanceList)

Creating Objects with Movie Scripts

Whilst it is possible to create objects using moviescripts, there are a few important things to consider. Firstly, is the issue of 'scope'.

Movie scripts generally have a 'global scope' - meaning that functions contained in a movie script can be called without specifying the script object containing the function. When the movie is run (or when you hit 'compile all scripts' in Authoring), Director will automatically create script objects from movie script members. These are some sort of special 'global' script objects. Whenever you call a function - whether it is a built in function or one you have created - and you do not specify the object when you call that function, Director will look at all these 'global' movie script objects to see if there is one that has a handler for the function you called. Thus, if you type

foo()

in the message window, Director will look at all the movie script objects for one that has an "on foo() " handler. If you have two movie scripts with an "on foo()" handler, only the first one will get called.

There are two important ramifications for Director's auto-created special 'global movie script objects': Firstly, if you call a global function (without referencing the script object containing the handler), Director will not send a reference to the object as a parameter (in other words, the first parameter - often labeled 'me' - will not be included). This means that if you have a movie script like this

[Movie Script "test1"]

on foo (me)

  put "me: "& me.string

end

If you call the foo function without a reference to the script object, then the 'me' parameter will be void:

[Message Window]

foo()

-- "me: <VOID>"

However, if you call the foo function using a reference to the script object, then the 'me' parameter will be supplied:

script("test1").foo()

-- "me: <offspring "script1" 5 6fbc4e0>"

The other point to remember is that if you call a function without specifying which object has the function, Director will look first at all movie script objects before checking whether it is a built in function. This means if you have an "on new" handler in a movie script, and later you try to use the new() function (say, for example, to create a bitmap with newMember=new(#bitmap)), you will get a script error because Director will think you are trying to call your "on new" function.

First published 29/07/2005