ActiveEdit, ActiveTest, Add Life to the Web, Afterburner, Aftershock, Andromedia, Allaire, Animation PowerPack, Aria, Attain,
Authorware, Authorware Star, Backstage, Blue Sky Software, Blue Sky, Breeze, Bright Tiger, Clustercats, ColdFusion, Contents
Tab Composer, Contribute, Design In Motion, Director, Dream Templates, Dreamweaver, Drumbeat 2000, EDJE, EJIPT,
Extreme 3D, Fireworks, Flash, FlashHelp, Flash Lite, FlashPaper, Flex, Flex Builder, Fontographer, FreeHand, Generator, Help
To Source, HomeSite, Hotspot Studio, HTML Help Studio, JFusion, JRun, Kawa, Know Your Site, Knowledge Objects,
Knowledge Stream, Knowledge Track, LikeMinds, Lingo, Live Effects, MacRecorder Logo and Design, Macromedia,
Macromedia Action!, Macromedia Central, Macromedia Flash, Macromedia M Logo and Design, Macromedia Spectra,
Macromedia xRes Logo and Design, MacroModel, Made with Macromedia, Made with Macromedia Logo and Design, MAGIC
Logo and Design, Mediamaker, Movie Critic, Open Sesame!, RoboDemo, RoboEngine JFusion, RoboHelp, RoboHelp Office,
RoboInfo, RoboInsight, RoboPDF, 1-Step RoboPDF, RoboFlash, RoboLinker, RoboScreenCapture, ReSize, Roundtrip,
Roundtrip HTML, Shockwave, Sitespring, Smart Publishing Wizard, Software Video Camera, SoundEdit, Titlemaker,
UltraDev, Web Design 101, what the web can be, WinHelp, WinHelp 2000, WinHelp BugHunter, WinHelp Find+, WinHelp
Graphics Locator, WinHelp Hyperviewer, WinHelp Inspector, and Xtra are either registered trademarks or trademarks of
Macromedia, Inc. and may be registered in the United States or in other jurisdictions including internationally. Other product
names, logos, designs, titles, words, or phrases mentioned within this publication may be trademarks, service marks, or trade
names of Macromedia, Inc. or other entities and may be registered in certain jurisdictions including internationally.
Third-Party Information
This guide contains links to third-party websites that are not under the control of Macromedia, and Macromedia is not
responsible for the content on any linked site. If you access a third-party website mentioned in this guide, then you do so at your
own risk. Macromedia provides these links only as a convenience, and the inclusion of the link does not imply that Macromedia
endorses or accepts any responsibility for the content on those third-party sites.
Apple Disclaimer
APPLE COMPUTER, INC. MAKES NO WARRANTIES, EITHER EXPRESS OR IMPLIED, REGARDING THE
ENCLOSED COMPUTER SOFTWARE PACKAGE, ITS MERCHANTABILITY OR ITS FITNESS FOR ANY
PARTICULAR PURPOSE. THE EXCLUSION OF IMPLIED WARRANTIES IS NOT PERMITTED BY SOME STATES.
THE ABOVE EXCLUSION MAY NOT APPLY TO YOU. THIS WARRANTY PROVIDES YOU WITH SPECIFIC
LEGAL RIGHTS. THERE MAY BE OTHER RIGHTS THAT YOU MAY HAVE WHICH VARY FROM STATE TO
STATE.
This reference provides conceptual and how-to information about scripting in Macromedia
Director MX 2004, and also provides reference descriptions and examples for the scripting
application programming interfaces (APIs) that you use to write scripts.
The scripting APIs are the means by which you access the functionality of Director through
script to add interactivity to a movie. By using these APIs, you can create interactive functionality
that is identical to that provided by the prewritten behaviors that are shipped with Director, in
addition to functionality that is more powerful and more varied than that provided by the
prewritten behaviors.
The prewritten behaviors enable you to add basic interactive functionality to a movie, such as
moving the playhead to a frame number or marker, or zooming in when a user clicks a sprite.
They also enable non-interactive functionality such as sprite animation, media loading, and frame
navigation. The scripting APIs enable you to extend and customize these types of functionality.
Intended audience
This reference is intended for you if you want to do any of the following:
• Extend the existing functionality of prewritten behaviors by using script.
• Add functionality to a movie by using script instead of prewritten behaviors.
• Add more powerful, varied, and custom functionality to a movie than that provided by
prewritten behaviors.
This reference is intended to provide all the information, from basic to advanced, you need to add
interactivity to your movies by using script. Therefore, you do not need to have any prior
scripting experience to write effective scripts in Director.
Regardless of your experience level with Director, Lingo, or JavaScript syntax, take a few moments
to browse Chapter 2, “Director Scripting Essentials,” on page 9 and Chapter 3, “Writing Scripts
in Director,” on page 49 before you begin writing scripts. Like any product, Director has its own
unique set of scripting conventions, types of data, and so on. You will need to be comfortable
with these unique characteristics of Director before you can write effective scripts.
5
What’s new with Director scripting
If you have written scripts in previous versions of Director, you should note some new and
important changes about scripting in this latest release.
Dot syntax scripting format
In previous releases of Director, you could write Lingo scripts by using two types of syntax:
verbose syntax or dot syntax. Verbose syntax was very similar to English, and was relatively easy
for new programmers to learn. However, verbose syntax scripts quickly became long and complex,
and were difficult to debug.
Now that the scripting model of Director is compatible with both Lingo and JavaScript syntax,
scripts should be written only in dot syntax. Dot syntax will be familiar to many programmers,
since it is the syntax used in most object-oriented languages such as Java or C++, and in many
web-based scripting languages such as Microsoft JScript or JavaScript.
To support backwards compatibility, scripts written by using verbose syntax in previous versions
of Director will still run. However, starting with Director MX 2004, dot syntax is the
recommended syntax to use, and is the only syntax that will be supported and documented in
the future.
For more information on using dot syntax to write scripts, see “Scripting in dot syntax format”
on page 50.
JavaScript syntax compatibility
Director is now compatible with JavaScript syntax. This means that in addition to being able to
author and debug scripts by using Lingo, which is the long-time scripting language of Director,
you can choose to author and debug scripts by using JavaScript syntax. The implementation of
JavaScript in Director is referred to as JavaScript syntax throughout this reference.
The support of JavaScript syntax in Director helps create a scripting environment that is familiar
not only to JavaScript developers but also to developers experienced with Macromedia Flash
ActionScript, Macromedia Flash Communication Server, Macromedia Dreamweaver,
Macromedia Authorware, and a number of other environments.
The implementation of JavaScript syntax in Director is JavaScript 1.5, which means that it is fully
compliant with the ECMAScript Language Specification ECMA-262, 3rd Edition. Almost all of
the features and functionality in JavaScript 1.5 are now available in Director.
For more information on choosing Lingo or JavaScript syntax, see “Choosing between Lingo and
JavaScript syntax” on page 49.
Note: This reference is intended to only discuss the features and functionality of the JavaScript 1.5
implementation that are essential to writing JavaScript syntax scripts in Director. It is not intended to
provide a complete reference for JavaScript 1.5. For more detailed information on JavaScript 1.5 than
is provided in this reference, see one of the many third-party resources on the subject.
New ways to access the scripting APIs
In this release of Director, the scripting APIs have been grouped into objects, and are accessed
through these objects. These objects contain the functionality required to add interactivity to
your movies and are accessible to both Lingo and JavaScript syntax within Director, projectors,
and Macromedia Shockwave Player.
6Chapter 1: Introduction
Although the way you access the scripting APIs in this release may vary from previous releases,
you still have access to the same APIs that you did before, in addition to some brand new ones.
The only difference is that you access them by using the new objects.
For more information on the objects and their corresponding scripting APIs, see “Introducing the
Director objects” on page 51.
What’s new in this documentation
If you learned how to script in previous versions of Director, you should know about some
changes in the scripting documentation for this release. The Director Scripting Reference takes the
place of the Lingo Dictionary that was shipped with previous versions of Director. This reference is
organized differently than the Lingo Dictionary.
In the Lingo Dictionary, information about the scripting model was organized by feature.
For example, if you wanted to learn how to work with sprites in script, you looked up that
information in one of the sections under the Sprites heading, such as Dragging Sprites, Sprite
Dimensions, and so on. In addition, all of the scripting APIs were listed in a single alphabetical
list, which meant that all functions, properties, events, and so on were mixed together
alphabetically.
In the Director Scripting Reference, information about the scripting model is organized by object.
This organization closely reflects the organization of the actual scripting objects that you use in
your scripts. For example, if you want to find out how to work with sprites in script, you should
look for the Sprite section in the chapter, Director Core Objects.
The scripting APIs are still listed in alphabetical order, but they are categorized by API type. For
example, all methods are listed alphabetically under the Methods heading, all properties are listed
alphabetically under the Properties heading, and so on.
Finding information about scripting in Director
With its new organization, the Director Scripting Reference contains the following topics:
Director Scripting Essentials Provides information about the basic scripting concepts and
components you will use when scripting in Director.
Writing Scripts in Director Provides information about the Director scripting environment in
addition to advanced scripting concepts and techniques.
Debugging Scripts in Director Provides information about how to find problems in your
scripts when they are not performing as expected.
Director Core Objects Provides a list of the objects and APIs that you use to access the core
functionality and features in Director, such as the Director player engine, movie windows, sprites,
sounds, and so on.
Media Types Provides a list of the media types and APIs that you use to access the functionality
of the various media types in Director, such as RealMedia, DVD, Animated GIF, and so on, that
are added to movies as cast members.
Scripting Objects Provides a list of the scripting objects, also known as Xtra extensions, and
APIs that you use to extend core Director functionality. Xtra extensions provide capabilities such
as importing filters and connecting to the Internet.
3D Objects Provides a list of the objects you use to add 3D functionality to a movie.
Finding information about scripting in Director7
Constants Provides a list of the constants that are available in Director.
Events and Messages Provides a list of the events that are available in Director.
Keywords Provides a list of the keywords that are available in Director.
Methods Provides a list of the methods that are available in Director.
Operators Provides a list of the operators that are available in Director.
Properties Provides a list of the properties that are available in Director.
8Chapter 1: Introduction
CHAPTER 2
Director Scripting Essentials
If you are new to scripting in Macromedia Director MX 2004, you may want to take some time
to learn the basic scripting concepts that are essential to understanding how to script in Director
before you begin. Some of these essentials include definitions of important terms, syntax rules,
available data types, and information about the basic elements of scripting in Director—for
example, variables, arrays, operators, and so on.
Types of scripts
A Director movie can contain four types of scripts: behaviors, movie scripts, parent scripts, and
scripts attached to cast members. Behaviors, movie scripts, and parent scripts all appear as
independent cast members in the Cast window. A script attached to a cast member is associated
with that cast member in the Cast window and does not appear independently.
• Behaviors are scripts that are attached to sprites or frames in the Score, and are referred to as
sprite behaviors or frame behaviors. The Cast window thumbnail for each behavior contains a
behavior icon in the lower right corner.
When used in the Director Scripting Reference, the term behavior refers to any script that you
attach to a sprite or a frame. This differs from the behaviors that come in the Director Library
Palette. For more information on these behaviors, which are built into Director, see the Using
Director topics in the Director Help Panel.
All behaviors that have been added to a cast library appear in the Behavior inspector’s Behavior
pop-up menu. Other types of scripts do not appear there.
You can attach the same behavior to more than one location in the Score. When you edit a
behavior, the edited version is applied everywhere the behavior is attached in the Score.
• Movie scripts contain handlers that are available globally, or on a movie level. Event handlers in
a movie script can be called from other scripts in the movie as the movie plays.
A movie script icon appears in the lower right corner of the movie script’s Cast window
thumbnail.
Movie scripts are available to the entire movie, regardless of which frame the movie is in or
which sprites the user is interacting with. When a movie plays in a window or as a linked
movie, a movie script is available only to its own movie.
9
• Parent scripts are special scripts that contain Lingo that is used to create child objects. You can
use parent scripts to generate script objects that behave and respond similarly yet can still
operate independently of each other. A parent script icon appears in the lower right corner of
the Cast window thumbnail.
For information on using parent scripts and child objects, see “Object-oriented programming
with Lingo” on page 55.
JavaScript syntax does not use parent scripts or child objects; it uses regular JavaScript syntaxstyle object-oriented programming techniques. For information on object-oriented
programming in JavaScript syntax, see “Object-oriented programming with JavaScript syntax”
on page 65
• Scripts attached to cast members are attached directly to a cast member, independent of the
Score. Whenever the cast member is assigned to a sprite, the cast member’s script is available.
Unlike behaviors, movie scripts, and parent scripts, cast member scripts do not appear in the
Cast window. However, if Show Cast Member Script Icons is selected in the Cast Window
Preferences dialog box, cast members that have a script attached display a small script icon in
the lower left corner of their thumbnails in the Cast window.
Scripting terminology
Both Lingo and JavaScript syntax use some terms that are specific to each language, in addition to
some terms that are shared between each language.
Important scripting terms are listed here in alphabetical order. These terms are used throughout
the Director Scripting Reference, so it will help to understand these terms before moving forward.
• Constants are elements whose values do not change. For example, in Lingo, constants such as
TAB, EMPTY, and RETURN always have the same values, and cannot be modified. In JavaScript
syntax, constants such as
cannot be modified. You can also create your own custom constants in JavaScript syntax by
using the keyword
For more information on constants, see “Constants” on page 20.
Math.PI and Number.MAX_VALUE always have the same values, and
const.
• Events are actions that occur while a movie is playing. Events occur when a movie stops, a
sprite starts, the playhead enters a frame, the user types at the keyboard, and so on. All events
in Director are predefined, and always have the same meaning.
For more information on events, see “Events” on page 33.
• Expressions are any part of a statement that produces a value. For example, 2 + 2 is
an expression.
• Functions refer to either top-level functions or specific types of JavaScript syntax code.
A top-level function instructs a movie to do something while the movie is playing or returns a
value, but it is not called from any specific object. For example, you would call the top-level
list() function by using the syntax list(). Like a function, a method also instructs a movie
to do something while the movie is playing or returns a value, but it is always called from
an object.
A function is used in JavaScript syntax to represent an event handler, a custom object, a custom
method, and so on. The use of JavaScript functions in these cases is described in the applicable
topics later in this reference.
10Chapter 2: Director Scripting Essentials
• Handlers, or event handlers, are sets of statements within a script that run in response to a
specific event and subsequent message. When an event occurs, Director generates and sends
a corresponding message to scripts, and a corresponding handler runs in response to the
message. The names of handlers are always the same as the events and messages they
respond to.
Note: Although in JavaScript syntax an event is actually handled by a function, the term handler is
used generically throughout this reference to refer to both Lingo handlers and JavaScript syntax
functions that handle events.
For more information on handlers, see “Handlers” on page 35.
• Keywords are reserved words that have a special meaning. For example, in Lingo, the keyword
end indicates the end of a handler. In JavaScript syntax, the keyword var indicates that the
term following it is a variable.
• Lists (Lingo) or Arrays (JavaScript syntax) are ordered sets of values used to track and update
an array of data, such as a series of names or the values assigned to a set of variables. A simple
example is a list of numbers such as
[1, 4, 2].
For more information on using lists in both Lingo and JavaScript syntax, see “Linear lists and
property lists” on page 38.
For more information on using JavaScript syntax arrays, see “JavaScript syntax arrays”
on page 45.
• Messages are notices that Director sends to scripts when specific events occur in a movie. For
example, when the playhead enters a specific frame, the
Directors sends an
enterFrame message. If a script contains an enterFrame handler, the
statements within that handler will run, because the handler received the
If no scripts contain a handler for a message, the message is ignored in script.
For more information on messages, see “Messages” on page 34
enterFrame event occurs and
enterFrame message.
• Methods are terms that either instruct a movie to do something while the movie is playing or
return a value, and are called from an object. For example, you would call the
method from the Movie object, using the syntax
_movie.insertFrame(). Although similar in
functionality to top-level functions, methods are always called from an object, and top-level
functions are not.
insertFrame()
• Operators are terms that calculate a new value from one or more values. For example, the
addition (
For more information on operators, see “Operators” on page 25.
+) operator adds two or more values together to produce a new value.
• Parameters are placeholders that let you pass values to scripts. Parameters only apply to
methods and event handlers, and not to properties. They are required by some methods and
optional for others.
For example, the Movie object’s
optionally specifies the name of the movie that frame is in. To perform this task, the
method requires at least one parameter, and allows for a second parameter. The first required
parameter specifies what frame to send the playhead to, and the second optional parameter
specifies what movie the frame is in. Because the first parameter is required, a script error will
result if it is not present when the
optional, the method will perform its task even if the parameter is not present.
go() method sends the playhead to specific frame, and
go()
go() method is called. Because the second parameter is
Scripting terminology11
• Properties are attributes that define an object. For example, a sprite in a movie has specific
attributes, such as how wide it is, how tall it is, its background color, and so on. To access the
values of these three specific attributes, you would use the Sprite object’s
backColor properties.
width, height, and
For more information on assigning properties to variables, see “Storing and updating values in
variables” on page 21.
• Statements are valid instructions that Director can execute. All scripts are made up of sets of
statements. The following Lingo is a single complete statement.
_movie.go("Author")
For more information on writing script statements, see “Scripting in dot syntax format”
on page 50
• Variables are elements used to store and update values. Variables must start with a letter, an
underscore (
digits (0-9). To assign values to variables or change the values of many properties, you use the
equals (
For more information on using variables, see “Variables” on page 21.
_), or the dollar sign ($). Subsequent characters in a variable name can also be
=) operator.
Scripting syntax
The following are general syntax rules that apply to Lingo and JavaScript syntax.
• Comment markers vary between Lingo and JavaScript syntax.
All Lingo comments are preceded by double hyphens (
multiple lines must be preceded by double hyphens.
-- This is a single-line Lingo comment
--). Each line of a comment that covers
-- This is a
-- multiple-line Lingo comment
JavaScript syntax comments on a single line are preceded by a double-slash (//). Comments
that cover multiple lines are preceded with a
// This is a single-line JavaScript syntax comment
/* This is a
multiple-line JavaScript syntax comment */
You can place a comment on its own line or after any statement. Any text following the
comment markers on the same line are ignored.
Comments can consist of anything you want, such as notes about a particular script or handler
or notes about a statement whose purpose might not be obvious. Comments make it easier for
you or someone else to understand a procedure after you’ve been away from it for a while.
Adding large numbers of comments does not increase the size of your movie file when it is
saved as a compressed DCR or DXR file. Comments are removed from the file during the
compression process.
Comment markers can also be used to ignore sections of code you want to deactivate for
testing or debugging purposes. By adding comment markers rather than removing the code,
you can temporarily turn it into comments. Select the code you want to turn on or off, and
then use the Comment or Uncomment buttons in the Script window to quickly add or remove
comment markers.
12Chapter 2: Director Scripting Essentials
/* and followed by a */.
• Parentheses are required after all method and function names. For example, when calling the
Sound object’s
Otherwise, a script error will occur.
// JavaScript syntax
_sound.beep(); // this statement will work properly
_sound.beep; // this statement will result in a script error
When you call a method, function, or handler from within another method, function, or
handler, you must include parentheses in the calling statement. In the following example, the
modifySprite() method contains a call to a spriteClicked handler. The call to the
spriteClicked handler must include parentheses; otherwise, a script error occurs.
// JavaScript syntax
function modifySprite() {
spriteClicked(); // this call to the handler will work properly
spriteClicked; // this call to the handler results in a script error
}
function spriteClicked() {
// handler code here
}
You can also use parentheses to override the order of precedence in math operations, or to
make your statements easier to read. For example, the first math expression below yields a
result of 13, while the second expression yields a result of 5:
5 * 3 - 2 -- yields 13
5 * (3 - 2) -- yields 5
beep() method, you must include the parentheses after the word beep.
• Event handler syntax varies between Lingo and JavaScript syntax. In Lingo, handlers use the
syntax
on handlerName. In JavaScript syntax, handlers are implemented as functions, and use
the syntax
function handlerName(). For example, the following statements comprise a
handler that plays a beep when the mouse button is clicked:
-- Lingo syntax
on mouseDown
_sound.beep()
end
// JavaScript syntax
function mouseDown() {
_sound.beep();
}
• Event handler parameter syntax can vary between Lingo and JavaScript syntax. Both Lingo and
JavaScript syntax support enclosing parameters passed to a handler within parentheses. If more
than one parameter is passed, each parameter is separated by a comma. In Lingo, you can also
pass parameters that are not enclosed by parentheses. For example, the following
handler receives the two parameters
-- Lingo syntax
on addThem a, b -- without parentheses
c = a + b
end
a and b.
addThem
on addThem(a, b) -- with parentheses
c = a + b
end
// JavaScript syntax
function addThem(a, b) {
c = a + b;
}
Scripting syntax13
• The const keyword can be used in JavaScript syntax to specify a constant whose value does not
change. Lingo has its own predefined set of constants (
keyword
const does not apply to Lingo.
For example, the following statement specifies a constant named
to 12. This value will always be 12, and cannot be changed through script.
// JavaScript syntax
const intAuthors = 12;
TAB, EMPTY, and so on); therefore, the
intAuthors and sets its value
• The var keyword in JavaScript syntax can be placed in front of a term to specify that the term
is a variable. The following statement creates a variable named
// JavaScript syntax
var startValue = 0;
Note: Although using var in JavaScript syntax is optional, it is recommended that you always
declare local JavaScript syntax variables, or those inside a function, using var. For more
information on using variables, see “Variables” on page 21.
startValue.
• The line continuation symbol (\) in Lingo indicates that a long line of sample code has been
broken into two or more lines. Lines of Lingo that are broken in this way are not separate lines
of code. For example, the following code would still run.
JavaScript syntax does not include a line continuation symbol. To break multiple lines of
JavaScript syntax code, add a carriage return at the end of a line, and then continue the code on
the following line.
• Semicolons can be used to specify the end of a statement of JavaScript syntax code. Semicolons
do not apply to Lingo.
Using a semicolon is optional. If used, it is placed at the end of a complete statement. For
example, both of the following statements create a variable named
// JavaScript syntax
var startValue = 0
var startValue = 0;
startValue.
A semicolon does not necessarily specify the end of a line of JavaScript syntax code, and
multiple statements can be placed on one line. However, placing separate statements on
separate lines is recommended in order to improve readability. For example, the following
three statements occupy only one line of code and function properly, but it is difficult to
read the code.
// JavaScript syntax
_movie.go("Author"); var startValue = 0; _sound.beep();
• Character spaces within expressions and statements are ignored in both Lingo and JavaScript
syntax. In strings of characters surrounded by quotation marks, spaces are treated as characters.
If you want spaces in a string, you must insert them explicitly. For example, the first statement
below ignores the spaces between the list items, and the second statement includes the spaces.
• Case-sensitivity can vary between Lingo and JavaScript syntax.
Lingo is not case-sensitive in any circumstance—you can use uppercase and lowercase letters
however you want. For example, the following four statements are equivalent:
Although Lingo is not case-sensitive, it’s a good habit to choose a case convention and use it
consistently throughout your scripts. This makes it is easier to identify names of handlers,
variables, cast members, and so on.
JavaScript syntax is case-sensitive when referring to objects, the top level properties or methods
that refer to objects, or when referring to user-defined variables. For example, the top level
sprite() method returns a reference to a specific Sprite object, and is implemented in
Director with all lowercase letters. The first statement below refers to the name of the first
sprite in a movie, while the second and third statements result in a script error.
// JavaScript syntax
sprite(1).name // This statement functions normally
Sprite(1).name // This statement results in a script error
SPRITE(1).name // This statement results in a script error
Literal strings are always case-sensitive in both Lingo and JavaScript syntax.
For more information on using strings, see “Strings” on page 18.
Data types
A data type is a set of data with values that have similar, predefined characteristics. Every variable
and property value in Director is of a specific data type, and values returned by methods are of a
specific data type.
For example, consider the following two statements. In the first statement, variable
assigned a whole number value of 14, which is an integer. So, the data type of variable
integer. In the second statement, variable
which is a string. So, the data type of variable
stringX is assigned a sequence of character values,
stringX is string.
intX is
intX is
// JavaScript syntax
var intX = 14;
var stringX = "News Headlines";
The values that are returned by methods or functions are also of an inherent data type. For
example, the Player object’s
windowPresent() method returns a value that specifies whether a
window is present. The returned value is TRUE (1) or FALSE (0).
Data types15
Some data types are shared between Lingo and JavaScript syntax, and some data types are specific
to one language or another. The set of data types that Director supports is fixed and cannot be
modified, meaning that new data types cannot be added and existing data types cannot be
removed. Director supports the following data types.
Data typeDescription
# (symbol)A self-contained unit that can be used to represent a condition or flag. For example,
Array(JavaScript syntax only) Although not literally a data type, an Array object can be
BooleanA value that is
ColorRepresents an object’s color.
ConstantA piece of data whose value does not change.
DateAlthough not literally a data type, in JavaScript syntax a Date object can be used to
Float(Lingo only) A floating-point number. For example, 2.345 or 45.43.
Function(JavaScript syntax only) Although not literally a data type, a Function object can be
Integer(Lingo only) A whole number. For example, 5 or 298.
ListA linear or property list made up of values or property names and values,
Math(JavaScript syntax only) Although not literally a data type, a Math object can be
null(JavaScript syntax only) Denotes a variable whose value behaves as 0 in numeric
Number(JavaScript syntax only) Although not literally a data type, a Number object can be
ObjectAlthough not literally a data type, an Object object can be used to create a custom
PointA point on the Stage that has both a horizontal and vertical coordinate.
RectA rectangle on the Stage.
RegExp(JavaScript only) A regular expression pattern that is used to match character
StringA contiguous sequence of keyboard symbols or character values. For example,
#list or #word.
used to work with linear lists of values. The functionality of an Array object is similar
to that of the List data type in Lingo.
TRUE (1) or FALSE (0). In Lingo, all TRUE or FALSE values are simple
integer constants, 1 for
values are by default the actual Boolean
simple integer constants automatically when required in Director.
In Lingo,
syntax,
work with dates. In Lingo, use the date() method to create a Date object and work
with dates.
used to specify a string of code to run.
respectively.
used to perform mathematical functions.
contexts and as
used to represent numerical constants, such as a maximum value, not-a-number
(NaN), and infinity.
named container that contains data and methods that act on that data.
combinations in strings.
"Director" or "$5.00".
TRUE and FALSE can be either lowercase or uppercase. In JavaScript
true and false must always be lowercase.
TRUE, 0 for FALSE. In JavaScript syntax, all true or false
true or false values, but are converted to
FALSE in Boolean contexts.
16Chapter 2: Director Scripting Essentials
Data typeDescription
undefined(JavaScript syntax only) Denotes a variable that does not have a value.
VectorA point in 3D space.
VOID(Lingo only) Denotes an empty value.
Note: Many of the data types and objects that are specific to JavaScript syntax contain their own set
of methods and properties that can be used to further manipulate those types. While the Director Scripting Reference may refer to some of these methods and properties, it does not include complete
reference information about them. For more detailed information on these data types and objects,
and their methods and properties, see one of the many third-party resources on the subject.
The built-in properties in Director, such as the Cast object’s name property, can only be assigned
values that are the same data type as that of the property’s inherent data type. For example, the
Cast object’s
News Headlines. If you try to assign a value of a different data type to this property, such as the
name property’s inherent data type is a string, so the value must be a string such as
integer 20, a script error occurs.
If you create your own custom properties, their values can be of any data type, regardless of the
data type of the initial value.
Both Lingo and JavaScript syntax are dynamically typed. This means that you do not have to
specify the data type of a variable when you declare it, and data types are automatically converted
as needed while a script runs.
For example, the following JavaScript syntax initially sets the variable
later in the script it is set to a string. When the script runs, the date type of
myMovie to an integer, and
myMovie is converted
automatically.
-- Lingo syntax
myMovie = 15 -- myMovie is initially set to an integer
...
myMovie = "Animations" -- myMovie is later set to a string
// JavaScript syntax
var myMovie = 15; // myMovie is initially set to an integer
...
myMovie = "Animations"; // myMovie is later set to a string
Data types17
Literal values
A literal value is any part of a statement or expression that is to be used exactly as it is, rather than
as a variable or a script element. Literal values that you encounter in script are character strings,
integers, decimal numbers, cast member names and numbers, frame and movie names and
numbers, symbols, and constants.
Each type of literal value has its own rules.
Strings
Strings are words or groups of characters that script treats as regular words instead of as variables.
Strings must be enclosed in double quotation marks. For example, you might use strings to give
messages to the user of your movie or to name cast members. In the following statement,
and Greeting are both strings. Hello is the literal text being put into the text cast member;
Greeting is the name of the cast member.
-- Lingo syntax
member("Greeting").text = "Hello"
Similarly, if you test a string, double quotation marks must surround each string, as in the
following example:
-- Lingo syntax
if "Hello Mr. Jones" contains "Hello" then soundHandler
Both Lingo and JavaScript syntax treat spaces at the beginning or end of a string as a literal part of
the string. The following expression includes a space after the word to:
// JavaScript syntax
trace("My thoughts amount to ");
Although Lingo does not distinguish between uppercase and lowercase when referring to cast
members, variables, and so on, literal strings are case-sensitive. For example, the following two
statements place different text into the specified cast member, because
literal strings.
In Lingo, the string() function can convert a numerical value into a string. In JavaScript syntax,
the
toString() method can convert a numerical value into a string.
Note: Attempting to use the toString() method in JavaScript syntax on a null or undefined value
results in a script error. This is in contrast with Lingo, in which the
values, including those that are
VOID.
Hello and HELLO are
string() function works on all
Hello
Numbers
In Lingo, there are two types of numbers: integers and decimals.
An integer is a whole number, without any fractions or decimal places, in the range of
-2,147,483,648 and +2,147,483,647. Enter integers without using commas. Use a minus (
for negative numbers.
18Chapter 2: Director Scripting Essentials
-) sign
A decimal number, also called a floating-point number, or float, is any number that includes a
decimal point. In Lingo, the
floatPrecision property controls the number of decimal places
used to display these numbers. Director always uses the complete number, up to 15 significant
digits, in calculations; Director rounds any number with more than 15 significant digits in
calculations.
JavaScript syntax does not distinguish between integers and floating-point numbers, and merely
uses numbers. For example, the following statements illustrate that the number 1 is an integer in
Lingo and a number in JavaScript syntax, and that the decimal number 1.05 is a float in Lingo
and a number in JavaScript syntax:
// JavaScript syntax
trace(typeof(1)) // number
trace(typeof(1.05)) // number
In Lingo, you can convert a decimal to an integer by using the integer() function. You can
also convert an integer to a decimal by performing a mathematical operation on the integer, for
example, by multiplying an integer by a decimal. In JavaScript syntax, you can convert a string or
a decimal number to a whole number by using the
integer() function, parseInt() rounds down. For example, the following statement rounds
parseInt() function. As opposed to Lingo’s
off the decimal number 3.9 and converts it to the integer 4 (Lingo) and the number 3
(JavaScript syntax).
-- Lingo syntax
theNumber = integer(3.9) -- results in a value of 4
// JavaScript syntax
var theNumber = parseInt(3.9); // results in a value of 3
In Lingo, the value() function can convert a string into a numerical value.
You can also use exponential notation with decimal numbers: for example, -
123.4e+9.
In Lingo, you can convert an integer or string to a decimal number by using the
1.1234e-100 or
float()
function. In JavaScript syntax, you can convert a string to a decimal number by using the
parseFloat() function. For example, the following statement stores the value 3.0000 (Lingo)
and 3 (JavaScript syntax) in the variable
-- Lingo syntax
theNumber = float(3) -- results in a value of 3.0000
theNumber.
// JavaScript syntax
var theNumber = parseFloat(3) // results in a value of 3
Literal values19
Constants
A constant is a named value whose content never changes.
In Lingo, the predefined terms
are always the same. The predefined terms
TRUE, FALSE, VOID, and EMPTY are constants because their values
BACKSPACE, ENTER, QUOTE, RETURN, SPACE, and TAB
are constants that refer to keyboard characters. For example, to test whether the last key pressed
was the Space bar, use the following statement:
-- Lingo syntax
if _key.keyPressed() = SPACE then beep()
In JavaScript syntax, you can access predefined constants using some of the data types that are
unique to JavaScript syntax. For example, the Number object contains constants such as
Number.MAX_VALUE and Number.NaN, the Math object contains constants such as Math.PI and
Math.E, and so on.
Note: This reference does not provide in-depth information about the predefined constants in
JavaScript syntax. For more information on these constants, see one of the many third-party
resources on the subject.
In JavaScript syntax, you can also define your own custom constants by using the const keyword.
For example, the following statement creates a constant named
items, and assigns it a value of 20.
This value cannot be changed after it has been created.
// JavaScript syntax
const items = 20;
For more information on constants, see Chapter 9, “Constants,” on page 151.
Symbols
A symbol is a string or other value in Lingo that begins with the pound (
#) sign.
Symbols are user-defined constants. Comparisons using symbols can usually be performed very
quickly, providing more efficient code.
For example, the first statement below runs more quickly than the second statement:
In both Lingo and JavaScript syntax, convert a string to a symbol by using the
-- Lingo syntax
x = symbol("novice") -- results in #novice
symbol() method.
// JavaScript syntax
var x = symbol("novice"); // results in #novice
Convert a symbol back to a string by using the string() function (Lingo) or the toString()
method (JavaScript syntax).
-- Lingo syntax
x = string(#novice) -- results in "novice"
// JavaScript syntax
var x = symbol("novice").toString(); // results in "novice"
20Chapter 2: Director Scripting Essentials
In JavaScript syntax, you cannot compare symbols of the same name to determine whether they
refer to the same symbol. To compare symbols of the same name, you must first convert them to
strings by using the
toString() method, and then perform the comparison.
Variables
Director uses variables to store and update values. As the name implies, a variable contains a value
that can be changed or updated as a movie plays. By changing the value of a variable as the movie
plays, you can do things such as store a URL, track the number of times a user takes part in an
online chat session, record whether a network operation is complete, and many more options.
It is a good idea always to assign a variable a known value the first time you declare the variable.
This is known as initializing a variable. Initializing variables makes it easier to track and compare
the variable’s value as the movie plays.
Variables can be global or local. A local variable exists only as long as the handler in which it is
defined is running. A global variable can exist and retain its value as long as Director is running,
including when a movie branches to another movie. A variable can be global within an individual
handler, a specific script, or an entire movie; the scope depends on how the global variable is
initialized.
If you want a variable to be available throughout a movie, it is good practice to declare it in an
prepareMovie
ensures that the variable is available from the very start of the movie.
For more information on using both global and local variables, see “Using global variables”
on page 22 and “Using local variables” on page 24.
Storing and updating values in variables
Variables can hold data for any of the data types found in Director, such as integers, strings,
or
FALSE values, symbols, lists, or the result of a calculation. Use the equals (=) operator to store
the values of properties and variables.
As mentioned in the Data types section of this reference, variables in both Lingo and JavaScript
syntax are dynamically typed, which means that they can contain different types of data at
different times. (The ability to change a variable’s type distinguishes Lingo from other languages
such as Java and C++, in which a variable’s type cannot be changed.)
For example, the statement
assigned the variable an integer. If you subsequently use the statement
becomes a string variable, because the variable now contains a string.
You can convert a string to a number by using the
method (JavaScript syntax), or a number to a string by using the string() function (Lingo) or
the
toString() method (JavaScript syntax).
The values of some properties can be both set (the value is assigned) and returned (the value is
retrieved), and some property values can only be returned. Properties whose values can be both set
and returned are called read/write, and those that can only be returned are called read-only.
Often these are properties that describe some condition that exists outside the control of Director.
For example, you cannot set the
of channels within a movie that contains Macromedia Shockwave content. However, you
can return the number of channels by referring to the
(Lingo) or a function prepareMovie() (JavaScript syntax) handler. This
x = 1 creates the variable x, which is an integer variable because you
x = "one", the variable x
value() function (Lingo) or the parseInt()
numChannels cast member property, which indicates the number
numChannels property of a cast member.
on
TRUE
Variables21
To assign a value to a variable:
• Use the equals (=) operator.
For example, the following statement assigns a URL to the variable
// JavaScript syntax
var placesToGo = "http://www.macromedia.com";
Variables can also hold the results of mathematical operations. For example, the following
statement adds the result of an addition operation to the variable
-- Lingo syntax
mySum = 5 + 5 -- this sets mySum equal to 10
As another example, the following statement returns the cast member assigned to sprite 2 by
retrieving the value of the sprite’s
-- Lingo syntax
textMember = sprite(2).member
member property and places it into the variable textMember.
It is good practice to use variable names that indicate what the variable is used for. This makes
your scripts easier to read. For example, the variable
mySum indicates that the variable contains a
sum of numbers.
To test the values of properties or variables:
placesToGo:
mySum:
• Use the put() or the trace() functions in the Message window or check the values in the
Watch er wi ndow ; (
both Lingo and JavaScript syntax).
For example, the following statement displays the value assigned to the variable
Message window.
-- Lingo syntax
myNumber = 20 * 7
put(myNumber) -- displays 140 in the Message window
put() and trace() provide identical functionality and are available to
myNumber in the
// JavaScript syntax
var myNumber = 20 * 7;
trace(myNumber) // displays 140 in the Message window
Using global variables
Global variables can be shared among handlers, scripts, or movies. A global variable exists and
retains its value as long as Director is running or until you call the
clearGlobals() method.
In Macromedia Shockwave Player, global variables persist among movies displayed by the
goToNetMovie() method, but not among those displayed by the goToNetPage() method.
Every handler that declares a variable as global can use the variable’s current value. If the handler
changes the variable’s value, the new value is available to every other handler that treats the
variable as global.
It is good practice to start the names of all global variables with a lowercase g. This helps identify
which variables are global when you examine your code.
Director provides a way to display all current global variables and their current values and to clear
the values of all global variables.
22Chapter 2: Director Scripting Essentials
To display all current global variables and their current values:
• Use the Global object’s showGlobals() method in the Message window.
For more information on the Message window, see “Debugging in the Message window”
on page 87.
To clear all current global variables:
• Use the Global object’s clearGlobals() method in the Message window to set the value of all
global variables to
To monitor the values of global variables during movie playback, use the Object inspector. For
more information on the Object inspector, see “Debugging in the Object inspector” on page 91.
Global variables in Lingo
In Lingo, variables are considered local by default, and you do not need to precede the variable
name with any keyword. To declare a global variable, you must precede the variable with the
keyword
global.
If you declare a global variable at the top of a script and before any handlers, the variable is
available to all handlers in that specific script. If you declare a global variable within a handler, the
variable is available only to that handler; however, if you declare a global variable with the same
name within two separate handlers, an update to the variable’s value in one handler will also be
reflected in the variable in the other handler.
The following example illustrates working with two global variables:
to all handlers in the script, and
other handlers that declare it on the first line of the handler.
-- Lingo syntax
global gScript -- gScript is available to all handlers
VOID (Lingo) or undefined (JavaScript syntax).
gScript, which is available
gHandler, which is available within its defining handler and any
on mouseDown
global gHandler
gScript = 25
gHandler = 30
end
on mouseUp
global gHandler
trace(gHandler) -- displays 30
end
In Lingo, when you use the term global to define global variables, the variables automatically
have
VOID as their initial value.
Global variables in JavaScript syntax
In JavaScript syntax, variables are considered global by default. The scope of a global variable can
be determined by how and where it is declared.
• If you declare a variable within a JavaScript syntax function without preceding the variable
name with the keyword
script.
var, the variable is available to all functions within its containing
• If you declare a variable outside a JavaScript syntax function, with or without the keyword var,
the variable is available to all functions within its containing script.
Variables23
• If you declare a variable inside or outside a JavaScript syntax function by using the syntax
_global.varName, the variable is available to all scripts within a movie.
The following example uses the syntax
gMovie as global. This variable is available to all scripts within the movie.
// JavaScript syntax
_global.gMovie = 1; // Declare gMovie in one script
// Create a function in a separate script that operates on gMovie
function mouseDown() {
_global.gMovie++;
return(_global.gMovie);
}
The following example declares the global variable gScript in one script. This variable is
available only to functions within that script.
// JavaScript syntax
var gScript = 1; // Declare gScript in a script
// gScript is available only to functions in the script that defines it
function mouseDown() {
gScript++;
return(gScript);
}
In JavaScript syntax, when you define variables before any handlers, the variables automatically
have
undefined as their initial value.
Using local variables
A local variable exists only as long as the handler in which it is defined is running. However, after
a local variable is created, you can use the variable in other expressions or change its value while a
script is still within the handler that defined the variable.
Treating variables as local is a good idea when you want to use a variable only temporarily in one
handler. This helps you avoid unintentionally changing the value in another handler that uses the
same variable name.
_global.gMovie in one script to declare the variable
To create a local variable:
• In Lingo, assign the variable a value using the equals (=) operator.
• In JavaScript syntax, inside a function precede the variable name with the keyword var, and
then assign the variable a value using the equals operator.
Note: Because JavaScript syntax variables are global by default, if you attempt to declare a local
variable inside a function without using the keyword
behavior. Therefore, although using
local JavaScript syntax variables using
To display all current local variables in the handler:
var is optional, it is strongly recommended that you declare all
var to avoid any unexpected behavior.
var, your script could produce unexpected
• In Lingo only, use the showLocals() function.
In Lingo, you can use this method in the Message window or in handlers to help with debugging.
The result appears in the Message window. The
JavaScript syntax.
To monitor the values of local variables during movie playback, use the Object inspector. For
more information on the Object inspector, see “Debugging in the Object inspector” on page 91.
24Chapter 2: Director Scripting Essentials
showLocals() method does not apply to
Operators
Operators are elements that tell Lingo and JavaScript syntax scripts how to combine, compare, or
modify the values of an expression. Many of the operators in Director are shared between Lingo
and JavaScript syntax, and some are unique to each language.
Some types of operators include the following:
• Arithmetic operators (such as +, -, /, and *)
• Comparison operators (such as <, >, and >=), which compare two arguments
• Logical operators (not, and, or), which combine simple conditions into compound ones
• String operators (such as &, &&, and +), which join, or concatenate, strings of characters
Note: There are many more types of operators in JavaScript syntax than there are in Lingo,
and not all of them are covered in this reference. For more information on additional operators
in JavaScript 1.5, see one of the many third-party resources on the subject.
The items that operators act upon are called operands. In Lingo, there are only binary operators.
In JavaScript syntax, there are both binary and unary operators. A binary operator requires two
operands, one before the operator and one after the operator. A unary operator requires a single
operand, either before or after the operator.
In the following example, the first statement illustrates a binary operator, where the variables
and
y are operands and the plus (+) sign is the operator. The second statement illustrates a unary
For reference information on operators, see Chapter 13, “Operators,” on page 595.
i is the operand and ++ is the operator.
x
Understanding operator precedence
When two or more operators are used in the same statement, some operators take precedence over
others in a precise hierarchy to determine which operators to execute first. This is called the
operators’ precedence order. For example, multiplication is always performed before addition.
However, items in parentheses take precedence over multiplication. In the following example,
without parentheses the multiplication in this statement occurs first:
-- Lingo syntax
total = 2 + 4 * 3 -- results in a value of 14
When parentheses surround the addition operation, addition occurs first:
-- Lingo syntax
total = (2 + 4) * 3 -- results in a value of 18
Descriptions of the types of operators and their precedence order follow. Operators with higher
precedence are performed first. For example, an operator whose precedence order is 5 is
performed before an operator whose precedence order is 4. Operations that have the same order
of precedence are performed left to right.
Operators25
Arithmetic operators
Arithmetic operators add, subtract, multiply, divide, and perform other arithmetic operations.
Parentheses and the minus sign are also arithmetic operators.
OperatorEffectPrecedence
( )
-
*
mod
/
%
++
--
+
-
Note: In Lingo, when only integers are used in an operation, the result is an integer. Using integers
and floating-point numbers in the same calculation results in a floating-point number. In JavaScript
syntax, all calculations essentially result in floating-point numbers.
Groups operations to control precedence order.5
When placed before a number, reverses the sign of a number.5
Performs multiplication.4
(Lingo only) Performs modulo operation.4
Performs division.4
(JavaScript syntax only) Returns the integer remainder of dividing
two operands.
(JavaScript syntax only) Adds one to its operand. If used as a prefix
operator (
as a postfix operator (
adding one.
(JavaScript syntax only) Subtracts one from its operand. The return
value is analogous to that of the increment operator.
When placed between two numbers, performs addition.3
When placed between two numbers, performs subtraction.3
++x), returns the value of its operand after adding one. If used
x++), returns the value of its operand before
4
4
4
When dividing one integer by another does not result in a whole number, Lingo rounds the result
down to the nearest integer. For example, the result of
4/3 is 1. In JavaScript syntax, the actual
floating-point value, 1.333, is returned.
To force Lingo to calculate a value without rounding the result, use
values in an expression. For example, the result of
4/float(3) is 1.333.
float() on one or more
Comparison operators
Comparison operators compare two values and determine whether the comparison is true or false.
OperatorMeaningPrecedence
==
===
!=
26Chapter 2: Director Scripting Essentials
(JavaScript syntax only) Two operands are equal. If the operands are
not of the same data type, JavaScript syntax attempts to convert the
operands to an appropriate data type for the comparison.
(JavaScript syntax only) Two operands are equal and of the same
data type
(JavaScript syntax only) Two operands are not equal. If the operands
are not of the same data type, JavaScript syntax attempts to convert the
operands to an appropriate data type for the comparison.
1
1
1
OperatorMeaningPrecedence
!==
<>
<
<=
>
>=
=
(JavaScript syntax only) Two operands are not equal and/or not of the
same type
(Lingo only) Two operands are not equal1
The left operand is less than the right operand1
The left operand is less than or equal to the right operand1
The left operand is greater than the right operand1
The left operand is great than or equal to the right operand1
(Lingo only) Two operands are equal1
Assignment operators
Assignment operators assign a value to its left operand based on the value of its right operand.
With the exception of the basic assignment operator, equal (
=), all of the following shortcut
assignment operators apply only to JavaScript syntax.
OperatorMeaningPrecedence
=Equal1
x += y(JavaScript syntax only) x = x + y1
x -= y(JavaScript syntax only) x = x - y1
x *= y(JavaScript syntax only) x = x * y1
x /= y(JavaScript syntax only) x = x / y1
x %= y(JavaScript syntax only) x = x % y1
1
Logical operators
Logical operators test whether two logical expressions are true or false.
Use care when using logical operators and string operators in Lingo and JavaScript syntax. For
example, in JavaScript syntax
true, but in Lingo,
&& is a string operator that concatenates two strings and inserts a space
&& is a logical operator that determines whether two expressions are
between the two expressions.
OperatorEffectPrecedence
and
&&
or
||
not
!
(Lingo only) Determines whether both expressions are true4
(JavaScript syntax only) Determines whether both expressions are true 4
(Lingo only) Determines whether either or both expressions are true4
(JavaScript syntax only) Determines whether either or both expressions
are true
(Lingo only) Negates an expression5
(JavaScript syntax only) Negates an expression5
Operators27
4
The not (Lingo) or ! (JavaScript syntax) operator is useful for toggling a TRUE or FALSE value to
its opposite. For example, the following statement turns on the sound if it’s currently off and
turns off the sound if it’s currently on:
-- Lingo syntax
_sound.soundEnabled = not (_sound.soundEnabled)
Use care when using logical operators and string operators in Lingo and JavaScript syntax. For
example, in JavaScript syntax
true, but in Lingo,
&& is a string operator that concatenates two strings and inserts a space
&& is a logical operator that determines whether two expressions are
between the two expressions.
OperatorEffectPrecedence
&(Lingo only) Concatenates two strings2
+(JavaScript syntax only) Concatenates two string values and returns a
third string that is the union of the two operands
+=(JavaScript syntax only) Concatenates one string variable and one
string value, and assigns the returned value to the string variable
&&(Lingo only) Concatenates two strings and inserts a space between
the two
"Marks the beginning or end of a string.1
2
2
2
Conditional constructs
By default, Director always executes script statements starting with the first statement and
continuing in order until it reaches the final statement or a statement that instructs a script to go
somewhere else.
The order in which statements are executed affects the order in which you should place
statements. For example, if you write a statement that requires some calculated value, you need to
put the statement that calculates the value first.
The first statement in the following example adds two numbers, and the second statement assigns
a string representation of the sum to a field cast member named
Stage. The second statement could not be placed before the first statement because the variable
has not yet been defined.
// JavaScript syntax
var x = 2 + 2;
member("Answer").text = x.toString();
28Chapter 2: Director Scripting Essentials
Answer, which appears on the
x
Both Lingo and JavaScript syntax provide conventions for altering the default execution order or
script statements, and for performing actions depending on specific conditions. For example, you
may want to do the following in your scripts:
• Execute a set of statements if a logical condition is true, or execute alternate statements if the
logical condition is false.
• Evaluate an expression and attempt to match the expression’s value to a specific condition.
• Execute a set of statements repeatedly until a specific condition is met.
Testing for logical conditions
To execute a statement or set of statements if a specified condition is true or false, you use the
if...then...else (Lingo) or if...else (JavaScript syntax) structures. For example, you can
create an
if...then...else or if...then structure that tests whether text has finished
downloading from the Internet and, if it has, then attempts to format the text. These structures
use the following pattern to test for logical conditions:
• In both Lingo and JavaScript syntax, statements that check whether a condition is true or false
begin with the term
if.
• In Lingo, if the condition exists, the statements following the term then are executed. In
JavaScript syntax, curly brackets (
surround each individual
if, else, or else if statement.
{ }) take the place of the Lingo term then, and must
• In both Lingo and JavaScript syntax, if the condition does not exist, scripts skip to the next
statement in the handler using the term
else or else if.
• In Lingo, the term end if specifies the end of the if test. In JavaScript syntax, the if test ends
automatically, so there is no term that explicitly ends the test.
To optimize your script’s performance, test for the most likely conditions first.
The following statements test several conditions. The term
perform if previous conditions are false:
-- Lingo syntax
if _mouse.mouseMember = member(1) then
_movie.go("Cairo")
else if _mouse.mouseMember = member(2) then
_movie.go("Nairobi")
else
_player.alert("You’re lost.")
end if
else if specifies alternative tests to
// JavaScript syntax
if (_mouse.mouseMember = member(1)) {
_movie.go("Cairo");
}
else if (_mouse.mouseMember = member(2)) {
_movie.go("Nairobi");
}
else {
_player.alert("You’re lost.");
}
Conditional constructs29
When writing if...then structures in Lingo, you can place the statement or statements
following
carriage return after
then in the same line as then, or you can place them on their own line by inserting a
then. If you insert a carriage return, you must also include an end if
statement at the end of the if...then structure.
When writing
following
carriage return after
if structures in JavaScript syntax, you can place the statement or statements
if in the same line as if, or you can place them on their own line by inserting a
if.
For example, the following statements are equivalent:
-- Lingo syntax
if _mouse.mouseMember = member(1) then _movie.go("Cairo")
if _mouse.mouseMember = member(1) then
_movie.go("Cairo")
end if
// JavaScript syntax
if (_mouse.mouseMember = member(1)) { _movie.go("Cairo"); }
if (_mouse.mouseMember = member(1)) {
_movie.go("Cairo");
}
For reference information on using the if...then...else and if...else structures, see “if”
on page 209.
Evaluating and matching expressions
case (Lingo) or switch...case (JavaScript syntax) structures are shorthand alternatives to
The
using
if...then...else or if...then structures when setting up multiple branching
structures. The
than many
In Lingo, the condition to test for follows the term
case and switch...case structures are often more efficient and easier to read
if...then...else or if...then structures.
case in the first line of the case structure.
The comparison goes through each line in order until Lingo encounters an expression that
matches the test condition. When a matching expression is found, Director executes the Lingo
that follows the matching expression.
In JavaScript syntax, the condition to test for follows the term
structure. Each comparison in the test follows the term
Each
case comparison can be ended by using the optional term break. Including the term break
breaks the program out of the
switch structure and executes any statements following the
switch in the first line of the
case for each line that contains a test.
structure. If break is omitted, the following case comparison is executed.
A
case or switch...case structure can use comparisons as the test condition.
For example, the following case and switch...case structures test which key the user pressed
most recently and responds accordingly.
• If the user pressed A, the movie goes to the frame labeled Apple.
• If the user pressed B or C, the movie performs the specified transition and then goes to the
frame labeled Oranges.
30Chapter 2: Director Scripting Essentials
• If the user pressed any other letter key, the computer beeps.
Note: In JavaScript syntax, only one comparison can be made per case statement.
For reference information on using case structures, see “case” on page 203.
Repeating actions
In both Lingo and JavaScript syntax, you can repeat an action a specified number of times or
while a specific condition exists.
In Lingo, to repeat an action a specified number of times you use a
Specify the number of times to repeat as a range following
repeat with.
In JavaScript syntax, to repeat an action a specified number of times you use the
The
for structure takes three parameters: the first parameter typically initializes a counter
repeat with structure.
for structure.
variable, the second parameter specifies a condition to evaluate each time through the loop, and
the third parameter is typically used to update or increment the counter variable.
The
repeat with and for structures are useful for performing the same operation on a series of
objects. For example, the following loop makes Background Transparent the ink for sprites 2
through 10:
-- Lingo syntax
repeat with n = 2 to 10
sprite(n).ink = 36
end repeat
// JavaScript syntax
for (var n=2; n<=10; n++) {
sprite(n).ink = 36;
}
Conditional constructs31
The following example performs a similar action, but with decreasing numbers:
-- Lingo syntax
repeat with n = 10 down to 2
sprite(n).ink = 36
end repeat
// JavaScript syntax
for (var n=10; n>=2; n--) {
sprite(n).ink = 36;
}
In Lingo, to repeat a set of instructions as long as a specific condition exists, use the repeat
while
structure.
In JavaScript syntax, to repeat a set of instructions as long as a specific condition exists, use the
while structure.
For example, the following statements instruct a movie to beep continuously whenever the mouse
button is being pressed:
-- Lingo syntax
repeat while _mouse.mouseDown
_sound.beep()
end repeat
// JavaScript syntax
while (_mouse.mouseDown) {
_sound.beep();
}
Both Lingo and JavaScript syntax scripts continue to loop through the statements inside the loop
until the condition is no longer true, or until one of the statements sends the script outside the
loop. In the previous example, the script exits the loop when the mouse button is released because
the
mouseDown condition is no longer true.
In Lingo, to exit a loop, use the
In JavaScript syntax, to exit a loop you can use the term
exit repeat statement.
break. A loop also automatically exits
when a condition is no longer true.
For example, the following statements make a movie beep while the mouse button is pressed,
unless the mouse pointer is over sprite 1. If the pointer is over sprite 1, the script exits the
loop and stops beeping. The
rollover() method indicates whether the pointer is over the
specified sprite.
-- Lingo syntax
repeat while _mouse.stillDown
_sound.beep()
if _movie.rollOver(1) then exit repeat
end repeat
// JavaScript syntax
while (_mouse.stillDown) {
_sound.beep();
if (_movie.rollOver(1)) {
break;
}
}
For reference information on the repeat while and while structures, see “repeat while”
on page 220.
32Chapter 2: Director Scripting Essentials
Events, messages, and handlers
A key component to creating powerful, useful scripts is an understanding of the concepts and
functionality of events, messages, and handlers. Understanding the order in which events and
messages are sent and received will help you determine exactly when specific scripts or parts of
scripts should run. It will also help you debug scripts when specific actions are not occurring
when you expect them to occur.
When a movie plays, the following occurs:
1 Events occur in response to either a system or user-defined action
2 Messages that correspond to these events are sent to the scripts in a movie
3 Handlers within scripts contain the instructions that run when a specific message is received
The name of an event corresponds to the name of the message it generates, and the handler that
handles the event corresponds to both the event and the message. For example, when the event
named
mouseDown occurs, Director generates and sends to scripts a message named mouseDown,
which would in turn be handled by a handler named
mouseDown.
Events
There are two categories of events that occur when a movie plays:
• System events occur without a user interacting with the movie, and are predefined and
named in Director. For example, when the playhead enters a frame, when a sprite is clicked,
and so on.
• User-defined events occur in response to actions that you define. For example, you could
create an event that occurs when the background color of a sprite changes from red to blue,
when a sound has played five times, and so on.
Many system events, such as
in a predefined order while a movie is playing. Other system events, particularly mouse events
such as
mouseDown, mouseUp, and so on, do not necessarily occur automatically while a movie is
playing, but rather when a user triggers them.
For example, when a movie first starts, the
prepareFrame event always occurs second, and so on. However, the mouseDown and mouseUp
events may never occur in a movie unless a user triggers them by clicking the movie.
The following lists illustrate the system events that always occur during a movie, and the order in
which they occur.
prepareFrame, beginSprite, and so on, occur automatically and
prepareMovie event always occurs first, the
When the movie first starts, events occur in the following order:
1 prepareMovie
2 prepareFrame Immediately after the prepareFrame event, Director plays sounds, draws
sprites, and performs any transitions or palette effects. This event occurs before the
event. A
prepareFrame handler is a good location for script that you want to run before the
enterFrame
frame draws.
3 beginSprite This event occurs when the playhead enters a sprite span.
4 startMovie This event occurs in the first frame that plays.
Events, messages, and handlers33
When the movie encounters a frame, events occur in the following order:
1 beginSprite This event occurs only if new sprites begin in the frame.
2 stepFrame
3 prepareFrame
4 enterFrame After enterFrame and before exitFrame, Director handles any time delays
required by the tempo setting, idle events, and keyboard and mouse events.
5 exitFrame
6 endSprite This event occurs only if the playhead exits a sprite in the frame.
When a movie stops, events occur in the following order:
1 endSprite This event occurs only if sprites currently exist in the movie.
2 stopMovie
For reference information on the predefined system events in Director, see Chapter 10, “Events
and Messages,” on page 159.
Messages
To run the appropriate set of script statements at the right time, Director must determine what is
occurring in the movie and which statements to run in response to certain events.
Director sends messages to indicate when specific events occur in a movie, such as when sprites
are clicked, keyboard keys are pressed, a movie starts, the playhead enters or exits a frame, or a
script returns a certain result.
The general order in which messages are sent to objects is as follows:
1 Messages are sent first to behaviors attached to a sprite involved in the event. If a sprite has more
than one behavior attached to it, behaviors respond to the message in the order in which they
are attached to the sprite.
2 Messages are sent next to a script attached to the cast member assigned to the sprite.
3 Messages are then sent to behaviors attached to the current frame.
4 Messages are sent last to movie scripts.
Although you can define your own message names, most common events that occur in a movie
have built-in message names.
For reference information on the built-in messages in Director, see Chapter 10, “Events and
Messages,” on page 159.
Defining custom messages
In addition to using built-in message names, you can define your own messages and
corresponding handler names. A custom message can call another script, another handler, or
the statement’s own handler. When the called handler stops executing, the handler that called
it resumes.
A custom message and handler name must meet the following criteria:
• It must start with a letter.
• It must include alphanumeric characters only (no special characters or punctuation).
34Chapter 2: Director Scripting Essentials
• It must consist of one word or of several words connected by an underscore—no spaces
are allowed.
• It must be different from the name of any predefined Lingo or JavaScript syntax element.
Using predefined Lingo or JavaScript keywords for message and handler names can create
confusion. Although it is possible to explicitly replace or extend the functionality of a Lingo or
JavaScript element by using it as a message or handler name, this should be done only in certain
advanced situations.
When you have multiple handlers with similar functions, it is useful to give them names that have
similar beginnings so they appear together in an alphabetical listing, such as the listing that can be
displayed by the Edit > Find > Handler command.
Handlers
A handler is a set of statements within a script that runs in response to a specific event and
subsequent message. Although Director contains built-in events and messages, you must create
your own custom handlers for each event/message pair that you want to handle.
Deciding where to place handlers
You can place handlers in any type of script, and a script can contain multiple handlers. It’s a good
idea to group related handlers in a single place, though, for easier maintenance.
The following are some useful guidelines for many common situations:
• To associate a handler with a specific sprite, or to have a handler run in response to an action
on a specific sprite, put the handler in a behavior attached to the sprite.
• To set up a handler that should be available any time the movie is in a specific frame, put the
handler in a behavior attached to the frame.
For example, to have a handler respond to a mouse click while the playhead is in a frame,
regardless of where the click occurs, place a
behavior rather than in a sprite behavior.
mouseDown or mouseUp handler in the frame
• To set up a handler that runs in response to messages about events anywhere in the movie, put
the handler in a movie script.
• To set up a handler that runs in response to an event that affects a cast member, regardless of
which sprites use the cast member, put the handler in a cast member script.
Determining when handlers receive a message
After sending a message to scripts, Director checks for handlers in a definite order.
1 Director first checks whether a handler exists in the object from which the message was sent. If
a handler is found, the message is intercepted, and the script in the handler runs.
2 If no handler is found, Director then checks cast member, in ascending o rder, for any associated
movie scripts that might contain a handler for the message. If a handler is found, the message is
intercepted, and the script in the handler runs.
3 If no handler is found, Director then checks whether a frame script contains a handler for the
message. If a handler is found, the message is intercepted, and the script in the handler runs.
4 If no handler is found, Director then checks sprites, in ascending order, for any scripts
associated with the sprites that might contain a handler for the message. If a handler is found,
the message is intercepted, and the script in the handler runs.
Events, messages, and handlers35
After a handler intercepts a message, the message does not automatically pass on to the remaining
locations. However, in Lingo you can use the
pass() method to override this default rule and
pass the message to other objects.
If no matching handler is found after the message passes to all possible locations, Director ignores
the message.
The exact order of objects to which Director sends a message depends on the message. For
information on the sequence of objects to which Director sends specific messages, see the entry
for each message in Chapter 10, “Events and Messages,” on page 159.
Using parameters to pass values to a handler
By using parameters for values, you can give the handler exactly the values that it needs to use at a
specific time, regardless of where or when you call the handler in the movie. Parameters can be
optional or required, depending on the situation.
To create parameters for a handler:
• In Lingo, put the parameters after the handler name. In JavaScript syntax, put the parameters
within parentheses, and then put them after the handler name. Use commas to separate
multiple parameters.
When you call a handler, you must provide specific values for the parameters that the handler
uses. You can use any type of value, such as a number, a variable that has a value assigned, or a
string of characters. Values in the calling statement must be in the order that they follow in the
handler’s parameters, and they must be surrounded by parentheses.
In the following example, the variable assignment
passed the two values 2 and 4. The
addThem handler replaces the parameter placeholders a and b
with the two values passed to it, stores the result in the local variable
return to send the result back to the original method, which is then assigned to mySum.
Because 2 is first in the list of parameters, it is substituted for
is second in the list of parameters, it is substituted for
c = a + b;
return c; // returns the result to the calling statement
}
In Lingo, when you call a custom method from an object, a reference to the script object in
memory is always passed as an implied first parameter to the handler for that method. This means
that you must account for the script object reference in your handler.
36Chapter 2: Director Scripting Essentials
For example, consider that you wrote a custom sprite method named jump() that takes a single
integer as a parameter, and you placed the method in a behavior. When you call
jump() from a
sprite object reference, the handler must also include a parameter that represents the script object
reference, and not just the single integer. In this case, the implied parameter is represented by the
keyword
-- Lingo syntax
myHeight = sprite(2).jump(5)
on jump(me,a)
end
on jump(a)
end
me, but any term will work.
return a + 15 -- this handler works correctly, and returns 20
return a + 15 -- this handler does not work correctly, and returns 0
You can also use expressions as values. For example, the following statement substitutes 3+6 for a
and
8>2 (or 1, representing TRUE) for b, and would return 10:
-- Lingo syntax
mySum = addThem(3+6, 8>2)
In Lingo, each handler begins with the word on followed by the message that the handler should
respond to. The last line of the handler is the word
end, but this is optional.
In JavaScript syntax, each handler begins with the word
end. You can repeat the handler’s name after
function followed by the message that
the handler should respond to. The statements that comprise the handler are surrounded by
opening and closing brackets, as are all JavaScript syntax functions.
Returning results from handlers
Often, you want a handler to report some condition or the result of some action.
To return results from a handler:
• Use the keyword return to have a handler report a condition or the result of an action. For
example, the following
-- Lingo syntax
on findColor
return sprite(1).foreColor
end
// JavaScript syntax
function findColor() {
return(sprite(1).foreColor);
}
You can also use the keyword return by itself to exit from the current handler and return no
value. For example, the following jump handler returns nothing if the aVal parameter equals 5;
otherwise, it returns a value.
-- Lingo syntax
on jump(aVal)
if aVal = 5 then return
aVal = aVal + 10
return aVal
end
findColor handler returns the current color of sprite 1:
Events, messages, and handlers37
// JavaScript syntax
function jump(aVal) {
if(aVal == 5) {
return;
}
else {
aVal = aVal + 10;
return(aVal);
}
}
When you define a handler that returns a result, you must use parentheses after the handler when
you call it from another handler. For example, the statement
findColor
handler and then displays the result in the Message window.
put(findColor()) calls the on
Linear lists and property lists
In your scripts, you may want to track and update lists of data, such as a series of names or the
values assigned to a set of variables. Both Lingo and JavaScript syntax have access to linear lists
and property lists. In a linear list, each element in the list is a single value. In a property list, each
element in the list contains two values; the first value is a property name, and the second value is
the value associated with that property.
Because both Lingo and JavaScript syntax have access to linear and property lists, it is
recommended that you use linear lists and property lists if values in your code are shared between
Lingo and JavaScript syntax scripts.
If values in your code are used only in JavaScript syntax scripts, it is recommended that you use
JavaScript Array objects to work with lists of data. For more information on using arrays, see
“JavaScript syntax arrays” on page 45.
Creating linear lists
You create a linear list in one of the following ways:
• In Lingo, use either the top level list() function or the list operator ([ ]), using commas to
separate items in the list.
• In JavaScript syntax, use the top level list() function, using commas to separate items in
the list.
The index into a linear list always starts with 1.
When you use the top level
function. This function is useful when you use a keyboard that does not provide square brackets.
All of the following statements create a linear list of three names and assign it to a variable.
-- Lingo syntax
workerList = ["Bruno", "Heather", "Carlos"] -- using the Lingo list operator
workerList = list("Bruno", "Heather", "Carlos") -- using list()
// JavaScript syntax
var workerList = list("Bruno", "Heather", "Carlos"); // using list()
38Chapter 2: Director Scripting Essentials
list() function, you specify the list’s elements as parameters of the
You can also create empty linear lists. The following statements create empty linear lists.
-- Lingo syntax
workerList = [] -- using the Lingo list operator
workerList = list() -- using list() with no parameters
// JavaScript syntax
var workerList = list(); // using list() with no parameters
Creating property lists
You create a property list in one of the following ways:
• In Lingo, use either the top level propList() function or the list operator ([:]). When using
the list operator to create a property list, you can use a either a colon to designate name/value
elements and commas to separate elements in the list, or commas to both designate name/value
elements and to separate elements in the list.
• In JavaScript syntax, use the top level propList() function and insert commas to both
designate name/value elements and to separate elements in the list.
When you use the top level
parameters of the function. This function is useful when you use a keyboard that does not provide
square brackets.
Properties can appear more than once in a given property list.
All of the following statements create a property list with four property names—
propList() function, you specify the property list’s elements as
left, top,
// JavaScript syntax
var sprite1Loc = propList("left",400, "top",550, "right",500, "bottom",750);
You can also create empty property lists. The following statements create empty property lists.
-- Lingo syntax
sprite1Loc = [:] -- using the Lingo property list operator
sprite1Loc = propList() -- using propList() with no parameters
// JavaScript syntax
var sprite1Loc = propList(); // using propList() with no parameters
Setting and retrieving items in lists
You can set and retrieve individual items in a list. The syntax differs for linear and property lists.
To set a value in a linear list, do one of the following:
• Use the equals (=) operator.
• Use the setAt() method.
Linear lists and property lists39
The following statements illustrate defining the linear list workerList that contains one value,
Heather, and then adds Carlos as the second value in the list.
-- Lingo syntax
workerList = ["Heather"] -- define a linear list
workerList[2] = "Carlos" -- set the second value using the equal operator
workerList.setAt(2, "Carlos") -- set the second value using setAt()
// JavaScript syntax
var workerList = list("Heather"); // define a linear list
workerList[2] = "Carlos"; // set the second value using the equal operator
workerList.setAt(2, "Carlos"); // set the second value using setAt()
To retrieve a value in a linear list:
• Use the list variable followed by the number that indicates the value’s position in the list. Place
square brackets around the number.
• Use the getAt() method.
The following statements create the linear list
the list to the variable
-- Lingo syntax
workerList = ["Bruno", "Heather", "Carlos"] -- define a linear list
name2 = workerList[2] -- use bracketed access to retrieve "Heather"
name2 = workerList.getAt(2) -- use getAt() to retrieve "Heather"
// JavaScript syntax
var workerList = list("Bruno", "Heather", "Carlos");
var name2 = workerList[2] // use bracketed access to retrieve "Heather"
var name2 = workerList.getAt(2) // use getAt() to retrieve "Heather"
To set a value in a property list, do one of the following:
name2.
workerList, and then assign the second value in
• Use the equals (=) operator.
• In Lingo only, use the setaProp() method.
• Use dot syntax.
The following Lingo statement uses the equals operator to make
with the property
-- Lingo syntax
foodList = [:] -- define an empty property list
foodList[#Bruno] = "sushi" -- associate sushi with Bruno
Bruno.
The following Lingo statement uses setaprop() to make sushi the new value associated with
the property Bruno.
-- Lingo syntax
foodList = [:] -- define an empty property list
foodList.setaProp(#Bruno, "sushi") -- use setaProp()
sushi the new value associated
// JavaScript syntax
foodList = propList() -- define an empty property list
foodList.setaProp("Bruno", "sushi") -- use setaProp()
The following statements use dot syntax to set the value associated with Bruno from sushi to
teriyaki.
40Chapter 2: Director Scripting Essentials
-- Lingo syntax
foodList = [#Bruno:"sushi"] -- define a property list
trace(foodList) -- displays [#Bruno: "sushi"]
foodList.Bruno = "teriyaki" -- use dot syntax to set the value of Bruno
trace(foodList) -- displays [#Bruno: "teriyaki"]
// JavaScript syntax
var foodList = propList("Bruno", "sushi"); // define a property list
trace(foodList); // displays ["Bruno": "sushi"]
foodList.Bruno = "teriyaki" // use dot syntax to set the value of Bruno
trace(foodList) -- displays [#Bruno: "teriyaki"]
To retrieve a value in a property list, do one of the following:
• Use the list variable followed by the name of the property associated with the value. Place
square brackets around the property.
• Use the getaProp() or getPropAt() methods.
• Use dot syntax.
The following statements use bracketed access to retrieve the values associated with the properties
breakfast and lunch.
-- Lingo syntax
-- define a property list
foodList = [#breakfast:"Waffles", #lunch:"Tofu Burger"]
trace(foodList[#breakfast]) -- displays "Waffles"
trace(foodList[#lunch]) -- displays "Tofu Burger"
// JavaScript syntax
// define a property list
var foodList = propList("breakfast", "Waffles", "lunch", "Tofu Burger");
trace(foodList["breakfast"]); // displays Waffles
trace(foodList["lunch"]); // displays Tofu Burger
The following statements use getaProp() to retrieve the value associated with the property
breakfast, and getPropAt() to retrieve the property at the second index position in the list.
-- Lingo syntax
-- define a property list
foodList = [#breakfast:"Waffles", #lunch:"Tofu Burger"]
trace(foodList.getaProp(#breakfast)) -- displays "Waffles"
trace(foodList.getPropAt(2)) -- displays #lunch
// JavaScript syntax
// define a property list
var foodList = propList("breakfast", "Waffles", "lunch", "Tofu Burger");
trace(foodList.getaProp("breakfast")) // displays Waffles
trace(foodList.getPropAt(2)) // displays lunch
The following statements use dot syntax to access the values associated with properties in a
property list.
-- Lingo syntax
-- define a property list
foodList = [#breakfast:"Waffles", #lunch:"Tofu Burger"]
trace(foodList.breakfast) -- displays "Waffles"
// JavaScript syntax
// define a property list
var foodList = propList("breakfast", "Waffles", "lunch", "Tofu Burger");
trace(foodList.lunch); // displays Tofu Burger
Linear lists and property lists41
Checking items in lists
You can determine the characteristics of a list and the number of items the list contains by
using the following methods.
• To display the contents of a list, use the put() or trace() functions, passing the variable that
contains the list as a parameter.
• To determine the number of items in a list, use the count() method (Lingo only) or the
count property.
• To determine a list’s type, use the ilk() method.
• To determine the maximum value in a list, use the max() method.
• To determine the minimum value in a list, use the min() function.
• To determine the position of a specific property, use the findPos, findPosNear, or
getOne command.
The following statements use
-- Lingo syntax
workerList = ["Bruno", "Heather", "Carlos"] -- define a linear list
trace(workerList.count()) -- displays 3
trace(workerList.count) -- displays 3
// JavaScript syntax
var workerList = list("Bruno", "Heather", "Carlos"); // define a linear list
trace(workerList.count); // displays 3
The following statements use ilk() to determine a list’s type.
count() and count to display the number of items in a list.
// JavaScript syntax
var x = list("1", "2", "3");
trace(x.ilk()) // returns #list
The following statements use max() and min() to determine the maximum and minimum values
in a list.
-- Lingo syntax
workerList = ["Bruno", "Heather", "Carlos"] -- define a linear list
trace(workerList.max()) -- displays "Heather"
trace(workerList.min()) -- displays "Bruno"
// JavaScript syntax
var workerList = list("Bruno", "Heather", "Carlos"); // define a linear list
trace(workerList.max()); // displays Heather
trace(workerList.min()); // displays Bruno
The following statements use findPos to get the index position of a specified property in a
property list.
-- Lingo syntax
-- define a property list
foodList = [#breakfast:"Waffles", #lunch:"Tofu Burger"]
trace(foodList.findPos(#lunch)) -- displays 2
// JavaScript syntax
// define a property list
var foodList = propList("breakfast", "Waffles", "lunch", "Tofu Burger");
trace(foodList.findPos("breakfast")); // displays 1
42Chapter 2: Director Scripting Essentials
Adding and deleting items in lists
You can add or delete items in a list by using the following methods.
• To add an item at the end of a list, use the append() method.
• To add an item at its proper position in a sorted list, use the add() or addProp() methods.
• To add an item at a specific place in a linear list, use the addAt() method.
• To add an item at a specific position in a property list, use the addProp() method.
• To delete an item from a list, use the deleteAt(), deleteOne(), or deleteProp() methods.
• To replace an item in a list, use the setAt() or setaProp() methods.
The following statements use
-- Lingo syntax
workerList = ["Bruno", "Heather", "Carlos"] -- define a linear list
workerList.append("David")
trace(workerList) -- displays ["Bruno", "Heather", "Carlos", "David"]
// JavaScript syntax
var workerList = list("Bruno", "Heather", "Carlos"); // define a linear list
workerList.append("David");
trace(workerList); // displays ["Bruno", "Heather", "Carlos", "David"]
The following statements use addProp() to add a property and an associated value to a
property list.
-- Lingo syntax
-- define a property list
foodList = [#breakfast:"Waffles", #lunch:"Tofu Burger"]
foodList.addProp(#dinner, "Spaghetti") -- adds [#dinner: "Spaghetti"]
append() to add an item to the end of a list.
// JavaScript syntax
// define a property list
var foodList = propList("breakfast", "Waffles", "lunch", "Tofu Burger");
foodList.addProp("dinner", "Spaghetti"); // adds ["dinner": "Spaghetti"]
You do not have to explicitly remove lists. Lists are automatically removed when they are no
longer referred to by any variable. Other types of objects must be removed explicitly, by setting
variables that refer to them to
VOID (Lingo) or null (JavaScript syntax).
Copying lists
Assigning a list to a variable and then assigning that variable to a second variable does not make a
separate copy of the list. For example, the first statement below creates a list that contains the
names of two continents, and assigns the list to the variable
assigns the same list to a new variable
to
landList also automatically adds Australia to the list continentList. This happens
continentList. In the third statement, adding Australia
landList. The second statement
because both variable names point to the same list object in memory. The same behavior occurs
by using an array in JavaScript syntax.
-- Lingo syntax
landList = ["Asia", "Africa"]
continentList = landList
landList.add("Australia") -- this also adds "Australia" to continentList
Linear lists and property lists43
To create a copy of a list that is independent of another list:
• Use the duplicate() method.
For example, the following statements create a list and then make an independent copy of the list.
-- Lingo syntax
oldList = ["a", "b", "c"]
newList = oldList.duplicate() -- makes an independent copy of oldList
// JavaScript syntax
var oldList = list("a", "b", "c");
var newList = oldList.duplicate(); // makes an independent copy of oldList
After newList is created, editing either oldList or newList has no effect on the other.
Sorting lists
Lists are sorted in alphanumeric order, with numbers being sorted before strings. Strings are
sorted according to their initial letters, regardless of how many characters they contain. Sorted
lists perform slightly faster than unsorted lists.
A linear list is sorted according to the values in the list. A property list is sorted according to the
property names in the list or array.
After the values in a linear or property list are sorted, they will remain sorted, even as values are
added to or removed from the lists.
To sort a list:
• Use the sort() method.
For example, the following statements sort a nonsorted alphabetical list.
// JavaScript syntax
var oldList = list("d", "a", "c", "b");
oldList.sort(); // results in ["a", "b", "c", "d"]
Creating multidimensional lists
You can also create multidimensional lists that enable you to work with the values of more than
one list at a time.
In the following example, the first two statements create the separate linear lists
list1 and list2.
The third statement creates a multidimensional list and assigns it to mdList. To access the values
in a multidimensional list, the fourth and fifth statements use brackets to access the values in the
list; the first bracket provides access to a specified list, and the second bracket provides access to
the value at a specified index position in the list.
// JavaScript syntax
var list1 = list(5,10);
var list2 = list(15,20);
var mdList = list(list1, list2);
trace(mdList[1][2]); // displays 10
trace(mdList[2][1]); // displays 15
JavaScript syntax arrays
JavaScript syntax arrays are similar to Lingo-style linear lists in that each element in an array is a
single value. One of the main differences between JavaScript syntax arrays and Lingo-style linear
lists is that the index into an array always starts with 0.
You create a JavaScript syntax array by using the Array object. You can use either square brackets
(
[ ]) or the Array constructor to create an array. The following two statements create an array
with two values.
// JavaScript syntax
var myArray = [10, 15]; // using square brackets
var myArray = new Array(10, 15); // using the Array constructor
You can also create empty arrays. The following two statements create an empty array.
// JavaScript syntax
var myArray = [];
var myArray = new Array();
Note: The Director Scripting Reference does not include a complete reference for JavaScript syntax
Array objects. For more complete information on using Array objects, see one of the many third-party
resources on the subject.
Checking items in arrays
You can determine the characteristics of an array and the number of items the array contains by
using the following methods.
• To display the contents of a list, use the put() or trace() function, passing the variable that
contains the list as a parameter.
• To determine the number of items in an array, use the Array object’s length property.
• To determine an array’s type, use the constructor property.
The following example illustrates determining the number of items in an array using the
length property, and then returning the type of object using the constructor property.
// JavaScript syntax
var x = ["1", "2", "3"];
trace(x.length) // displays 3
trace(x.contructor == Array) // displays true
Adding and deleting items in arrays
You can add or delete items in an array by using the following methods:
• To add an item at the end of an array, use the Array object’s push() method.
• To add an item at its proper position in a sorted array, use the Array object’s splice() method.
• To add an item at a specific position in an array, use the Array object’s splice() method.
JavaScript syntax arrays45
• To delete an item from an array, use the Array object’s splice() method.
• To replace an item in an array, use the Array object’s splice() method.
The following example illustrates using the Array object’s
delete items from, and replace items in an array.
// JavaScript syntax
var myArray = new Array("1", "2");
trace(myArray); displays 1,2
myArray.push("5"); // adds the value "5" to the end of myArray
trace(myArray); // displays 1,2,5
myArray.splice(3, 0, "4"); // adds the value "4" after the value "5"
trace(myArray); // displays 1,2,5,4
myArray.splice(3, 2); // delete two values at index positions 3 and 4
trace(myArray); // displays 1,2,3
myArray.splice(2, 1, "7"); // replaces one value at index position 2 with "7"
trace(myArray); displays 1,2,7
Copying arrays
Assigning an array to a variable and then assigning that variable to a second variable does not
make a separate copy of the array.
For example, the first statement below creates an array that contains the names of two continents,
and assigns the array to the variable
new variable
automatically adds
continentList. In the third statement, adding Australia to landList also
Australia to the array continentList. This happens because both variable
landList. The second statement assigns the same list to a
names point to the same Array object in memory.
// JavaScript syntax
var landArray = new Array("Asia", "Africa");
var continentArray = landArray;
landArray.push("Australia"); // this also adds "Australia" to continentList
splice() method to add items to,
To create a copy of an array that is independent of another array:
• Use the Array object’s slice() method.
For example, the following statements create an array and then use
independent copy of the array.
// JavaScript syntax
var oldArray = ["a", "b", "c"];
var newArray = oldArray.slice(); // makes an independent copy of oldArray
After newArray is created, editing either oldArray or newArray has no effect on the other.
46Chapter 2: Director Scripting Essentials
slice() to make an
Sorting arrays
Arrays are sorted in alphanumeric order, with numbers being sorted before strings. Strings are
sorted according to their initial letters, regardless of how many characters they contain.
To sort an array:
• Use the Array object’s sort() method.
The following statements sort a non-sorted alphabetical array.
// JavaScript syntax
var oldArray = ["d", "a", "c", "b"];
oldArray.sort(); // results in a, b, c, d
The following statements sort a non-sorted alphanumeric array.
// JavaScript syntax
var oldArray = [6, "f", 3, "b"];
oldArray.sort(); // results in 3, 6, b, f
Sorting an array results in a new sorted array.
Creating multidimensional arrays
You can also create multidimensional arrays that enable you to work with the values of more than
one array at a time.
In the following example, the first two statements create the separate arrays
The third statement creates a multidimensional array and assigns it to
values in a multidimensional array, the fourth and fifth statements use brackets to access the
values in the array; the first bracket provides access to a specified array, and the second bracket
provides access to value at a specified index position in the array.
// JavaScript syntax
var array1 = new Array(5,10);
var array2 = [15,20];
var mdArray = new Array(array1, array2);
trace(mdArray[0][1]); // displays 10
trace(mdArray[1][0]); // displays 15
array1 and array2.
mdArray. To access the
JavaScript syntax arrays47
48Chapter 2: Director Scripting Essentials
CHAPTER 3
Writing Scripts in Director
Scripts in Macromedia Director MX 2004 support all kinds of functionality in movies that would
not be possible otherwise. As you write scripts, you may find the need for increasingly advanced
scripts to support complex interactivity in your Director movies. Intermediate and advanced
scripting concepts and techniques are presented here, including information about objectoriented scripting in Director.
If you are new to scripting in Director, make sure to read Chapter 2, “Director Scripting
Essentials,” on page 9 in addition to the topics here.
Choosing between Lingo and JavaScript syntax
Both Lingo and JavaScript syntax provide access to the same objects, events, and scripting APIs.
Therefore, it does not necessarily matter which language you choose to write your scripts. Your
choice might be as simple as deciding which language you have the most knowledge of and are
most comfortable with.
To understand how scripting languages typically work with a given object and event model in
Director, consider the following:
• In general, a given scripting language, such as Lingo or JavaScripts syntax, is wrapped around a
given object and event model in order to provide access to those objects and events.
• JavaScript is an implementation of the ECMAScript standard that is wrapped around a web
browser’s object and event model to provide access to the browser’s objects and events.
• ActionScript is an implementation of the ECMAScript standard that is wrapped around the
Macromedia Flash object and event model to provide access to Flash objects and events.
• The Director implementation of JavaScript syntax is an implementation of ECMAScript that
is wrapped around the Director object and event model to provide access to Director objects
and events.
• Lingo is a custom syntax that is wrapped around the Director object and event model to
provide access to Director objects and events.
Lingo and JavaScript syntax are the two languages you can use to access the same Director object
and event model. Scripts written in one language have the same capabilities as scripts written in
the other language.
49
Therefore, after you know how to access the scripting APIs in one language, you essentially know
how to access them in the other language. For example, JavaScript syntax code can access Lingo
data types such as symbols, linear lists, property lists, and so on, create and invoke Lingo parent
scripts and behaviors, create and invoke Xtra extensions, and use Lingo string chunk expressions.
Also, both JavaScript syntax and Lingo scripts can be used within a single movie; however, a single
script cast member can contain only one syntax or the other.
There are two main differences between Lingo and JavaScript syntax:
• Each language contains some terminology and syntax conventions that are unique to each
language. For example, the syntax for an event handler is different in Lingo than it is in
JavaScript syntax:
-- Lingo syntax
on mouseDown
...
end
// JavaScript syntax
function mouseDown() {
...
}
For more information on the terminology and syntax conventions used for each language, see
“Scripting terminology” on page 10 and “Scripting syntax” on page 12.
• Some of the scripting APIs are accessed slightly differently in each language. For example,
you would use different constructs to access the second word in the first paragraph of a text
cast member:
Whether you write scripts in Lingo or JavaScript syntax, you write them by using the dot syntax
format. You use dot syntax to access the properties or methods related to an object. A dot syntax
statement begins with a reference to an object, followed by a period (dot), and then the name of
the property, method, or text chunk that you want to specify. Each dot in a statement essentially
represents a move from a higher, more general level in the object hierarchy to a lower, more
specific level in the object hierarchy.
For example, the following statement first creates a reference to the cast library named "News
Stories", and then uses dot syntax to access the number of cast members in that cast library.
To identify chunks of text, include terms after the dot to refer to more specific items within text.
For example, the first statement below refers to the first paragraph of the text cast member named
"News Items". The second statement below refers to the second word in the first paragraph.
For certain objects that handle cascading property access to either data or a specific cast member
type, as illustrated in the previous two statements, access to the properties is not supported by
using normal JavaScript syntax. Therefore, you must use the
getPropRef() and getProp()
methods to access cascading properties in JavaScript syntax.
There are a few things to note about this JavaScript syntax exception:
• This technique must be applied to 3D objects, text cast members, field cast members, and
XML Parser Xtra extensions accessed by using JavaScript syntax.
• You must use the getPropRef() method to store a reference to one of the previously
mentioned objects or its properties by using JavaScript syntax.
• You must use the getProp() method to retrieve a property value of one of the previously
mentioned objects or its properties by using JavaScript syntax.
• 3D objects and properties must be accessed by using their fully qualified names in JavaScript
syntax. For example, in Lingo, the property
shaderList[1]. However, in JavaScript syntax, the property shaderList[1] must be used at
all times.
shader can be used as a shortcut for the property
Introducing the Director objects
In basic terms, objects are logical groupings of named data that also can contain methods that act
on that data. In this release of Director, the scripting APIs have been grouped into objects and are
accessed through these objects. Each object provides access to a specific set of named data and
type of functionality. For example, the Sprite object provides access to the data and functionality
of a sprite, the Movie object provides access to the data and functionality of a movie, and so on.
The objects used in Director fall into the following four categories. Depending on the type of
functionality you want to add and the part of a movie you are adding functionality to, you will
use the objects from one or more of these categories:
• Core objects
• Media types
• Scripting objects
• 3D objects
Introducing the Director objects51
Core objects
This category of objects provides access to the core functionality and features available in
Director, such as the Director player engine, movie windows, sprites, sounds, and so on. They
represent the base layer through which all APIs and other object categories are accessed.
There are also a group of top-level methods and properties that enable you to access all of the core
objects directly, instead of having to traverse the object hierarchy to access a specific core object.
For a reference of the available core objects and their APIs, see Chapter 5, “Director Core
Objects,” on page 101.
Media types
This category of objects provides access to the functionality of the various media types, such as
RealMedia, DVD, Animated GIF, and so on, which are added to movies as cast members.
Literally, media types are not actually objects, but rather cast members that are of a specific type
of media. When a media type is added to a movie as a cast member, it not only inherits the
functionality of the core Member object, it also extends the Member object by providing
additional functionality that is available only to the specified media type. For example, a
RealMedia cast member has access to the Member object’s methods and properties, but it also has
additional methods and properties that are specific to RealMedia. All other media types also
exhibit this behavior.
For a reference of the available media types and their APIs, see Chapter 6, “Media Types,”
on page 119.
Scripting objects
This category of objects, also known as Xtra extensions, provides access to the functionality of the
software components, such as XML Parser, Fileio, SpeechXtra, and so on, that are installed with
Director and extend core Director functionary. The preexisting Xtra extensions provide
capabilities such as importing filters and connecting to the Internet. If you know the C
programming language, you can create your own custom Xtra extensions.
For a reference of the available scripting objects and their APIs, see Chapter 7, “Scripting
Objects,” on page 137.
3D objects
This category of objects provides access to the functionality of the cast members and text that are
used to create 3D movies.
For more information about 3D movies, see the Using Director topics in the Director Help Panel.
For a reference of the available 3D objects and their APIs, see Chapter 8, “3D Objects,”
on page 141.
52Chapter 3: Writing Scripts in Director
Object model diagrams
The following diagrams illustrate the basic high-level relationships between the object groups and
their hierarchies within Director. For information on object creation, properties and methods,
and other APIs, see the relevant API reference topics.
Object model diagrams53
Top level functions and properties
There are a number of top level functions and properties that provide direct access to the core
objects and functionality in Director. You will likely make extensive use of many of these
functions and properties as you create references to core objects, new images, lists, and so on. For
example, the top level
list() function creates a linear list.
The following tables list the top level functions and properties.
Top level functions
castLib()randomVector()
channel() (Top level)rect()
color()script()
date() (formats), date() (System)showLocals()
image()sound()
isBusy()sprite()
list()symbol()
member()timeout()
point()trace()
propList()vector()
put()window()
random()xtra()
_movie property refers directly to the core Movie object, and the top level
Top level properties
_global_player
_key_sound
_mouse_system
_movie
Introduction to object-oriented programming in Director
By using either Lingo or JavaScript syntax, you can apply object-oriented programming principles
to your scripts. Applying object-oriented principles typically makes programming easier by letting
you write less code and letting you use simpler logic to accomplish tasks, in addition to increasing
the reusability and modularity of your code.
Depending on the scripting language you are using, you apply these principles using two
different paradigms:
• In Lingo, you use parent scripts, ancestor scripts, and child objects to simulate object-oriented
programming.
• In JavaScript syntax, you use standard JavaScript-style object-oriented programming
techniques to create classes and subclasses.
54Chapter 3: Writing Scripts in Director
Each paradigm enables you to apply the advantages of object-oriented programming to your
scripts, so it does not really matter which scripting language you are using. You merely apply the
principles in different ways.
Because each scripting language uses a different paradigm to apply object-oriented principles, the
techniques described for one language won’t work in the other language. Therefore, you only
need to read the content that applies to the scripting language you are using:
• For more information on simulating object-oriented programming in Lingo, see “Object-
oriented programming with Lingo” on this page.
• For more information on object-oriented programming in JavaScript syntax, see “Object-
oriented programming with JavaScript syntax” on page 65.
Object-oriented programming with Lingo
In Lingo, parent scripts provide the advantages of object-oriented programming. You can use
parent scripts to generate script objects that behave and respond similarly yet can still operate
independently of each other.
You can create multiple copies (or instances) of a parent script by using Lingo. Each instance of a
parent script is called a child object. You can create child objects on demand as the movie plays.
Director does not limit the number of child objects that can be created from the same parent
script. You can create as many child objects as the computer’s memory can support.
Director can create multiple child objects from the same parent script, just as Director can create
multiple instances of a behavior for different sprites. You can think of a parent script as a template
and of child objects as implementations of the parent template.
The discussion about Lingo parent scripts and child objects describes the basics of how to write
parent scripts and create and use child objects, and also provides script examples. It does not teach
fundamental object-oriented programming concepts; however, to use parent scripts and child
objects successfully, you must understand object-oriented programming principles. For an
introduction to the basics of object-oriented programming, see one of the many third-party
resources on that subject.
Similarity to other object-oriented languages
If you are familiar with an object-oriented programming language such as Java or C++, you may
already understand the concepts that underlie parent scripting but know them by different names.
Terms that Director uses to describe parent scripts and child objects correspond to the following
common object-oriented programming terms:
Parent scripts in Director correspond to classes in object-oriented programming.
Child objects in Director correspond to instances in object-oriented programming.
Property variables in Director correspond to instance variables or member variables in object-
oriented programming.
Handlers in Director correspond to methods in object-oriented programming.
Ancestor scripts in Director correspond to the Super class or base class in object-oriented
programming.
Object-oriented programming with Lingo55
Parent script and child object basics
In Lingo, a parent script is a set of handlers and properties that define a child object; it is not a
child object itself. A child object is a self-contained, independent instance of a parent script.
Children of the same parent have identical handlers and properties, so child objects in the same
group can have similar responses to events and messages.
Typically, parent scripts are used to build child objects that make it easier to organize movie logic.
These child objects are especially useful when a movie requires the same logic to be run several
times concurrently with different parameters. You can also add a child object to a Sprite object’s
scriptInstanceList or the Movie object’s actorList as a way to control animation.
Because all the child objects of the same parent script have identical handlers, those child objects
respond to events in similar ways. However, because each child object maintains independent
values for the properties defined in the parent script, each child object can behave differently than
its sibling objects—even though they are instances of the same parent script.
For example, you can create a parent script that defines child objects that are editable text fields,
each with its own property settings, text, and color, regardless of the other text fields’ settings.
By changing the values of properties in specific child objects, you can change any of these
characteristics as the movie plays without affecting the other child objects based on the same
parent script.
Similarly, a child object can have a property set to either
TRUE or FALSE regardless of that
property’s setting in sibling child objects.
A parent script refers to the name of a script cast member that contains the property variables
and handlers. A child object created from a parent script is essentially a new instance of the script
cast member.
Differences between child objects and behaviors
While child objects and behaviors are similar in that they both can have multiple instances, they
have some important differences as well. The main difference between child objects and behaviors
is that behaviors are associated with locations in the Score because they are attached to sprites.
Behavior objects are automatically created from initializers stored in the Score as the playhead
moves from frame to frame and encounters sprites with attached behaviors. In contrast, child
objects from parent scripts must be created explicitly by a handler.
Behaviors and child objects differ in how they become associated with sprites. Director
automatically associates a behavior with the sprite that the behavior is attached to, but you must
explicitly associate a child object with a sprite. Child objects do not require sprite references and
exist only in memory.
Ancestor basics
Parent scripts can declare ancestors, which are additional scripts whose handlers and properties a
child object can call on and use.
Ancestor scripting lets you create a set of handlers and properties that you can use and reuse for
multiple parent scripts.
56Chapter 3: Writing Scripts in Director
A parent script makes another parent script its ancestor by assigning the script to its ancestor
property. For example, the following statement makes the script What_Everyone_Does an
ancestor to the parent script in which the statement occurs:
When handlers and properties are not defined in a child object, Director searches for the handler
or property in the child’s ancestors, starting with the child’s parent script. If a handler is called or
a property is tested and the parent script contains no definition for it, Director searches for a
definition in the ancestor script. If a definition exists in the ancestor script, that definition is used.
A child object can have only one ancestor at a time, but that ancestor script can have its own
ancestor, which can also have an ancestor, and so on. This lets you create a series of parent scripts
whose handlers are available to a child object.
Writing a parent script
A parent script contains the code needed to create child objects and define their possible actions
and properties. First, you must decide how you want the child objects to behave. Then, you can
write a parent script that does the following:
• Optionally declares any appropriate property variables; these variables represent properties for
which each child object can contain a value independent of other child objects.
• Sets up the initial values of the child objects’ properties and variables in the on new handler.
• Contains additional handlers that control the child objects’ actions.
Declaring property variables
Each child object created from the same parent script initially contains the same values for its
property variables. A property variable’s value belongs only to the child object it’s associated with.
Each property variable and its value persists as long as the child object exists. The initial value for
the property variable is typically set in the
on new handler; if it’s not set, the initial value is VOID.
To declare a property variable:
• Use the property keyword at the beginning of the parent script.
To set and test property variables from outside the child object:
• Set and test property variables in the same way you would any other property in your scripts,
by using the syntax
For example, the following statement sets the
car1.speed = 55
Creating the new handler
Each parent script typically uses an
when another script issues a
specified parent script to create a child object from itself. The
can also set the child object’s initial property values, if you want.
The
on new handler always starts with the phrase on new, followed by the me variable and any
parameters being passed to the new child object.
objectRef.propertyName.
speed property of an object car1:
on new handler. This handler creates the new child object
new(script parentScriptName) command, which tells the
on new handler in the parent script
Object-oriented programming with Lingo57
The following on new handler creates a new child object from the parent script and initializes the
child’s
spriteNum property with the value passed to it in the aSpriteNum parameter. The return
statement returns the child object to the handler that originally called the on new handler.
me
-- Lingo syntax
property spriteNum
on new me, aSpriteNum
spriteNum = aSpriteNum
return me
end
For more information on calling the on new handlers, see “Creating a child object” on page 59.
Adding other handlers
You determine a child object’s behavior by including in the parent script the handlers that
produce the desired behavior. For example, you could add a handler to make a sprite
change color.
The following parent script defines a value for the property
handler that changes the
-- Lingo syntax
property spriteNum
on new me, aSpriteNum
spriteNum = aSpriteNum
return me
end
on changeColor me
spriteNum.foreColor = random(255)
end
foreColor property of the sprite.
spriteNum, and contains a second
Referring to the current object
Typically, one parent script creates many child objects, and each child object contains more than
one handler. The special parameter variable
me tell the handlers in a child object that they are to
operate on the properties of that object and not on the properties of any other child object. This
way, when a handler within a child object refers to properties, the handler uses its own child
object’s values for those properties.
The term
parent script. It is always important to define
me must always be the first parameter variable stated in every handler definition in a
me as the first parameter for parent scripts and to
pass the same parameter if you need to call other handlers in the same parent script, since these
will be the handlers in each of the script’s child objects.
When referring to properties defined in ancestor scripts, you must use the
me parameter as the
source of the reference. This is because the property, while defined in the ancestor script, is
nevertheless a property of the child object. For example, the following statement uses
to an object and access properties defined in an ancestor of the object:
-- Lingo syntax
x = me.y -- access ancestor property y
Because the variable me is present in each handler of a child object, it indicates that all the
handlers control that same child object.
58Chapter 3: Writing Scripts in Director
me to refer
Creating a child object
Child objects exist entirely in memory; they are not saved with a movie. Only parent and ancestor
scripts exist on disk.
To create a new child object, you use the
new() method and assign the child object a variable
name or position in a list so you can identify and work with it later.
To create a child object and assign it to a variable, use the following syntax.
The scriptName parameter is the name of the parent script, and parameter1, parameter2, ...
are any parameters you are passing to the child object’s
creates a child object whose ancestor is
scriptName. It then calls the on new handler in the child
on new handler. The new() method
object with the specified parameters.
You can issue a
initial settings by changing the values of the parameters passed with the
new() statement from anywhere in a movie. You can customize the child object’s
new() statement.
Each child object requires only enough memory to record the current values of its properties and
variables and a reference to the parent script. Because of this, in most cases, you can create and
maintain as many child objects as you require.
You can produce additional child objects from the same parent script by issuing additional
new() statements.
You can create child objects without immediately initializing their property variables by using the
rawNew() method. The rawNew() method does this by creating the child object without calling
the parent script’s
rawNew() allows you to create the objects ahead of time and defer the assignment of property
on new handler. In situations where large numbers of child objects are needed,
values until each object is needed.
The following statement creates a child object from the parent script Car without initializing its
property variables and assigns it to the variable
-- Lingo syntax
car1 = script("Car").rawNew()
car1:
To initialize the properties of one of these child objects, call its on new handler:
car1.new
Checking child object properties
You can check the values of specific property variables in individual child objects by using a
simple
objectName.propertyName syntax. For example, the following statement assigns the
variable
-- Lingo syntax
x = car1.carSpeed
x the value of the carSpeed property of the child object in the variable car1:
Querying object properties from outside the objects themselves can be useful for getting
information about groups of objects, such as the average speed of all the car objects in a racing
game. You might also use the properties of one object to help determine the behavior of other
objects that are dependent on it.
Object-oriented programming with Lingo59
In addition to checking the properties that you assign, you can check whether a child object
contains a specific handler or find out which parent script an object came from. This is useful
when you have objects that come from parent scripts that are similar but that have subtle
differences.
For example, you may want to create a scenario in which one of several parent scripts might be
used to create a child object. You can then determine which parent script a particular child object
came from by using the
The following statements check whether the object
named
Car:
-- Lingo syntax
if car1.script = script("Car") then
_sound.beep()
end if
script() function, which returns the name of an object’s parent script.
car1 was created from the parent script
You can also get a list of the handlers in a child object by using the handlers() method, or check
whether a particular handler exists in a child object by using the
The following statement places a list of the handlers in the child object
myHandlerList:
-- Lingo syntax
myHandlerList = car1.handlers()
handler() method.
car1 into the variable
The resulting list would look something like this:
[#start, #accelerate, #stop]
The following statements use the handler() method to check whether the handler on
accelerate
-- Lingo syntax
if car1.handler(#accelerate) then
put("The child object car1 contains the handler named on accelerate.")
end if
exists in the child object car1:
Removing a child object
You can remove a child object from a movie by setting all variables that contain a reference to the
child object to another value. If the child object has been assigned to a list, such as
actorList,
you must also remove the child object from the list.
To remove a child object and the variables that refer to it:
• Set each variable to VOID.
Director deletes the child object when there are no more references to it. In the following
example,
ball1 contains the only reference to a specific child object, and it is set to VOID to delete
the object from memory.
-- Lingo syntax
ball1 = VOID
To remove an object from actorList:
• Use the delete() method to delete the item from the list.
60Chapter 3: Writing Scripts in Director
Using scriptInstanceList
You can use the
Normally,
scriptInstanceList property to dynamically add new behaviors to a sprite.
scriptInstanceList is the list of behavior instances created from the behavior
initializers defined in the Score. If you add child objects created from parent scripts to this list, the
child objects receive the messages sent to other behaviors.
For example, the following statement adds a child object to the
When a child object is added to scriptInstanceList, you must initialize the child object’s
spriteNum property. Typically, you do this from a parameter passed in to the on new handler.
Note: The beginSprite message is not sent to dynamically added child objects.
For reference information on scriptInstanceList, see “scriptInstanceList” on page 975.
Using actorList
You can set up a special list of child objects (or any other objects) that receives its own message
each time the playhead enters a frame or the
The special list is
actorList, which contains only objects that have been explicitly added to
updateStage() method updates the Stage.
the list.
The message is the
updateStage() command is used.
Objects in
actorList receive a stepFrame message instead of an enterFrame message at each
stepFrame message that is sent only when the playhead enters a frame or the
frame. If the objects have an on stepFrame handler available, the script in the handler runs each
time the playhead enters a new frame or the
Some possible uses of
actorList and stepFrame are to animate child objects that are used as
updateStage() method updates the Stage.
sprites or to update a counter that tracks the number of times the playhead enters a frame.
An
on enterFrame handler could achieve the same results, but the actorList property and
stepFrame handler are optimized for performance in Director. Objects in actorList respond
more efficiently to
stepFrame messages than to enterFrame messages or custom messages sent
after an updateStage() method.
Object-oriented programming with Lingo61
To add an object to the actorList:
• Use the actorList property as follows, where childObject is a reference to the child object
to add:
-- Lingo syntax
_movie.actorList.add(childObject)
The object’s stepFrame handler in its parent or ancestor script then runs automatically each
time the playhead advances. The object is passed as the first parameter,
stepFrame
Director does not clear the contents of
handler.
actorList when branching to another movie, which can
me, to the on
cause unpredictable behavior in the new movie. If you do not want child objects in the current
movie to be carried over into the new movie, insert a statement that clears
prepareMovie
To clear child objects from actorList:
handler of the new movie.
actorList in the on
• Set actorList to [ ], which is an empty list.
For reference information on
Creating timeout objects
A timeout object is a script object that acts like a timer and sends a message when the timer
expires. This is useful for scenarios that require specific things to happen at regular time intervals
or after a particular amount of time has elapsed.
Timeout objects can send messages that call handlers inside child objects or in movie scripts. You
create a timeout object by using the
handler to be called, and the frequency with which you want the handler to be called. After a
timeout object is created, Director keeps a list of currently active timeout objects, called
timeOutList.
The syntax described below is necessary for all new movies authored in Director MX 2004, or for
older movies playing in Director MX 2004 whose
to a value of 10. Movies authored in Director MX and earlier have a
property set to a value of 9 which allows you to use the syntax found in Director MX and earlier.
actorList, see “actorList” on page 625.
new() keyword. You must specify a name for the object, a
scriptExecutionStyle property has been set
scriptExecutionStyle
To create timeout objects:
-- Lingo syntax when scriptExecutionStyle is set to 9
variableName = timeout(name).new(timeoutPeriod, timeoutHandler,
targetObject)
-- Lingo syntax when scriptExecutionStyle is set to 10
variableName = timeout().new(timeoutName, timeoutPeriod, timeoutHandler,
targetObject)
variableName = new timeout(timeoutName, timeoutPeriod, timeoutHandler,
targetObject)
// JavaScript syntax
variableName = new timeout(timeoutName, timeoutPeriod, timeoutFunction,
targetObject)
62Chapter 3: Writing Scripts in Director
This statement uses the following elements:
• variableName is the variable you are placing the timeout object into.
• timeout indicates which type of Lingo object you are creating.
• timeoutName is the name you give to the timeout object. This name appears in the
timeOutList. It is the #name property of the object.
• new creates a new object.
• intMilliseconds indicates the frequency with which the timeout object should call the
handler you specify. This is the
calls the specified handler every 2 seconds.
#period property of the object. For example, a value of 2000
• #handlerName is the name of the handler you want the object to call. This is the
#timeOutHandler property of the object. You represent it as a symbol by preceding the name
with the
#accelerate.
# sign. For example, a handler called on accelerate would be specified as
• targetObject indicates which child object’s handler should be called. This is the #target
property of the object. It allows specificity when many child objects contain the same handlers.
If you omit this parameter, Director looks for the specified handler in the movie script.
The following statement creates a timeout object named
handler in the child object
To determine when the next timeout message will be sent from a particular timeout object, check
its
#time property. The value returned is the point in time, in milliseconds, when the next
timeout message will be sent. For example, the following statement determines the time when
the next timeout message will be sent from the timeout object
Message window:
-- Lingo syntax
put(timeout("timer1").time)
timer1 that calls an on accelerate
timer1 and displays it in the
Using timeOutList
When you begin creating timeout objects, you can use
timeOutList to check the number of
timeout objects that are active at a particular moment.
The following statement sets the variable
count property.
-- Lingo syntax
x = _movie.timeoutList.count
x to the number of objects in timeOutList by using the
You can also refer to an individual timeout object by its number in the list.
The following statement deletes the second timeout object in
forget() method.
-- Lingo syntax
timeout(2).forget()
Object-oriented programming with Lingo63
timeOutList by using the
Relaying system events with timeout objects
When you create timeout objects that target specific child objects, you enable those child objects
to receive system events. Timeout objects relay these events to their target child objects. The
system events that can be received by child objects include
stopMovie, prepareFrame, and exitFrame. By including handlers for these events in child
prepareMovie, startMovie,
objects, you can make the child objects respond to them for whatever purposes you see fit. System
events received by child objects are also received by movie scripts, frame scripts, and other scripts
designed to respond to them.
The following parent script contains a handler for the system event
handler
-- Lingo syntax
property velocity
on new me
end
on exitFrame
end
on slowDown mph
end
slowDown.
velocity = random(55)
velocity = velocity + 5
velocity = velocity - mph
exitFrame and a custom
Associating custom properties with timeout objects
If you want to associate custom properties with a timeout object, you may want to create a
timeout object that uses as a target anything other than a reference to a script instance object.
When you use this technique, the target data becomes data that is associated with the timeout
object, and can be used in your timeout handler.
The following example illustrates using this technique.
-- Lingo syntax
-- initialize a timeout object and pass it a data property list (tData)
-- instead of a reference to a script instance object
tData = [#beta: 0]
tTO = timeout("betaData").new(50,#targetHandler,tData)
-- within a movie script, create the targetHandler handler
on targetHandler (aData)
-- increment and display the beta property
tData.beta = tData.beta + 1
put(tData.beta)
end targetHandler
In the previous example, the beta property keeps incrementing. This means that you can
initialize several timeout objects that all call the same movie script handler, and each timeout
object can have its own data list associated with it.
64Chapter 3: Writing Scripts in Director
In general, keep the following in mind:
• When using a reference to a script instance as a target, the target handler in that particular
script instance is called. This technique does now allow the use of custom properties.
• When using a reference to anything other than a script instance (such as a property list) as a
target, the target handler in a movie script is called. This technique allows the use of custom
properties.
Object-oriented programming with JavaScript syntax
Object-oriented programming in JavaScript syntax is somewhat different than it is in other
object-oriented languages such as Java and C++—while some object-oriented languages are classbased, JavaScript syntax is prototype-based.
The following two bullet points compare and contrast, at a high level, class-based languages with
prototype-based languages such as JavaScript syntax.
• In class-based languages, you create class definitions that define the initial properties and
methods that characterize all instances created from those classes. A class definition contains
special methods, called constructor methods, that are used to create the instances of that class.
When an instance is created by using the
constructor method, that instance inherits all the properties of its parent class. That instance
can also perform other processing specific to that instance depending on the constructor that
was called.
In a class definition, you perform inheritance by creating a subclass that inherits all the
properties of its parent class, in addition to defining new properties and optionally modifying
inherited ones. The parent class from which a subclass is created is also known as a super-class.
new operator in association with a particular
• In prototype-based languages, such as JavaScript syntax, there is no distinction between classes,
instances, subclasses, and so on—they are all known as objects. Instead of using class
definitions, in JavaScript syntax you use "prototype objects" as the template from which new
objects are created. Similar to class-based languages, in JavaScript syntax, you create a new
object by using the
Instead of using super-classes and subclasses, in JavaScript syntax, you associate prototype
objects with constructor functions to perform inheritance. This process is very similar to using
super-classes and subclasses, only with different terminology.
Also, as opposed to class-based languages, in JavaScript syntax you can add and remove
properties from an object or set of objects at runtime. For example, if you add a property to a
prototype object at runtime, any instance objects for which it is a prototype also get that
property.
new operator in association with a constructor function.
Object-oriented terminology
Because all types in JavaScript syntax are known as objects, class-based terms such as super-class,
subclass, class, instance, and so on do not have literal technical meanings in JavaScript syntax.
However, all of these terms essentially map to objects in JavaScript syntax, and are convenient to
use generically when referring to the different types of JavaScript syntax objects. Therefore, these
class-based terms are used interchangeably with object throughout the discussion about objectoriented programming in JavaScript syntax to mean the following:
• superclass Any class from which subclasses (objects) are created; a parent class.
• subclass Any class that has been created from a superclass (object); a child class.
Object-oriented programming with JavaScript syntax65
• class A generic term for a superclass or subclass; a parent or child class.
• instance or object instance A single object that has been created from a superclass.
Custom classes
One of the major advantages of object-oriented programming is the ability to create your own
custom classes that enable you to add custom functionality to your scripts. The predefined classes
provided by JavaScript syntax, such as Object, String, Math, and so on are useful in some cases,
but they may not provide the functionality you require to accomplish your task. For example,
suppose you want some objects in your movie to represent types of transportation, such as cars,
boats, planes, and so on, and that you want each category to exhibit unique characteristics and
functionality. Neither the predefined JavaScript syntax classes nor the predefined Director objects
may directly provide the functionality that you need. Therefore, you may want to create a new
class for each type of transportation so you can define unique characteristics for each type.
Keep in mind that when you create custom JavaScript syntax classes, you still have access to all the
features and functionality of the predefined Director objects. This means that although the
predefined Director objects may not directly provide the functionality that you need, you can still
use them in your custom classes to access their values and predefined functionality.
Constructor functions
In JavaScript syntax, a constructor function represents the class that contains the template from
which new object instances are created. Constructor functions create and initialize (set the default
state of) properties in the new objects.
Constructor functions are essentially identical in format to regular JavaScript syntax method
functions. The difference between a constructor function and a method function is that a
constructor function uses the special
is being initialized. A method function typically only performs some action on a given set of an
object’s data.
The following example illustrates one way to create a Rectangle constructor function that could
be used to initialize the height and width of new Rectangle objects.
function Rectangle(w, h) {
this.width = w;
this.height = h;
}
You can also create a constructor function by using "function literal" syntax. Function literal
syntax provides the same functionality as the syntax used previously, and is merely an alternative
way to write the constructor. The following example illustrates using function literal syntax to
create a Rectangle constructor function similar to the one illustrated previously.
Rectangle = function(w, h) {
this.width = w;
this.height = h;
}
Note: When defining constructor functions that apply to a movie, be sure to place them in a movie
script so they are available globally.
this keyword to represent a reference to the new object that
It is considered good scripting practice to give constructor functions names that map to their
functionality, and to use initial capitalization in their names, such as
66Chapter 3: Writing Scripts in Director
Rectangle or Circle.
Constructor functions are typically used only to initialize new objects, but can also return the
object if desired. If you do return the initialized object, the returned object becomes the value of
the
new expression.
Object instances
The most common way to create a new object instance is to use the
new operator followed by the
name of a constructor function. The following examples create new object instances.
var objRandom = new Object(); // assigns a reference to an Object object
var objString = new String(); // assigns a reference to a String object
A constructor function can optionally define parameters that a new object instance passes to it to
initialize the state of the object instance. If a constructor function does define parameters used
during initialization of new object instances, the property values are initialized as follows:
• If you pass values to the constructor function during initialization, the properties that received
values are set to those values.
• If you do not pass values to the constructor function during initialization, the properties that
did not receive values are set to
When you create new object instances, the keyword
constructor function to refer to the new object instance. Therefore, a new object instance is
initialized with all of the properties defined by using the
In the following example, a
names of three properties that will be associated with new object instances. The statement
following the constructor initializes a new object instance by passing values to the constructor.
These values are used as the initial values of the properties specified by the keyword
// Circle constructor function
function Circle(x, y, r) {
Circle constructor function uses the keyword this to specify the
this.
// xCoord = 10, yCoord = 15, radius = 5
var objCircle = new Circle(10, 15, 5);
Now that objCircle has been initialized, you can access its properties. Using the objCircle
instance created previously, you could set some variables equal to the values of its properties.
var theXCoord = objCircle.xCoord; // assigns the value 10 to theXCoord
var theYCoord = objCircle.yCoord; // assigns the value 15 to theYCoord
var theRadius = objCircle.radius; // assigns the value 5 to theRadius
Note: For more information on using dot syntax to access properties and methods of an object, see
“Scripting in dot syntax format” on page 50.
It is considered good scripting practice to give new objects names that map to their functionality,
and to name them by using lowercase letters, such as
objRectangle or objCircle.
You can also create an object instance by using "object literal" syntax, which eliminates the need
for the
new operator and a constructor function. You typically only use this technique when you
need only one instance of an object that has not been defined in a constructor function. The
following example creates an object instance with
var objSmallCircle = { x:1, y:2, radius:2 };
Object-oriented programming with JavaScript syntax67
x = 1, y = 2, and radius = 2.
Object inheritance
In addition to being able to create your own custom classes, another major advantage of objectoriented programming is the ability of subclasses to inherit the properties and methods of the
superclasses from which they were created. Inheritance enables you to easily create objects that
already have built-in properties and functionality.
In JavaScript syntax, there is one superclass that acts as the base class from which all other
subclasses are created—the Object superclass. The Object superclass contains a few basic
properties and methods. The subclasses that are created by using Object as a template always
inherit these basic properties and methods, and likely define their own properties and methods.
Subclasses of these classes inherit from Object, from their superclasses, and so on. All additional
objects that you create would continue this chain of inheritance.
For example, Object contains the
create a new class named
the
constructor property and the toString() method of Object. If you then create another
class named
constructor property and the toString() method of Object, in addition to any custom
SubObj2 using SubObj1 as a superclass, SubObj2 would also inherit the
SubObj1, it is a subclass of Object, and therefore automatically inherits
properties and methods you defined in
constructor property and the toString() method. If you
SubObj1.
Two of the important properties that your custom constructor functions inherit from the Object
superclass are
prototype and constructor. The prototype property represents the prototype
object of a class, which enables you to add variables (properties) and methods to object instances,
and is the means by which inheritance is typically implemented in JavaScript syntax. The
constructor property represents the constructor function itself. The use of these properties is
explained in the following sections.
Prototype objects
As previously stated, when you create a subclass, it automatically inherits the properties and
methods of the superclass on which it is based. In JavaScript syntax, inheritance is typically
implemented by using prototype objects. A subclass actually inherits its properties and methods
from the prototype object of its superclass, and not from the superclass itself. This important
point offers a distinct advantage: all properties and methods do not literally have to be copied
from a class to an object instance of that class, which can dramatically decrease the amount of
memory required by new object instances.
Every class in JavaScript syntax, including the predefined Object class, contains only one
prototype object. Every object instance created from a class has access to the properties and
methods in the prototype object of that class. Therefore, the prototype object of a class is typically
the only object that actually stores the properties and methods for that class; an object instance
only contains the properties required to initialize that instance.
In your code, it appears that each object instance actually contains those properties and methods
because you can access them directly from each object instance, but the instance is actually using
the prototype object to access them. The prototype object of a class is created automatically when
you create the class. You access the prototype object by using the
prototype property of the class.
Because a prototype object of a class stores properties that are shared by all object instances, they
are ideally suited to define properties and methods whose values will be shared across all object
instances. By sharing properties and methods across object instances, you can easily create
instances that exhibit a defined default behavior, and can also customize any instances that deviate
from the default behavior.
68Chapter 3: Writing Scripts in Director
Prototype objects typically are not suited to define properties and methods whose values may vary
across object instances. In cases where values may vary across object instances, you typically define
those properties and methods within the class itself.
To specify the scope of a custom property or method, you define it as one of the following
four types:
• Instance variables
• Instance methods
• Class variables
• Class methods
Instance variables
Instance variables are any variables (properties) that are defined in a constructor function and that
are copied into each object instance of that constructor. All object instances have their own copies
of instance variables. This means that if there are five object instances of a
five copies of each instance variable defined in the class. Because each object instance has its own
copy of an instance variable, each object instance can assign a unique value to an instance variable
without modifying the values of other copies of the instance variable. You access instance variables
directly from their containing object instances.
The following example defines four instance variables—
make, model, color, and speed—in a
constructor function. These four instance variables are available directly from all object instances
of the
Car constructor.
function Car(make, model, color) { // define a Car class
The following object instance objCar contains all four instance variables. Although a value for
the instance variable
whose initial value is 0 because the
// objCar.make="Subaru", objCar.model="Forester",
// objCar.color="silver", objCar.speed = 0
var objCar = new Car("Subaru", "Forester", "silver");
speed is not passed to the Car constructor, objCar still has a speed property
speed variable is defined in the Car constructor.
Circle class, there are
Instance methods
Instance methods are any methods that are accessible through an object instance. Object instances
do not have their own copies of instance methods. Instead, instance methods are first defined as
functions, and then properties of the constructor function’s prototype object are set to the
function values. Instance methods use the keyword
this in the body of the defining constructor
function to refer to the object instance they are operating on. Although a given object instance
does not have a copy of an instance method, you still access instance methods directly from their
associated object instances.
Object-oriented programming with JavaScript syntax69
The following example defines a function named Car_increaseSpeed(). The function name is
then assigned to the
// increase the speed of a Car
function Car_increaseSpeed(x) {
increaseSpeed property of the Car class’s prototype object.
An object instance of Car could then access the increaseSpeed() method and assign its value to
a variable by using the following syntax.
var objCar = new Car("Subaru", "Forester", "silver");
var newSpeed = objCar.increaseSpeed(30);
You can also create an instance method by using function literal syntax. Using function literal
syntax eliminates the need to define a function, and the need to assign a property name to the
function name.
The following example uses function literal syntax to define an
contains the same functionality as the
// increase the speed of a Car
Car.prototype.increaseSpeed = function(x) {
this.speed += x;
return this.speed;
}
increaseSpeed() function defined previously.
increaseSpeed() method that
Class variables
Also known as static variables, these are any variables (properties) that are associated with a class,
and not an object instance. There is always only one copy of a class variable, regardless of the
number of object instances that are created from that class. Class variables do not use the
prototype object to implement inheritance. You access a class variable directly through the class,
and not through an object instance; you must define a class in a constructor function before you
can define class variables.
The following example defines two class variables—
function Car() { // define a Car class
...
}
MAX_SPEED and MIN_SPEED.
Car.MAX_SPEED = 165;
Car.MIN_SPEED = 45;
You would access the MAX_SPEED and MIN_SPEED class variables directly from the Car class.
var carMaxSpeed = Car.MAX_SPEED; // carMaxSpeed = 165
var carMinSpeed = Car.MIN_SPEED; // carMinSpeed = 45
Class methods
Also known as static methods, these are any methods that are associated with a class, and not an
object instance. There is always only one copy of a class method, regardless of the number of
object instances that are created from that class. Class methods do not use the prototype object to
implement inheritance. You access a class method directly through the class, and not through
an object instance; you must define a class in a constructor function before you can define
class methods.
70Chapter 3: Writing Scripts in Director
The following example defines a function named setInitialSpeed() that can change the
default speed of new car instances. The function name is assigned to the
property of the
function Car(make, model, color) { // define a Car class
}
Car.defaultSpeed = 10; // initial speed for new Car instances
// increase the speed of a Car
function Car_setInitialSpeed(x) {
Car.defaultSpeed = x;
}
Car.setInitialSpeed = Car_setInitialSpeed;
Car class.
setInitialSpeed
You access the setInitialSpeed() class method directly from the Car class.
var newSpeed = Car.setInitialSpeed(30);
You can also create a class method by using function literal syntax. The following example uses
function literal syntax to define a
functionality as the
// increase the speed of a Car
Car.setInitialSpeed = function(x) {
Car.defaultSpeed = x;
}
setInitialSpeed() function defined previously.
setInitialSpeed() method that contains the same
Recommended steps for defining a class
The following list describes the recommended steps to follow when defining a class:
1 Define a constructor function that is used as the template from which all object instances are
initialized. You may additionally define any instance variables in the constructor function by
using the keyword
2 Define any instance methods, and possibly additional instance variables, that are stored in the
this to refer to an object instance.
prototype object of a class. These instance methods and variables are available to all object
instances, and are accessible through the prototype object of the class.
3 Define any class methods, class variables, and constants that are stored in the class itself. These
class methods and variables are accessible only through the class itself.
In your code, when you access a property of an object instance, JavaScript syntax searches the
object instance itself for that property. If the instance does not contain the property, JavaScript
syntax then searches the prototype object of the super-class from which the instance was created.
Because an object instance is searched before the prototype object of the class from which it was
created, object instance properties essentially hide properties from the prototype object of their
super-classes. This means that both an object instance and its super-class could realistically define
a property with the same name but different values.
Object-oriented programming with JavaScript syntax71
Deleting variables
You can delete a class variable or an instance variable by using the
delete operator. The following
example illustrates this process.
function Car() { // define a Car constructor function
...
}
Car.color = "blue"; // define a color property for the Car class
Car.prototype.engine = "V8"; // define an engine property for the prototype
Accessing the constructor property of a prototype object
When you define a class by creating a constructor function, JavaScript syntax creates a prototype
object for that class. When the prototype object is created, it initially includes a
property that refers to the constructor function itself. You can use the
constructor property of a
constructor
prototype object to determine the type of any given object.
In the following example, the
function used to the create the object instance. The value of the
constructor property contains a reference to the constructor
constructor property is actually
a reference to the constructor itself and not a string that contains the constructor’s name.
function Car() { // define a Car class
// initialization code here
}
var myCar = new Car(); // myCar.constructor == function Car() {}
Creating properties dynamically
Another advantage of using prototype objects to implement inheritance is that properties and
methods that are added to a prototype object are automatically available to object instances. This
is true even if an object instance was created before the properties or methods were added.
In the following example, the
color property is added to the prototype object of a Car class after
an object instance of Car has already been created.
function Car(make, model) { // define a Car class
this.make = make;
this.model = model;
}
var myCar = new Car("Subaru", "Forester"); // create an object instance
trace(myCar.color); // returns undefined
// add the color property to the Car class after myCar was initialized
Car.prototype.color = "blue";
trace(myCar.color); // returns "blue"
72Chapter 3: Writing Scripts in Director
You can also add properties to object instances after the instances have been created. When you
add a property to a specific object instance, that property is available only to that specific object
instance. Using the
color property to myCar after it has already been created.
trace(myCar.color); // returns undefined
myCar.color = "blue"; // add the color property to the myCar instance
trace(myCar.color); // returns "blue"
var secondCar = new Car("Honda", "Accord"); // create a second object instance
trace(secondCar.color); // returns undefined
myCar object instance created previously, the following statements add the
Writing scripts in the Script window
When you write scripts for a movie, the quantity and variety of scripts can be very large. Deciding
which methods or properties to use, how to structure scripts effectively, and where scripts should
be placed requires careful planning and testing, especially as the complexity of your movie grows.
Before you begin writing scripts, formulate your goal and understand what you want to
achieve. This is as important—and typically as time-consuming—as developing storyboards
for your work.
When you have an overall plan for the movie, you are ready to start writing and testing scripts.
Expect this to take time. Getting scripts to work the way you want often takes more than one
cycle of writing, testing, and debugging.
The best approach is to start simple and test your work frequently. When you get one part of a
script working, start writing the next part. This approach helps you identify bugs efficiently and
ensures that your scripts are solid as they become more complex.
When you write your scripts, you write them in the Script window in the Director user interface.
The Script window provides a number of features that help you create and modify your scripts.
To open the Script window, do one of the following:
• Select Window > Script.
• Double-click a script cast member in the Cast window.
For information on alternative ways to create and open scripts, see “Performing common tasks”
on page 79.
Writing scripts in the Script window73
Setting Script window preferences
You can change the font of text in the Script window and define different colors for various code
components. To change the default font of text in the Script window and the color of various
code elements, you use Script window preferences. Director automatically colors different types of
code elements unless you turn off Auto Coloring.
To set Script window preferences:
1 Select Edit > Preferences > Script.
2 To choose the default font, click the Font button and select settings from the Font dialog box.
3 To choose the default color of text in the Script window, select a color from the Color menu.
4 To choose the background color for the Script window, select a color from the Background
color menu.
5 To make new Script windows automatically color certain code elements, select Auto Coloring.
This option is on by default. With Auto Coloring off, all text appears in the default color.
6 To make new Script windows automatically format your scripts with proper indenting, select
Auto Format. This option is on by default.
Note: The auto coloring and auto formatting features do not apply to JavaScript syntax code.
Therefore, if you are authoring scripts using JavaScript syntax, the Auto Coloring and Auto Format
buttons in the Script window are disabled, and terms such as
the default text color.
function, var, and this will appear in
7 To make new Script windows display line numbers for your scripts, select Line Numbering.
This option is on by default.
8 If Auto Coloring is on, select colors for the following code elements from the corresponding
color menus:
■ Keywords
■ Comments
■ Literals
■ Custom (terms you define in your own code)
9 To change the line number column background color, click the Line Numbers color menu and
choose a new color.
10 To change the location of the Call Stack, Variable, and Watcher panes in the Debugger
window, select left, top, right, or bottom from the Debugger Panes menu.
74Chapter 3: Writing Scripts in Director
Inserting common scripting terms
The Script window provides pop-up menus of common scripting terms that you can use to insert
statements in a script. The same menus also appear in the Message window.
In both the Script window and the Message window, you can select which scripting syntax you
want to use for a particular script.
To select the scripting syntax:
• From the Script Syntax pop-up menu, select either Lingo or JavaScript.
After you select a scripting syntax, you enter code in the syntax you have chosen. If you try to
compile a script in a syntax other than the one you chose, a script error occurs.
When entering scripts in the Script window, you can comment out or uncomment either single
or multiple lines of code by using the Comment or Uncomment buttons. Depending on which
scripting syntax you have chosen, the Comment and Uncomment buttons display the correct
comment markers for that syntax; Lingo uses double-hyphens (
double-slashes (
//).
--), and JavaScript syntax uses
To comment code:
• Highlight the line or lines of code you want to comment out, and click Comment.
Note: When using the Comment button to comment out multiple lines of JavaScript syntax code,
Director inserts double-slashes before each line. You can also comment out multiple lines of code by
inserting /* before the first line of commented code and inserting */ after the last line of commented
code, but you must do this manually.
To uncomment code:
• Highlight the line or lines of code that you want to remove comments from, and
click Uncomment.
Both the Script window and the Message window contain the following menus:
• The Alphabetical Lingo menu lists every element in alphabetical order, except 3D Lingo.
• The Categorized Lingo menu lists categories of elements according to the features they are
often used for. It does not include 3D Lingo.
• The Alphabetical 3D Lingo menu lists all 3D Lingo elements in alphabetical order.
Writing scripts in the Script window75
• The Categorized 3D Lingo menu lists categories of all 3D Lingo elements according to the
features they are used for.
• The Scripting Xtras pop-up menu includes the methods and properties of all scripting Xtra
extensions found, regardless of whether they are Macromedia or third-party Xtra extensions.
Note: The scripting Xtra extensions listed in the Scripting Xtras pop-up menu are only those that
support the
some cast member media types such as 3D and DVD also support the
not appear in the Scripting Xtras pop-up menu because they are not implemented in Director as
scripting Xtra extensions.
interface() method and whose names actually appear in the pop-up menu. Although
interface() method, they do
When you select an element from the pop-up menus, Director inserts the element at the insertion
point in the Script window.
When an element requires additional parameters, placeholder names are included that indicate
the additional required information. When more than one argument or parameter is required, the
first one is highlighted for you, so all you must do is type to replace it. You must select and change
the other parameters yourself.
Some cast member types and scripting Xtra extensions provide scripting terms that do not appear
in the pop-up menus. These member types and Xtra extensions often have their own
documentation, and you can find some information from within Director.
To display a list of available Xtra extensions:
• Issue either put(_player.xtraList) or trace(_player.xtraList) in the Message window.
To display a list of available scripting Xtra extensions:
• Issue either put(_player.scriptingXtraList) or trace(_player.scriptingXtraList)
in the Message window.
To display a list of methods and properties for an Xtra extension:
• From the Scripting Xtras pop-up menu, point to an Xtra extension, and on the submenu,
click put interface. The methods and properties for that Xtra extension appear in the Message
window.
Entering and editing text
Entering and editing text in a Script window is similar to entering and editing text in any
other field.
The following are common editing tasks that you perform in the Script window:
• To select a word, double-click the word.
• To select an entire script, select Select All from the Edit menu.
• To start a new line, enter a carriage return.
• In Lingo, to wrap a long line of code with a continuation symbol, press Alt+Enter (Windows)
or Option+Return (Macintosh) where you want to insert a soft line break. The continuation
symbol (\) that appears indicates that the statement continues on the next line.
In JavaScript syntax, to wrap a long line of code, insert a regular line break by pressing Enter
(Windows) or Return (Macintosh). The Lingo continuation symbol causes a script error in
JavaScript syntax scripts.
76Chapter 3: Writing Scripts in Director
• To locate a handler in the current script, select the handler’s name from the Go to Handler
pop-up menu in the Script window.
• To compile any modified scripts, click the Script window’s Recompile All Modified Scripts
button or close the Script window. When you modify a Script, an asterisk appears in the Script
window title bar, indicating that the script needs to be recompiled.
• To compile all scripts in a movie, select Recompile All Scripts from the Control menu.
• To reformat a script with proper indentation, press Tab in the Script window.
Director automatically indents statements when the syntax is correct. If a line does not indent
properly, there is a problem in the syntax on that line.
• To open a second Script window, Alt-click (Windows) or Option-click (Macintosh) the New
Cast Member button in the Script window. This can be helpful for editing two different
sections of a long script simultaneously.
• To toggle line numbering, click the Line Numbering button.
• To toggle Auto Coloring, click the Auto Coloring button. Auto coloring displays each type of
Lingo element (properties, commands, and so on) in a different color.
• To toggle Auto Formatting, click the Auto Format button. Auto Formatting adds the correct
indenting to your scripts each time you add a carriage return or press Tab.
Note: The auto coloring and auto formatting features do not apply to JavaScript syntax code.
Therefore, if you are authoring scripts using JavaScript syntax, the Auto Coloring and Auto Format
buttons in the Script window are disabled, and terms such as
the default text color.
Finding handlers and text in scripts
The Find command in the Edit menu is useful for finding handlers and for finding and editing
text and handlers.
function, var, and this will appear in
To find handlers in scripts:
1 Select Edit > Find > Handler.
The Find Handler dialog box appears.
The left-most column in the Find Handler dialog box displays the name of each handler in
the movie. The middle column displays the number of the cast member associated with the
handler’s script, along with the name of that cast member. The rightmost column lists the cast
library that contains the cast member.
2 Select the handler that you want to find.
3 Click Find.
The handler appears in the Script window.
The title bar at the top of the Script window indicates the script’s type.
Writing scripts in the Script window77
To find text in scripts:
1 Make the Script window active.
2 Select Edit > Find > Text.
The Find Text dialog box appears.
3 Enter text that you want to find in the Find field, and then click Find.
By default, find is not case-sensitive:
ThisHandler, thisHandler, and THISHANDLER are all the
same for search purposes. Click the Case Sensitive check box to make the find case-sensitive.
To specify which cast members to search:
• Select the appropriate option under Search: Scripts.
To start the search over from the beginning after the search reaches the end:
• Select the Wrap-Around option.
To search only for whole words and not fragments of other words that match the word:
• Select the Whole Words Only option.
To find the next occurrence of the text specified in the Find field:
The following are ways to perform common tasks for creating, attaching, and opening scripts.
To create a frame behavior (script attached to a frame):
• Double-click the behavior channel in the frame to which you want to attach the behavior.
Behavior channels
When you create a new behavior, the behavior receives the cast library number of the first
available location in the current Cast window.
When you create a new frame behavior, the Script window opens and already contains the Lingo
on exitFrame handler The first line contains on exitFrame, followed by a line with a blinking
insertion point, and then a line with the word
common Lingo behavior to the frame. To make this handler work with JavaScript syntax, replace
on exitFrame with function exitFrame() {, and replace end with }.
end. This makes it easy for you to quickly attach a
One of the most common frame behaviors is one that keeps the playhead looping in a single
frame. This can be useful when you want your movie to keep playing in a single frame while
waiting for the user to click a button or for a digital video or sound to finish playing.
To keep the playhead in a single frame:
• In a frame behavior, type the following statement on the line after the on exitFrame (Lingo)
or
function exitFrame() (JavaScript syntax) statement:
-- Lingo syntax
_movie.go(_movie.frame)
// JavaScript syntax
_movie.go(_movie.frame);
The Movie object’s frame property refers to the frame currently occupied by the playhead. This
statement essentially tells the playhead to "go back to the frame you are currently in."
Writing scripts in the Script window79
To create a sprite behavior (script attached to a sprite):
• In the Score or on the Stage, select the sprite that you’re attaching the behavior to. Then select
Window > Behavior Inspector and select New Behavior from the Behavior pop-up menu.
When you create a new sprite behavior, the Script window opens and already contains the Lingo
on mouseUp handler. The first line contains the line on mouseUp, followed by a line with a
blinking insertion point, and then a line with the word
end. This makes it easy for you to quickly
attach a common behavior to the sprite. To make this handler work with JavaScript syntax,
replace
on mouseUp with function mouseUp() {, and replace end with }.
To open a behavior for editing:
1 Double-click the behavior in the Cast window.
The Behavior inspector opens.
2 Click the Script Window icon in the Behavior inspector.
The Script window displays the behavior.
Alternatively, you can open the Script window and cycle through the scripts until you reach
the behavior.
To remove a behavior from a Score location:
• Select the location and then delete the script from the list displayed in the Property inspector
(Behavior tab).
To attach existing behaviors to sprites or frames, do one of the following:
• Drag a behavior from a cast to a sprite or frame in the Score or (for sprites) to a sprite on
the Stage.
• In the score, select the sprites or frames that you’re attaching the behavior to. Then
select Window > Behavior Inspector and select the existing behavior from the Behavior
pop-up menu.
To create a movie script (script attached to a movie), do one of the following:
• If the current script in the Script window is a movie script, click the New Script button in the
Script window. (Clicking the New Script button always creates a script of the same type as the
current script.)
• If the current script in the Script window is not a movie script, click the New Script button
and then change the new script’s type with the Script Type pop-up menu in the Script tab of
the Property inspector.
• If no sprites or scripts are selected in the cast, Score, or Stage, then open a new Script window;
this creates a new movie script by default.
To open a movie script or parent script for editing:
• Double-click the script in the Cast window.
To change a script’s type:
1 Select the script in the Cast window or open it in the Script window.
2 Click the Script tab of the Property inspector and select a script type from the Script Type
pop-up menu.
80Chapter 3: Writing Scripts in Director
To cycle through the scripts in the Script window:
• Use the Previous Cast Member and Next Cast Member arrows at the top of the Script window
to advance or back up to a script.
To duplicate a script:
• Select the script in the Cast window and select Duplicate from the Edit menu.
To create a script that is attached automatically to every sprite made from a specific cast member,
attach the script to the cast member itself.
To create a script attached to a cast member or open an existing one, do one of the
following:
• Right-click (Windows) or Control-click (Macintosh) on a cast member in the Cast window
and select Cast Member Script from the context menu.
• Select a cast member in the Cast window and then click the Cast Member Script button in the
Cast window.
Using linked scripts
In addition to scripts stored as internal cast members, you can choose to keep scripts in external
text files and link them to your Director movie. These linked scripts are similar to linked image or
digital video files that you can import into Director movies.
Advantages of using linked scripts include the following:
• One person can work on the Director file while another works on the script.
• You can easily exchange scripts with others.
• You can control the scripts separately from the Director file in a source code control
application such as Microsoft Visual SourceSafe or Perforce by Perforce Software. Applications
such as this prevent multiple programmers working on the same Director project from
overwriting each other’s work.
Linked scripts are used by Director only during authoring. At runtime, Director projectors and
Macromedia Shockwave Player use a special internal copy of the script data stored in the movie.
This way, your linked scripts need not be distributed with your movies and cannot be copied by
end users.
To import a script as a linked text file:
1 Select File > Import.
2 Select Script as the type of file to import.
3 Select the script file(s) you want to import.
You can import files with the file extensions .txt, .ls, or .js. The .ls extension is the Director
linked script extension.
To create a list of files you want to import, you can use the Add and Add All buttons. This is
especially useful if you want to import scripts from multiple locations.
4 Select Link to External File from the Media pop-up menu.
5 Click Import.
Writing scripts in the Script window81
You can edit linked scripts normally in the Director Script window. Changes you make are
written to the external files each time you save your Director movie. (If you imported the linked
script from a UNIX server, UNIX line endings are preserved.) If you import a script whose text
file is locked, you won’t be able to edit the script in Director.
You cannot apply custom text colors to linked scripts in the Script window. Script auto coloring,
however, is enabled for linked scripts.
To turn an internal script cast member into an external, linked script cast member:
1 Select the internal cast member and click the Script tab of the Property inspector.
2 Click Link Script As.
3 Enter a name for the script file in the Save As dialog box.
4 Click Save.
To reload a linked script after it is edited:
• Use the Member object’s unload() method.
If a linked script is edited outside of Director, you can reload it by using the
the Message window. The following statement causes the script member
unloaded and then reloaded:
-- Lingo syntax
member("myScript").unload()
// JavaScript syntax
member("myScript").unload();
unload() method in
myScript to be
82Chapter 3: Writing Scripts in Director
CHAPTER 4
Debugging Scripts in Director
Scripts do not always do what you want the first time. The script often has an error in its syntax:
possibly a word is misspelled or a small part of the script is missing. Other times, the script might
work but does not produce the expected result. Mistakes or bugs almost always occur when
writing your scripts, so you should allow enough time for debugging when you develop
multimedia titles.
As your skill with scripting increases, you’ll probably encounter different types of problems as you
master one area but start learning others. However, the basic troubleshooting techniques
described here are useful for novice and advanced users alike.
The best way to correct a bug in your scripts varies from situation to situation. There are not
one or two standard procedures that resolve the problem. You must use a variety of tools and
techniques, such as the following:
• An overview and understanding of how scripts in the movie interact with each other
• Familiarity and practice with common debugging methods
The following tools help you identify problems in scripts:
• The Message window, when tracing is on, displays a record of the frames that play and the
handlers that run in the movie.
• The Debugger window displays the values of global variables, properties of the script that is
currently running, the sequence of handlers that ran to get to the current point, and the value
of variables and expressions that you select.
• The Script window lets you enter comments, insert stopping points in the script, and select
variables whose value is displayed in the Object inspector.
• The Object inspector lets you view and set the values of objects and properties you select.
83
Good scripting habits
Good scripting habits can help you avoid many scripting problems in the first place.
• Try to write your scripts in small sets of statements and test each one as you write it. This
isolates potential problems where they are easier to identify.
• Insert comments that explain what the script statements are intended to do and what the
values in the script are for. This makes it easier to understand the script if you return to it later
or if someone else works on it. For example, the comment in the following statements make
the purpose of the
-- Lingo syntax
-- Loop until the "s" key is pressed
repeat while not(_key.keyPressed("s"))
_sound.beep()
end repeat
// JavaScript syntax
// Loop until the "s" key is pressed
while(!_key.keyPressed("s")) {
_sound.beep();
}
if...then structure and repeat loop clear:
• Make sure that the script’s syntax is correct. Use the Script window’s pop-up menus to insert
pre-formatted versions of scripting elements. Rely on the API topics of this reference to check
that statements are set up correctly.
• Use variable names that indicate the variables’ purpose. For example, a variable that contains a
number should be called something like
newNumber instead of ABC.
Basic debugging
Debugging involves strategy and analysis, not a standard step-by-step procedure. This section
describes the basic debugging approaches that programmers successfully use to debug any code,
not just Lingo or JavaScript syntax.
Before you modify a movie significantly, always make a backup copy. It may help to name the
copies incrementally, for example, fileName_01.dir, fileName_02.dir, fileName_03.dir, and so on
to keep track of the various stages of a movie.
Identifying the problem
It might seem obvious, but the first thing to do when debugging is to identify the problem. Is a
button doing the wrong thing? Is the movie going to the wrong frame? Is a field not editable
when it should be?
You may also want to determine what you expect a particular script to do, and then compare your
expectation with what the script actually does. This process helps you clearly define your goal and
see what parts of the goal are not being met.
If you copied a script or a portion of a script from another movie or from a written example,
check whether the script was designed for some specific conditions. Perhaps it requires that a
sprite channel is already scripted. Maybe cast member names must follow a specific style
convention.
84Chapter 4: Debugging Scripts in Director
Locating the problem
Do the following to start locating a problem:
• Think backwards through the chain to identify where the unexpected started to happen.
• Use the Message window to trace which frames the movie goes through and the handlers
that your scripts run.
• Determine what the scripts should be doing and consider what in these statements relates to
the problem. For example, if a text cast member is not editable when you expect it to be, where
in the movie does (or does not) your script set the cast member’s
editable property?
• If a sprite does not change as intended on the Stage, is the updateStage() method needed
somewhere?
• Does the problem occur only on certain computers and not others? Does it happen only when
the display is set to millions of colors? Maybe something in the computer is interfering with
the application.
You can focus on specific lines of script by inserting a breakpoint—a point where the script pauses
its execution and invokes the Debugger window—in a line. This gives you a chance to analyze
conditions at that point before the script proceeds. For information on how to insert breakpoints
in a script, see “Debugging in the Debugger window” on page 94.
Solving simple problems
When finding a bug, it’s a good idea to check for simple problems first.
The first debugging test occurs when you compile your script. You can compile your script by
doing one of the following:
• In the Script window, click Recompile All Modified Scripts.
• From the Control menu, click Recompile All Scripts.
• Press Shift+F8.
• Close the Script window.
It is typically more convenient to compile scripts by using one of the first three options. The
fourth option requires that you close the Script window each time you want to compile a script.
When you compile your script, Macromedia Director MX 2004 gives you an error message if the
script contains incorrect syntax. The message usually includes the line in which the problem was
first detected. A question mark appears at the spot in the line where Director first found
the problem.
For example, the first line in the previous error message tells you that the script error in question
is a syntax error, and also tells you what the syntax error is. The second line in the error message
displays the actual line of code that contains the syntax error.
Basic debugging85
Looking for syntax errors
Syntax errors are probably the most common bug encountered while scripting. When a script
fails, it is a good idea to first make sure that:
• Terms are spelled correctly, spaces are in the correct places, and necessary punctuation is used.
Director cannot interpret incorrect syntax.
• Quotation marks surround the names of cast members, labels, and strings within a statement.
• All necessary parameters are present. The specific parameters depend on the individual
element. See the API topic entries in this reference to determine any additional parameters that
an element requires.
Looking for other simple bugs
If your script compiles without an error message, it might contain a bug. If your script is not
doing what you want, check the following:
• Values for parameters are correct. For example, using an incorrect value for the number of
beeps that you want the
beep() method to generate gives you the wrong number of beeps.
• Values that change—such as variables and the content of text cast members—have the values
you want. You can display their values in the Object inspector by selecting the name of the
object and clicking Inspect Object in the Script window, or in the Message window by using
the
put() or trace() functions.
• The scripting elements do what you think they do. You can check their behavior by referring to
the API topic entries in this reference.
• If the script is written in JavaScript syntax, the script may contain a capitalization error.
JavaScript syntax is case-sensitive, which means that all methods, functions, properties, and
variables must be referred to by using the correct capitalization.
If you attempt to call a method or function by using incorrect capitalization, you will receive a
script error.
If you attempt to access a variable or property by using incorrect capitalization, you may not
receive a script error, but your script may not behave as expected. For example, the following
mouseUp handler contains a statement that attempts to access the itemLabel property by using
incorrect capitalization. This script does not produce a script error, but instead dynamically
creates a new variable with the incorrect capitalization. The value of the newly created variable
is
undefined.
// JavaScript syntax
function beginSprite() {
this.itemLabel = "Blue prints";
}
function mouseUp() {
trace(this.itemlabel) // creates the itemlabel property
}
86Chapter 4: Debugging Scripts in Director
Debugging in the Script window
The Script window contains several features that can help you debug scripts.
To open the Script window:
• Select Window > Script.
To make the current line of code a comment:
• Click Comment.
To remove commenting from the current line of code:
• Click Uncomment.
To turn breakpoints in the current line of code on and off:
• Click Toggle Breakpoint.
To turn off all breakpoints.
• Click Ignore Breakpoints.
To add the selected expression or variable to the Object inspector:
• Click Inspect Object.
Debugging in the Message window
The Message window provides a way for you to test scripting commands and to monitor what is
happening in your scripts while a movie plays.
To open the Message window:
• Select Window > Message.
Debugging in the Message window87
Managing the Message window
The Message window has an Input pane and an Output pane. The Input pane is editable. The
Output pane is read-only. The only way to display text in the Output pane is by calling the
or
trace() functions.
You can adjust the sizes of the Input and Output panes by dragging the horizontal divider that
separates them.
To resize the Output pane:
• Drag the horizontal divider to a new position.
To hide the Output pane completely:
• Click the Collapse/Expand button in the center of the horizontal divider.
When the Output pane is hidden, output from scripts that execute is displayed in the
Input pane.
To display the Output pane if it is hidden:
• Click the Collapse/Expand button again.
To clear the contents of the Message window:
• Click the Clear button.
If the Output pane is visible, its contents are deleted.
If the Output pane is not visible, the contents of the Input pane are deleted.
To delete a portion of the contents of the Output pane:
1 Select the text to be deleted.
2 Press the Backspace or Delete key.
put()
To copy text in the Input or Output pane:
1 Select the text.
2 Select Edit > Copy.
Testing scripts in the Message window
You can test Lingo and JavaScript syntax statements to see how they work by entering them in the
Message window and observing the results. When you enter a command in the Message window,
Director executes the command immediately, regardless of whether a movie is playing.
Before entering the statements you want to test, you must first select which scripting syntax,
Lingo or JavaScript syntax, you are going to test.
To select the scripting syntax
1 From the Script Syntax pop-up menu, select either Lingo or JavaScript.
To test a one-line statement:
1 Type the statement directly in the Message window.
2 Press Enter (Windows) or Return (Macintosh). Director executes the statement.
If the statement is valid, the Message window displays the result of the statement in the Output
pane at the bottom of the window. If the script is invalid, an alert appears.
88Chapter 4: Debugging Scripts in Director
For example, if you type the following statement into the Message window:
-- Lingo syntax
put(50+50)
// JavaScript syntax
trace(50+50);
and press Enter (Windows) or Return (Macintosh), the result appears in the Output pane:
-- Lingo syntax
-- 100
// JavaScript syntax
// 100
If you type the following statement into the Message window:
-- Lingo syntax
_movie.stage.bgColor = 255
// JavaScript syntax
_movie.stage.bgColor = 255;
and press Enter (Windows) or Return (Macintosh), the Stage becomes black.
You can test multiple lines of code all at once by copying and pasting statements into the Message
window or by pressing Shift+Return after each line of code.
To execute multiple lines of code by copying and pasting:
1 Copy the lines of code to the clipboard.
2 Enter a blank line in the Message window.
3 Paste the code into the input pane of the Message window.
4 Place the insertion point at the end of the last line of code.
5 Press Control+Enter (Windows) or Control+Return (Macintosh). Director finds the first blank
line above the insertion point and executes each line of code after the blank line in succession.
To enter multiple lines of code manually:
1 Enter a blank line in the Message window.
2 Enter the first line of code.
3 Press Shift+Return at the end of the line.
4 Repeat steps 2 and 3 until you have entered the last line of code.
5 Press Control+Enter (Windows) or Control+Return (Macintosh). Director finds the first blank
line above the insertion point and executes each line of code after the blank line in succession.
You can test a handler without running the movie by writing the handler in a Movie Script or
Behavior Script window, and then by calling it from the Message window.
To test a handler:
1 Copy and paste or manually enter a multiline handler into the Message window as described in
the previous two procedures.
2 Place the insertion point at the end of the last line of code.
3 Press Enter (Windows) or Return (Macintosh). The handler executes.
Any output from
put() or trace() statements in the handler appears in the Message window.
Debugging in the Message window89
Like the Script window, the Message window contains pop-up menus of scripting commands.
When you select a command from one of the pop-up menus, the command appears in the
Message window with the first argument that you must provide selected. Several menus are
provided to give you easy access to the whole catalog of scripting terms.
The pop-up menus include the following:
• Alphabetical Lingo includes all commands except 3D Lingo, presented in an alphabetical list.
• Categorized Lingo includes all commands except 3D Lingo, presented in a categorized list.
• Alphabetical 3D Lingo includes all 3D Lingo, presented in an alphabetical list.
• Categorized 3D Lingo includes all 3D Lingo, presented in a categorized list.
• Scripting Xtra extensions includes the methods and properties of all scripting Xtra extensions
found, regardless of whether they are Macromedia or third-party Xtra extensions.
Note: The scripting Xtra extensions listed in the Scripting Xtras pop-up menu are only those that
support the
some cast member media types such as 3D and DVD also support the
not appear in the Scripting Xtras pop-up menu because they are not implemented in Director as
scripting Xtra extensions.
interface() method and whose names actually appear in the pop-up menu. Although
interface() method, they do
Monitoring scripts in the Message window
You can set the Output pane of the Message window to display a record of the statements that a
movie executes as it plays. This is useful for tracking the flow of your code and seeing the result of
specific statements. You can do this in one of two ways.
To display statements in the Output pane, do one of the following:
• On the Message window, click Trace.
• Set the Movie object’s traceScript property to TRUE.
Entries after a double equal sign (==) indicate what has occurred in the movie—such as which
frame the movie has just entered, which script is running, or the result of a method or setting
a value.
For example, the following line indicates several things:
== Frame: 39 Script: 1 Handler: mouseUp
• The movie entered frame 39.
• The movie ran script 1, the first script attached to the frame.
• The movie ran the mouseUp handler in script 1 after the movie entered the frame.
90Chapter 4: Debugging Scripts in Director
Entries after an arrow made up of a double hyphen and right angle bracket (-->) indicate lines of
your code that have run. For example, the following Lingo lines:
--> _sound.fadeOut(1, 5*60)
--> if leftSide < 10 then
--> if leftSide < 200 then
--> _movie.go("Game Start")
indicate that these Lingo statements have run. Suppose you were trying to determine why the
playhead did not go to the frame labeled "Game Start." If the line
_movie.go("Game Start")
never appeared in the Message window, maybe the condition in the
-->
previous statement was not what you expected.
The Message window Output pane can fill with large amounts of text when the Trace button is
on. To delete the contents of the Output pane, click the Clear button. If the Output pane is not
visible, the contents of the Input pane are deleted.
You can keep track of the value of variables and other objects by selecting the name of the object
in the Message window and clicking the Inspect Object button. The object is added to the Object
inspector, where its value is displayed and updated as the movie plays. For more information on
the Object inspector, see “Debugging in the Object inspector” on page 91.
When you are in debugging mode, you can follow how a variable changes by selecting it in the
Message window and then clicking the Watch Expression button. Director then adds the variable
to the Watcher pane in the Debugger window, where its value is displayed and updated as you
work in the Debugger window. For more information on the Watcher pane, see “Debugging in
the Debugger window” on page 94.
Debugging in the Object inspector
With the Object inspector, you can view and set properties of many kinds of objects that are not
displayed in the Property inspector. These include scripting objects such as global variables, lists,
child objects from parent scripts, all 3D cast member properties, sprite properties, script
expressions, and so on. In addition, the Object inspector displays changes to object properties
that occur while a movie plays, such as changes due to scripts or changes to sprite Score
properties. These kinds of runtime changes are not displayed in the Property inspector during
movie playback.
To open the Object inspector:
• Select Window > Object Inspector.
Debugging in the Object inspector91
Understanding object structure
The Object inspector can be very useful for understanding the structure of complex objects. For
example, 3D cast members have many layers of properties. Because the Object inspector shows
you a visual representation of the nested structure of those properties, it makes it much easier to
become familiar with them and their relationships to each other. Understanding the property
structure of objects in Director is important when writing scripts.
The ability to watch the values of properties change while a movie plays is helpful for
understanding what is happening in the movie. It is especially helpful when testing and
debugging scripts because you can watch as the values change based on scripts you’ve written.
The Director Debugger window displays this information also, but is only available when you
are in debugging mode. For more information on debugging, see “Advanced debugging”
on page 99.
Viewable objects
The following are some of the objects you can enter into the Object inspector:
• Sprites, such as sprite(3)
• Cast members, such as member("3d")
• Global variables, such as gMyList
• Child objects, such as gMyChild
• Macromedia Flash objects, such as gMyFlashObject; for more information about using Flash
objects in Director, see the Using Director topics in the Director Help Panel.
• Script expressions, such as sprite(7).blend
Viewing objects
There are three ways to view an object in the Object inspector. You can drag items directly into
the Object inspector, enter the name of an item into the Object inspector manually, or use the
Inspect Object button in the Message and Script windows.
To drag an item to the Object inspector, do one of the following:
• Select a sprite in the Score window and drag it to the Object inspector.
• Select a cast member in the Cast window and drag it to the Object inspector.
• Select a the name of an object in the Script, Message, or Text window and drag it to the
Object inspector.
To enter an object manually in the Object inspector:
1 Double-click in the first empty cell in the Object column of the Object inspector.
2 Type the name of the object into the cell. Use the same name you would use to refer to the
object in your scripts.
3 Press Enter (Windows) or Return (Macintosh). If the object has subproperties, a plus sign (+)
appears to the left of it.
4 Click the plus sign. The properties of the object appear below it. Properties with subproperties
appear with a plus sign to their left. Click each plus sign to display the subproperties.
92Chapter 4: Debugging Scripts in Director
To view an object using the Inspect Object button:
1 In the Script window, highlight the part of a statement that refers to an object.
2 In the Script window, click Inspect Object. If the object has subproperties, a plus sign (+)
appears to the left of it.
3 Click the plus sign. The properties of the object appear below it. Properties with subproperties
appear with a plus sign to their left. Click each plus sign to display the subproperties.
Note: Inspecting large numbers of objects or large individual objects in the Object inspector can
cause noticeable performance issues during authoring, particularly when Auto Poll is enabled. For
example, inspecting a list that contains 10,000 entries can make Director appear to hang while the
display is updating.
Navigating objects
You can also navigate the contents of the Object inspector with the arrow keys on your keyboard.
To move up or down in the list of items:
• Use the Up and Down arrow keys.
To view an item’s subproperties:
• Select the item and press the Right arrow key.
To hide an item’s subproperties:
• Select the item and press the Left arrow key.
Using Autopoll
System properties, such as
milliseconds and colorDepth are only updated in the Object
inspector when the Autopoll option is turned on. Using Autopoll increases the processor
workload, which can slow your movie’s performance when you add more than a few system
properties to the Object inspector.
To turn on Autopoll:
1 Right-click (Windows) or Control-click (Macintosh) in the Object inspector. The Object
inspector context menu appears.
2 Select Autopoll from the context menu. When Autopoll is on, a check mark appears next to the
Autopoll item in the context menu.
To turn off Autopoll:
• Select Autopoll from the context menu again.
Modifying object or property values
You can set the value of an object or property in the Object inspector by entering a new value in
the box to the right of the object or property name.
To set an object or property value:
1 Double-click the value to the right of the item name.
2 Enter the new value for the item.
3 Press Enter (Windows) or Return (Macintosh). The new value is set and reflected in your
movie immediately.
You can enter a script expression as the value for an item. For example, you might set the value of
sprite(3).locH to the expression sprite(8).locH + 20.
Debugging in the Object inspector93
Removing objects
You can also remove items from the Object inspector.
To remove a single item from the Object inspector:
• Select the item and press the Backspace (Windows) or Delete (Macintosh) key.
To clear the entire contents of the Object inspector:
• Right-click (Windows) or Control-click (Macintosh) inside the Object inspector and select
Clear All from the context menu.
When you open a separate movie from the one you are working on, the objects you entered in the
Object inspector remain. This makes it easy to compare different versions of the same movie.
When you exit Director, the items in the Object inspector are lost.
Debugging in the Debugger window
The Debugger window is a special mode of the Script window. It provides several tools for finding
the causes of problems in your scripts. By using the Debugger, you can quickly locate the parts of
your code that are causing problems. The Debugger window allows you to run scripts one line at
a time, skip over nested handlers, edit the text of scripts, and view the values of variables and other
objects as they change. Learning to use the tools in the Debugger window can help you become a
more efficient programmer.
The Debugger window can help you locate and correct errors in your scripts. It includes several
tools that let you do the following:
• See the part of the script that includes the current line of code.
• Track the sequence of handlers that were called before getting to the current handler.
• Run selected parts of the current handler.
• Run selected parts of nested handlers called from the current handler.
• Display the value of any local variable, global variable, or property related to the code that
you’re investigating.
Entering debugging mode
In order to access the Debugger window, a break must occur in a script. A break occurs when
Director encounters a script error or a breakpoint in a script.
When a script error occurs, the Script Error dialog box appears. The dialog box displays
information about the type of error that occurred, and asks you whether you want to debug the
script, edit the script in the Script window, or cancel.
To enter debugging mode, do one of the following:
• Click Debug in the Script Error dialog box.
• Place a breakpoint in a script.
When Director runs and encounters a breakpoint, the script stops executing and the Script
window changes to debugging mode. The movie is still playing, but the execution of your scripts
is stopped until you use the Debugger to tell Director how to proceed. If you have multiple Script
windows open, Director searches for one containing the script where the breakpoint occurred and
changes that window to debugging mode.
94Chapter 4: Debugging Scripts in Director
To add a breakpoint that will open the Debugger window:
1 In the Script window, open the script that should contain the breakpoint.
2 Click in the left margin of the Script window next to the line of code where you want the
breakpoint to appear, or place the insertion point on the line of code and click Toggle
Breakpoint. Your code will stop executing at the beginning of this line, and the Script window
will enter debugging mode.
If the Script window is open when Director encounters a script error or a breakpoint, the
Debugger window replaces the Script window.
To stop debugging, do one of the following:
• Click the Run Script button in the Debugger window. This resumes normal script execution.
• Click the Stop Debugging button in the Debugger window. This stops both the debugging
session and the movie.
The Script window reappears in place of the Debugger window.
When the Debugger window opens, it shows the current line of code and offers several choices for
what to run next.
To see which is the current line of code:
• Look for the green arrow next to a line of code in the Script pane.
The green arrow points to the current line. You cannot select a different line of code by
clicking it in the Script pane.
Viewing the call stack in the Debugger window
The Call Stack pane displays the sequence of nested handlers that ran before the current line of
code. This sequence is called the call stack. Use the call stack to keep track of the structure of your
code while you are debugging. You can view the variables associated with a specific handler by
clicking the handler name in the Call Stack pane. The variables are displayed in the Variable pane.
Debugging in the Debugger window95
Viewing variables in the Debugger window
The Variable pane of the Debugger window displays the variables associated with the current
handler. The current handler is the handler displayed in the Script pane and the last handler
displayed in the Call Stack pane. You can also display the variables associated with previous
handlers in the call stack. As you step through a script, changes to the values of any of the
variables are displayed in red. For more information on stepping through scripts, see “Stepping
through scripts in the Debugger window” on page 97.
To display the variables associated with a handler in the call stack:
• Click the name of the handler in the Call Stack pane. The variables appear in the
Variable pane.
The Variable pane includes four tabs for viewing variables:
The All tab displays both global and local variables associated with the current handler.
The Local tab displays only the local variables associated with the selected handler.
The Property tab displays the properties declared by the current script.
The Global tab displays only the global variables associated with the selected handler.
You can sort the variables in the Variable pane:
• To sort the variables by name, click the word Name that appears above the variable names.
• To sort the variables in reverse-alphabetical order, click the word Name a second time.
You can change the values of local variables of the current handler and global variables in the
Variable pane. You cannot change the value of local variables that are not in the current handler.
To change the value of a variable in the Variable pane:
1 Double-click the value of the variable in the Value column.
2 Enter the new value for the variable.
3 Press Enter (Windows) or Return (Macintosh).
Viewing objects in the Debugger window
With the Watcher pane in the Debugger window, you can view variables and other data objects
associated with the current handler, as well as objects associated with other handlers. By adding
objects to the Watcher pane, you can keep track of their values as they change because of scripts.
When the value of an object changes due to the execution of a line of code, Director changes the
color of the object’s name in the Watcher pane to red.
The Watcher pane displays only the objects you add to it. You can use up to four separate tabs in
the Watcher pane to organize objects into groups.
To add an object to the Watcher pane whose name appears in the Script pane:
1 Select the name of the object in the Script pane.
2 Click the Watch Expression button.
96Chapter 4: Debugging Scripts in Director
To add an object to the Watcher pane whose name does not appear in the Script pane:
1 Double-click the first empty cell in the object column of the Watcher pane.
2 Type the name of the object in the cell and press Enter (Windows) or Return (Macintosh).
If the object has properties, a plus sign (+) appears next to the object’s name.
To display an object’s properties:
• Click the plus sign next to the object name.
The Watcher pane lets you organize objects in a few ways.
To organize objects in the Watcher pane, do one of the following:
• To sort the objects in the Watcher pane, click the Name column head at the top of the left
column. The object names in the column are listed in alphabetical order.
• To sort the objects in reverse-alphabetical order, click the Name column head a second time.
• To organize objects into groups, use the tabs in the Watcher pane. To add an object to a
specific tab, click the tab you want to use before adding the object.
• To clear the contents of a tab in the Watcher pane, select the tab and then right-click
(Windows) or Control-click (Macintosh) in the Watcher pane and select Clear All.
Stepping through scripts in the Debugger window
The Debugger window provides you with a set of tools for running scripts slowly, so you can
watch the effect that each line of code has on your movie. You can execute one line of code at a
time and choose whether to execute nested handlers one line at a time or all at once.
To execute only the current line of code indicated by the green arrow:
• Click the Step Script button.
Many handlers include calling statements to other handlers. You can focus your attention on such
nested handlers, or ignore them and focus on the code in the current handler.
When you are confident that nested handlers are performing as expected and want to concentrate
on the code in the current handler, the Debugger window can step over nested handlers and go
directly to the next line of code in the current handler. When the Debugger steps over a
nested handler, it executes the handler, but does not display the handler’s code or pause within
the nested handler.
To step over nested handlers:
• Click the Step Script button in the Debugger window.
The Step Script button runs the current line of code, runs any nested handlers that the line
calls, and then stops at the next line in the handler.
If you suspect that nested handlers are not performing as expected and want to study their
behavior, the Debugger window can run nested handlers line by line as well.
To run nested handlers one line at a time:
• Click the Step Into Script button in the Debugger window.
Clicking the Step Into button runs the current line of code and follows the normal flow
through any nested handlers called by that line. When finished with a nested handler, the
Debugger window stops at the next line of code within the upper-level handler.
Debugging in the Debugger window97
When you are finished debugging, you can exit the Debugger at any time:
To resume normal execution of code an exit the Debugger window:
• Click the Run Script button.
To exit the Debugger and stop playback of the movie:
• Click the Stop Debugging button.
Editing scripts in debugging mode
When you are in debugging mode, you may edit your scripts directly in the Debugger window.
This enables you to fix bugs as soon as you find them and then continue debugging.
To edit a script in the Debugger window:
1 Click in the Script pane and place the insertion point where you want to begin typing.
2 Enter the changes to the script.
You can jump to a specific handler by selecting the name of the handler and clicking the Go To
Handler button.
3 When you are finished debugging and editing scripts, click the Stop Debugging button. The
Script window returns to Script mode.
4 Click the Recompile All Modified Scripts button.
Debugging projectors and Shockwave movies
This section discusses debugging during runtime in Director projectors and movies that contain
Macromedia Shockwave content. You can use either the Message window or enable full script
error dialog boxes to debug projectors and movies that contain Shockwave content.
To debug using the Message window:
• Set the Player object’s debugPlaybackEnabled property to TRUE.
When this property is
content opens a Message window (Windows) or a Message text file (Macintosh), and the
results of any
put() or trace() function calls are output to these formats.
If at any time during the movie the
Message window or text file is closed and cannot be opened again during that playback session,
even if
debugPlaybackEnabled is set back to TRUE later in that session.
To debug by enabling full script error dialogs:
TRUE, playing back a projector or a movie that contains Shockwave
debugPlaybackEnabled property is set to FALSE, the
• In an .ini file for a projector or a movie that contains Shockwave content, set the
DisplayFullLingoErrorText property to 1.
This generates more descriptive error text in the script error dialog box than the generic error
text. For example, a generic error message might look like:
Script error: Continue?
Setting the DisplayFullLingoErrorText property to 1 could generate the following
error message:
Script error: list expected
For information on creating and modifying an appropriate .ini file for a projector or a movie
that contains Shockwave content, see the Director.ini template file in the root Director
installation folder.
98Chapter 4: Debugging Scripts in Director
Advanced debugging
If the problem is not easy to identify, try the following approaches:
• Determine which section has the problem. For example, if clicking a button produces the
wrong result, investigate the script assigned to the button.
If a sprite does the wrong thing, try checking the sprite’s property values. Are they set to the
values you want when you want?
• Figure out where the script flows. When a section of the movie does not do what you want,
first try to trace the movie’s sequence of events in your head. Look at other scripts in the
message hierarchy to make sure Director is running the correct handler.
• Follow the tracing in the Message window; this shows which frames the movie goes through
and any handlers that the movie calls as the movie plays.
• Try using the Step Script and Step Into features in the Debugger window and see whether the
results differ from what you expect.
• Check variables and expressions. Analyze how their values change as the movie plays. See if
they change at the wrong time or do not change at all. If the same variable is used in more than
one handler, make sure that each handler that uses the variable states that the variable is global.
You can track the values of variables and expressions by displaying their values in the Watcher
pane of the Debugger window or the Object inspector.
• Make changes one at a time. Don’t be afraid to change things in a handler to see if the change
eliminates the problem or gives some result that helps point to the problem.
However, do not trade one problem for another. Change things one at a time and change them
back if the problem is not fixed. If you introduce too many changes before solving a problem,
you might not determine what the original problem was and you might even introduce
new problems.
• Re-create the section. If you have not found the problem, try re-creating the section from
scratch. For example, if rolling the pointer over a sprite does not make the sprite behave the
way you want, create a simple movie that contains just the sprite and handler with the
rollOver() method.
Do not just copy and paste scripts; that might just copy the problem. Re-creating the section
lets you reconstruct the logic at its most basic level and verify that Director is working as you
expect. If the section that you re-create still does not work properly, chances are that there is
something wrong in the logic for the section.
If the section that you re-create works properly, compare that section to the original movie to
see where the two differ. You can also copy the section into the original piece and see whether
this corrects the problem.
Advanced debugging99
100Chapter 4: Debugging Scripts in Director
Loading...
+ hidden pages
You need points to download manuals.
1 point = 1 manual.
You can buy points or you can get point for every manual you upload.