Director Tutorials

 

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.