Learning to Program with Lingo
There are numerous books on the market that claim that you can learn a
programming language in day or even hours. The idea of learning Lingo (or
another programming language) in hours or days is misleading and unrealistic,
especially if you've had no experience with any other form of programming.
Computers are very stupid. They know nothing other than what they have been
told. They will do exactly what you tell them do to but you will have to
tell them in minute detail how they must do it. Programming is a
way of communicating with your computer. Learning to program involves more
than learning the 'words' and 'grammar' of the programming language. It
involves learning a way of thinking, which is very different to traditional
natural thinking. This can only be achieved with lots of practice and experience.
You can read more about the programming way of thinking in the Introduction
to Programming (PDF link) article.
What I intend to do here is take you through the first steps into the programming
world by looking at two areas of programming that move beyond go to
navigation behaviors. These areas are conditions, conditional statements
and loops. A number of programming terms will be used in this article,
and while most are explained here, you can find further information in my
Lingo & Programming Terminology definitions
page.
Programming Types
Procedural programming is a way of writing code as a list of instructions,
telling the computer, step-by-step, what to do. For example, a procedural
program may instruct the computer to read a number, multiply it by 6, display
the result. The instructions are activated in the order they are given.
Computer languages like BASIC, Pascal, C and FORTRAN are procedural. Procedural
programming is good for small projects. It is the most natural way to tell
a computer what to do, and the computer processor's own language, machine
code, is procedural. So, the translation of the procedural high-level language
into machine code is straightforward and efficient.
Object Oriented Programming (also known as OOP) is a form
of programming where the code is broken down into self-contained units (called
objects), each of which performs a single function. When that function
is needed, the application calls the object by sending a stream of
information (called messages).
Lingo is an object oriented programming language, as is C++ and Java.
Separating your code into discrete units makes programming much easier for organisation, management, reuse and modification and general efficiency in writing code.
Director's Programming Languages
With the release of Director MX 2004, the program now supports 2 programming
languages. These are Lingo and JavaScript Syntax. JavaScript Syntax was introduced
as there was a high demand from the programmer user base for a language
that is closer to other common languages.
The principles of programming in Lingo or JavaScript Syntax are the same.Your
choice of which to use will depend on your comfort level with the syntax.
Saying that, I am going to focus on Lingo. The reason is that Lingo is more
English-like, and in my experience, more friendly to non-programmers.
There are 2 types of syntax within Lingo verbose and dot
syntax. (Dot syntax was introduced in Director 7.) In verbose syntax,
you write an instruction in an English like sentence. In dot syntax, words
are replaced by dots and brackets. Let's look at example to change the text
of cast member "lecturer name" to "dean".
verbose syntax.
set the text of member "lecturer name" to
"dean"
The above statement (single line of code) is very
much like an English sentence. Programmers like to write quickly. So
Lingo coding evolved so that some words, from statements like the one above, could be dropped. We can drop
'set' and change 'to' to '='. So we'd have the following statement:
the property of object = value
dot syntax
member("Message").text = "dean"
In dot syntax, the statement is simplified further into a format
of object.property=value.
In Director MX 2004, the help files no longer list verbose
syntax, so it's probably a good idea to learn dot syntax.
Conditions and Conditional statements
It is often useful to determine whether a certain condition exists
before carrying out a set of instructions. The term TRUE or the number 1
indicates that the condition you’re testing for exists, and the term FALSE
or the number 0 indicates that a condition doesn't’t exist.
Examples of property conditions
the soundEnabled - system property that determines
if the sound is on (TRUE) or off (FALSE).
the mouseDown - system property that indicates
whether the mouse is currently being pressed (TRUE) or not (FALSE).
Some conditions can be tested only (like the mouseDown), others can
be tested and set (like the soundEnabled). You can switch conditions
by using the not operator.
the soundEnabled = not(the soundEnabled)
The above changes a TRUE value to FALSE and a FALSE value to TRUE, in other
words turns the sound on when it is off and turns it off when it is on.
Conditional statements allow you to check for a particular condition
and then act on it in a certain way. There are two ways you can test conditions.if..then
and case.
Using if... then
if condition(expression) then do something
(statement)
A single line if... then if the simplest form of a conditional
statement. You test for a condition and give an instruction if that condition
is met.
Example 1
Say we wanted to create our own custom scrollable text, we could control
the horizontal location property (locH) the vertical location property (locV).
A statement could be written as follows:
sprite(1).locV = sprite(1).locV + 10
This statement moves sprite 1 up by 10 pixels, by setting the locV to its
original value + 10. However, say we wanted it to stop moving up when it
reached a certain point, we could write the following:
if sprite(1).locV < 320 then sprite(1).locV = sprite(1).locV
+ 10
For a down statement, we may write:
if sprite(1).locV > 180 then sprite(1).locV = sprite(1).locV
- 10
So, we may have two behaviors for a up button and down button, and we use
a condition to restrict the movement to a minimum and maximum area.
Example 2
if rollover(1) then member("Message").text = "You
have moved the mouse over sprite 1."
Note we could have written the above as:
if rollover(1) = TRUE then member("Message").text
= "You have moved the mouse over sprite 1."
We can leave out = TRUE as the absence of
it allows the statement to assume a TRUE value for the condition.
Example 3
if rollover(1) then
member("Message").text = "You have moved the mouse over sprite 1."
else
member("Message").text = "The mouse is not over sprite 1."
end if
This example above tests whether the cursor is over sprite 1 and sets the
text of cast member '"message" to "You have moved the mouse over
sprite 1" if it is over sprite 1 and "The mouse is not over sprite
1" if it is not.
Using a multiple line if then requires an end if
statement to end the if segment. Using the operator and determines
multiple expressions are true. Using the operator or determines
whether either of the expressions are true.
if rollover(1) or rollover(2)
member("Message").text = "You have moved the mouse
wither over sprite 1 or over sprite 2."
end if
Sometimes, it is useful to place one condition within another.
if condition1 then
if condition2 then
do something
end if
end if
In the situation above, Lingo first tests for condition1. If it exists,
it will then test for a second condition and do something
if that condition exists as well. In this example, we could have just used
the and operator as in:
if condition1 and condition2 then ...
However, if we wanted to do something if condition 1 only existed, and do
something different if both conditions existed, then we'd use nested
conditions.Nesting is the process of putting one control statement
within another.This can be the form of if.. thens within if..
thens, if.. thens within loops or loops within loops.
(Loops are discussed lower down.) Note, when we use nesting, as in the example
above, we have to have multiple end ifs to close that nested segment
of code.
Using case
case expression of
value1 : statement
value2 : statement
otherwise:
statement(s)
end case
The case syntax uses a multiple branching logic structure
that is easier to write than repeated if...then statements.
Example
case the rollover of
1: member("Message").text = "You have moved the mouse over sprite 1."
2: member("Message").text = "You have moved the mouse over sprite 2."
3: member("Message").text = "You have moved the mouse over sprite 3."
otherwise
member("Message").text = "The mouse is not over sprite 1, 2 or 3."
end case
This case example above tests whether the cursor is over sprite 1, 2, or
3 and sets the text of cast member '"message" appropriately.
The if... then version of the above would be
if rollover(1) then
member("Message").text = "You have moved the mouse over sprite 1."
else if rollover(2) then
member("Message").text = "You have moved the mouse over sprite 2."
else if rollover(3) then
member("Message").text = "You have moved the mouse over sprite 3."
else
member("Message").text = "The mouse is not over sprite 1, 2 or 3."
end if
As you can see, the case version is better for the above example.
Loops
Loops are the process
of continually repeating a section of a script/movie. Code can be repeatedly
activated while a certain condition is true or for a specified number of
times.
To repeat a set of instructions as long as a specific condition exists:
repeat while condition
statement(s)
end repeat
Example
repeat while the mouseDown
nothing
end repeat
The above pauses everything while the mouse button is in a down-pressed
state. It is a useful loop to be placed towards the end of a mouseDown handler.
By doing this, any Lingo statements following the end
repeat statement, while be activated in a mouseUp event.
To repeat an action a specified number of times:
repeat with localVariable = startValue to endValue
statement(s)
end repeat
The above executes the Lingo statement(s) a
number of times specified by localVariable.
The value of this variable is the difference between the value specified
by startValue and the value specified by endValue.
The localVariable is incremented by 1 each
time Lingo cycles through the repeat loop.
You can count down by using:
repeat with localVariable = startValue down to endValue
Example
repeat with x = 6 to 10
sprite(x).visible = 1
end repeat
The above example makes sprites 6 to 10 visible. It uses a local variable
in the form of x. The statement sprite(x).visible
= 1 is run 5 times (from 6 to 10) counting up by 1 each time, and
substituting that value in the place of x.
It is easier to use the loop in this way rather than having to write:
sprite(6).visible = 1
sprite(7).visible = 1
sprite(8).visible = 1
sprite(9).visible = 1
sprite(10).visible = 1
To exit a repeat loop:
Use the exit repeat command. This instructs Lingo to leave
the repeat loop and jump to the statement. following the end repeat
statement and to remain within the current handler.
To skip a particular loop and jump to the next step:
Use the next repeat command.
Example
repeat with x = 6 to 10
if (x mod 2) = 1 then next repeat
sprite(x).visible = 1
end repeat
The above example makes sprites 6, 8 and 10 visible. The statement sprite(x).visible
= 1 is not activated for odd numbers because the use of the next
repeat in the conditional statement - if (x
mod 2) = 1 then next repeat. The use of the mod
operator performs the arithmetic modulus operation on two integer expressions.