Vous êtes sur la page 1sur 42

overview

today we'll explore flash programming fundamentals


after each theory segment, we'll study an example: a
multiple choice quiz
we'll build 3 versions of the quiz
user experience won't change with each quiz version
instead, we'll improve the code structure so it's:
 easier to maintain
 easier to extend
 faster to build
download example files here

the learning cycle


always remember: learning to program is a process, not an
event
you should expect to learn something every time you
program
don't worry if you don't follow everything the first time
through
even those things you don't understand will give you get a
sense of what's possible

speaking actionscript
programming languages are used to send information to and
receive information from computers
programming languages have vocabulary and grammar used
to communicate, just like human languages
using a programming language we tell a computer what to
do or ask it for information

expressing logic
the art of programming lies in the formulation of logical
steps
think of programming a computer like talking to a child:
 be explicit in every detail
 list every single step that's necessary to complete a task

flash's programming environment


Actions panel: the place you put your instructions
Window > Development panels > Actions (or "F9")
the "instructions" are known as "code" or "script"
Actions panel includes a quick reference pane for help while
you code
you can also put code in external text files, but for now we'll
stick to the actions panel

what you can do with actionscript


some of the things you can do with actionscript code:
 control the playhead of a timeline
 move things around
 create and manage user interfaces
 play sounds
 control video
 manage data (xml, lists, etc)
 communicate with server-side applications (e.g., web servers)

where to put the code


within a .fla file, code is attached to either a frame, button,
or movie clip
to attach code to a frame, button, or movie clip, first select
it, then type in the actions panel
notice that the actions panel title changes to match the
current selection (Actions - Frame, Actions - Button, or
Actions - Movie Clip
check the actions panel title before typing so you know what
you're attaching your code to
code on a movie clip or button controls that clip or button
generally speaking, placing code on clips and buttons is
discouraged, but is sometimes convenient

say hi to flash
select frame 1
type the following into the right side of the Actions panel:
var message = "Hi there Flash!";
that line of code constitutes a complete instruction, known
as a statement
now create three more statements:
var firstName = "your name here";
trace(message); trace("Hi
there, " + firstName + ", nice to meet you.");
the code doesn't do anything until we export a .swf file and
play the movie
select Control>>Test Movie

storing information
take another look at our first line of code
var message = "Hi there Flash!";
a literal translation for that code is:
Flash, please remember a piece of information for me...
...specifically, remember the phrase 'Hi there Flash!'
...please label the information message so that i can ask you for
it later
...whenever i ask you for message, give me back the text 'Hi
there Flash!
storing information is one of the foundations of programming
you can label stored information so that it can be used later

variables
look at our second line of code again:
var firstName = "your name here";
it asks Flash to remember our first name and label it firstName
Flash can remember any information that is considered a
valid type of data, such as numbers and text
in programming terms a piece of "text" is also known as
string
an individual piece of data is known as a datum
a datum (e.g., "Hi there Flash!") and the label that identifies it
(e.g., message) are together known as a variable

variable terminology
a variable's label ("message") is called its name
a variable's datum ("hi there Flash!") is called its value
a variable is said to "store" or "contain" its value
specifying a variable's value is called "assigning" or "setting"
the variable
to assign a variable a value, use the equals sign: =
creating a variable is called declaring it
to declare a variable, use the keyword var
example sentence: "declare a new variable named message,
and assign it the value "Hi there Flash!"

the interpreter
recall our third statement
trace(message);
it issues a command, trace, that causes data to appear in the
Output window
how does that work?
when you create a variable or issue a command, you're
actually addressing the ActionScript interpreter
the interpreter is the part of Flash that executes ActionScript
code
the interpreter does the following:
 runs your programs
 manages your code
 listens for instructions
 performs any ActionScript commands
 stores your data
 sends you information
 calculates values
if the interpreter understands your commands, it sends them
to the computer's processor for execution
if a command generates a result, the interpreter provides
that response to you
if the interpreter can't understand the command, it sends
you an error message
for example, try running this code:
= "test";
the interpreter outputs an error. it doesn't expect the =
without a variable name
remember that the interpreter has to read your code, letter
by letter, and try to understand it
error messages are GOOD! because they help you fix your
code

arguments
commands usually require supplementary information to run
for example, the trace() command requires the text to display
the data sent to a command is called an argument
to supply an argument to a command, enclose the argument
in parentheses, like this:
command(argument);
to supply multiple arguments to a command, separate them
with commas, like this:
command(argument1, argument2, argument3);
supplying an argument to a command is known as passing
the argument
for example, in the code gotoAndPlay(5):
 gotoAndPlay is the name of the command
 5 is the argument being passed (the frame number)
some commands, (e.g., stop()) require parentheses but can
not be passed arguments. we'll learn why later
operators
take another look at our fourth line of code:
trace("Hi there, " + firstName + ", nice to
meet you.");
the + signs join (concatenate) our text together
+ is one example of a programming tool called an operator
operators are like conjunctions ("and," "or," "but," etc.) in
human languages
all operators link phrases of code together
most operators transform data in some way
example operators:
 arithmetic: -, +, *, /
 comparison: < (less than), > (greater than)

logic in a program
we make millions of basic decisions in our daily lives
for example, when crossing the road we decide:
 if a car is coming, we wait for it to pass
 if a car is not coming, we cross the road
a program must make similar decisions based on the state of
its environment
for example:
 if the user has seen the website's introduction already, don't show it again
 if the user specifies the wrong password to a restricted zone, don't show the restricted content
a "decision" in a program means choosing whether or not to
execute a section of code

conditional statements
to let a program decide whether to execute code, we use a
conditional statement (a.k.a., a "conditional")
generic conditional structure:
if (this condition is met) { then execute
these lines of code
}
for example:
if (username == "James Bond") {
trace ("Welcome to my website, 007."); }
the equality operator, ==, tests if two data values are equal
don't mistake the equality operator (two equal signs ==) with
the assignment operator (one equal sign =)!
to execute an alternative section of code when a condition is
not met, use an else statement
if (userName == "James Bond") {
trace ("Welcome to my website, 007."); } else
{ trace
("Sorry, only James Bond can use this site.");
}
to execute one of many possible sections of code, use else if:
if (userName == "James Bond") {
trace ("Welcome to my website, 007."); } else
if
(userName == "Moock") { trace("Welcome to my
website, Colin."); } else { trace ("Sorry,
only James Bond or Colin can use this
site."); }

repetitive tasks
suppose you want to display a five-number sequence in the
Output window, starting at any number
you could display the sequence like this:
trace(10); trace(11); trace(12); trace(13);
trace(14);
if you want to start the sequence at 513, you have to retype
all the numbers
trace(513); trace(514); trace(515);
trace(516);
trace(517);
to avoid this retyping, we use a variable:
var x = 1; trace (x); x = x + 1; trace (x); x
= x + 1; trace
(x); x = x + 1; trace (x); x = x + 1; trace
(x);
to change the sequence starting number, just change the
initial value of x
but what if we want to count to 500?
even with the variable, it's too much typing

loops
to perform repetitive tasks, we use a loop
a loop is type of statement that causes a block of code to be
repeated
here's what the counting example looks like as a while loop:
var x = 1; while (x <= 5) { trace (x); x = x +
1; }
the statements to repeat are listed between the brackets: { }
the keyword while starts the loop
the comparison (x <= 5) indicates when to quit repeating the
loop
the loop stops repeating when x is less than or equal to 5
to make the loop count to 500, simply change 5 to 500

the for loop


basic loops come in two varieties: a while loop and a for loop
for does the same thing as while, but with a different syntax
here's a for loop:
for (var x = 1; x <= 5; x = x + 1) { trace(x);
}
the for loop is like a condensed while loop
the contents of the loop are the same, but rearranged:
initialize while (compare) { statements update
} for
(initialize; compare; update) { statements }
the for loop makes the initialization, comparison, and update
easier to find

functions
a function is a group of statements packaged together to
form a single, reusable command
functions let us write code once, but use it many times
throughout a program

repetition is bad
suppose we use this code to display the area of a rectangle:
var height = 10; var width = 20; trace(width *
height);
later we decide we want to display the area of five different
rectangles
our code gets 5 times longer:
var height1 = 10; var width1 = 20;
trace(width1 * height1);
var height2 = 234; var width2 = 59;
trace(width2 * height2); var height3 = 40;
var width3 = 99; trace(width3 * height3); var
height4 = 39; var width4 = 875;
trace(width * height); var height5 = 3; var
width5 = 2; trace(width5 *
height5);
notice that the same three statements are used for each
rectangle
repeating statements is error-prone and time-consuming
instead of repeating statements, create functions that
contain the repeated code
an example function
here's a function that displays the area of a rectangle
function displayArea (width, height)
{ trace(width * height);
}
the function keyword starts the function declaration
next comes the name of the function: displayArea
next comes a list of arguments used by the function, in
parentheses: (width, height)
finally, we list the statements of the function, within
brackets: { }
the statements contain the code that would otherwise have
been repeated

running a function
to run a function use same format as trace() command earlier
first, specify the function name:
displayArea
then provide any required arguments:
displayArea(10, 20);
the statements inside the function then run with width set to
10 and height set to 20

running a function, illustrated


here is the flow of operations for our example function
execution:
code comparison
here's our old code, with repeated statements:
var height1 = 10; var width1 = 20;
trace(width1 * height1);
var height2 = 234; var width2 = 59;
trace(width2 * height2); var height3 = 40;
var width3 = 99; trace(width3 * height3); var
height4 = 39; var width4 = 875;
trace(width * height); var height5 = 3; var
width5 = 2; trace(width5 *
height5);
here's the new code, with a function:
function displayArea (width, height)
{ trace(width * height);
} displayArea(10, 20); displayArea(234, 59);
displayArea(40, 99);
displayArea(39, 875); displayArea(3, 2);
the new code is shorter
the new code is easier to understand
function names describe what the code is doing

code comments
to add even more descriptive information to our code, we
use comments
a comment is a note in code that is meant to be read by
programmers
any line of code that starts with // is a comment:
// This is a comment...
comments help programmers understand how code works
you should always narrate your code with comments
for example...
// Displays the area of a rectangle in
Flash's Output window function displayArea
(width, height) { trace(width
* height); } // Display the area of five
rectangles
displayArea(10, 20); displayArea(234, 59);
displayArea(40, 99); displayArea(39,
875); displayArea(3, 2);

exiting and returning values from


functions
normally, a function ends when its last statement executes
but you can also stop a function manually, using a return
statement
for example, this revised version of displayArea() quits before
the area is ever displayed:
function displayArea (width, height) { return;
trace(width * height); }
usually, we only quit functions early based on some
condition
for example, this function quits if the supplied password is
wrong:
function enterSite(pass) { if(pass !=
"cactus") { // Exit if
the password is wrong: return; } // This code
is reached only if the password is
correct. gotoAndPlay("intro"); }
enterSite("hackAttack"); // Function will exit
prematurely enterSite("cactus"); // Function
will end naturally

built-in functions
take another look at the command gotoAndPlay() from the
previous example:
gotoAndPlay("intro");
is a built-in function, provided by ActionScript
gotoAndPlay()
there are lots of built-in functions, and they are used just
like any other function

returning to the point of


execution
when a function finishes, the interpreter continues executing
any code after the function call
for example:
// When this function is done
displayArea(25, 10); // Execution resumes here
trace("Done calculating area of first
rectangle"); // When
this function is done displayArea(13, 4); //
Execution
resumes here trace("Done calculating area of
second
rectangle");

returning information to the point


of execution
returnalways terminates a function
but return can also send information back to the script that
invoked the function
for example, the displayArea() function could return width*height
instead of displaying it:
function displayArea (width, height) { return
width * height;
}
the information returned by a function is called a return
value

using a function's return value


return values are often used to set a variable's value
for example, this code sets rectangleArea to 200:
var rectangleArea = displayArea(10, 20);
now that displayArea() returns the area instead of displaying it,
we should rename it to getArea()
function getArea (width, height) { return
width * height;
}
return values can even be added together
// Sets totalArea to 260 var
totalArea = getArea(10, 20) + getArea(5, 12);

objects
let's review a couple of concepts:
 a statement instructs Flash to do something
 a function groups multiple statements into a convenient command
an "object" takes the next logical step: it packages related
functions and variables into a single code module
each object is like a self-contained, miniature program
multiple objects can be used together like building blocks to
form complex functionality

object-oriented programming
object-oriented programming (oop) means structuring your
code with objects
some languages require that all code be contained by some
object (e.g., Java)
in flash, you can put all your code in objects if you want, but
it's not mandatory

custom objects vs built-in objects


just as some functions are built-in to ActionScript, some
objects are also built-in
built-in objects let us control:
 visuals (movie clips, buttons, text, video)
 sounds
 network communication
 ....and many other things in a movie
to program in flash, you must use the built-in objects
hence, some OOP knowledge is required, even if you don't
structure your own code with objects

movie clip objects


each movie clip instance on stage is represented by an
actionscript object
to control a movie clip object, we must give the movie clip
an instance name
once a movie clip has a name, we can:
 set its variables (also called "properties")
 control it by calling its functions (also called "methods")
for example, suppose we give a movie clip the instance
name ball
we can then set the horizontal position of the ball movie clip
like this:
ball._x = 150;
and we can make the ball movie clip stop playing like this:
ball.stop();

the language of objects


using objects, we can create sentence-like instructions in
code:
 the object is a noun
 the property is an adjective
 the method is a verb
for example:
object.property = value; noun.adjective =
value;
object.method(); noun.verb();

let's see it all in action!


we've now learned quite a lot of theory
let's apply that theory to an example: a multiple choice quiz

quiz overview
two questions; each with three multiple-choice answers
users submit their answers by clicking answer buttons
user answers are recorded in a variable
answer variables are used to calculate the user's score
at the end of the quiz, the score is displayed

build the layer structure


make a layer called scripts on which to place code
keep the scripts layer at the top so it's easy to find
make a layer called labels for all labels in our movie
make four layers for our quiz assets
 quiz end: for the results screen
 question 2: for the second question screen
 question 1: for the first question screen
 choice buttons: for the answer buttons
 housing: for the background and instructions
add 30 frames to all layers

create the question 1 screen


frame 1, question 1 layer, add text: "1) When were movie clips
introduced into Flash?"
below the question text add the answer text:
 Version 1
 Version 2
 Version 3

create the question 2 screen


select frame 1 of question 1 layer
right-click > copy frames
select frame 1 of question 2 layer
right-click > paste frames
insert blank keyframe at frame 10 of question 1 layer
at frame 10 of question 2 layer:
 change the question number from "1" to "2"
 change the text of the question to, "When was MP3 audio support added to Flash?"
 change the multiple choice answers to Version 3, Version 4, and Version 5
 notice that frames are used to represent application screens

add the answer buttons


create a simple button for the user to choose an answer
at frame 1 of choice buttons layer, place three answer button
instances
set instance name for buttons to: choice1_btn, choice2_btn, and
choice3_btn

initialize the quiz


add the code that initializes the movie to frame 1 of scripts
layer
no preloader for this example
first describe what the code does with a comment:
// Initialize main timeline variables
next, create variables to store user's answers:
var q1answer; // User's answer for question 1
var q2answer; //
User's answer for question 2
next, create a variable to track number of questions
answered correctly:
var totalCorrect = 0; // Counts number of
correct answers
finally, stop the movie at the first question:
stop();
variable naming styles
to indicate multiple words in variables use capital letters:
totalCorrect
or underscores:
total_correct
give variables and functions meaningful names
for example, avoid single letters, like "x" or abbreviations,
like "tc"
well-named variables help you understand how the code
works

add frame labels


question 2 is on frame 10, so when we want to display
Question 2 we could do this:
gotoAndStop(10);
sensible code, right? WRONG!
if we add frames before frame 10, our code breaks!
to avoid this problem, use frame labels
 at frame 1, labels layer, set the label to init
 at frame 10, labels layer, add a blank keyframe
 at frame 10, labels layer, set the label to q2
 at frame 20, labels layer, add a blank keyframe
 at frame 20, labels layer, set the label to quizEnd
now we can add frames before question 2 and our code will
still work

responding to answer button


clicks
to submit an answer to a question, the user clicks the
appropriate answer button
our code must record the user's choice in either q1answer or
q2answer
how do we set a variable when a button is pressed?
using an event handler...
event-based code vs timeline
code
two things cause code to run in flash:
 the playhead enters a frame with a script on it
 an event occurs (either user input or a system notification)
to run code in response to an event, we create an event
handler function or an event listener object
today, we'll only study event handler functions

event broadcast
every event in flash is triggered by some object
for example:
 the Stage object tells you when the movie is resized
 the Key object tells you when a key is pressed
 a Button object tells you when a button is clicked

event-handler functions
to respond to a "button clicked" event from a button...
...define an event handler function on that button
theButton.onRelease = eventHandlerFunction;
 theButton is the button instance that was clicked
 onRelease is the name of the event
 eventHandlerFunction is the function that should run when the button is clicked
the eventHandlerFunction can be defined inline or somewhere else
// Define the event hanlder function
inline... theButton.onRelease = function ()
{ // Store the user's answer
}
// Or define the event handler function
separately... theButton.onRelease =
storeAnswer; function storeAnswer ()
{ // Store the user's answer }
here's the general format for event handler functions:
eventBroadcastingObject.nameOfEvent =
eventHandlerFunction;

handling the answer button


events, question 1
question 1 answer-button-handlers are defined on frame 1,
scripts layer
here's the event handler function for answer button 1 of
question 1:
// Code executed when button 1 is pressed.
choice1_btn.onRelease = function ()
{ this._parent.q1answer = 1;
this._parent.gotoAndStop("q2"); };
the function does two things:
 records the user's choice in q1answer
 displays question 2
new code introduced:
 this means choice1_btn (the button that broadcast the event)
 _parent means the timeline containing choice1_btn
code for other two answer buttons follows same pattern:
// Code executed when button 2 is pressed.
choice2_btn.onRelease = function ()
{ this._parent.q1answer = 2;
this._parent.gotoAndStop("q2"); }; // Code
executed when button 3 is pressed.
choice3_btn.onRelease = function ()
{ this._parent.q1answer = 3;
this._parent.gotoAndStop("q2"); };

handling the answer button


events, question 2
frame 10, scripts layer, add a blank keyframe
question 2 answer-button-handlers are defined on frame 10,
scripts layer:
// Code executed when button 1 is pressed.
choice1_btn.onRelease = function ()
{ this._parent.q2answer = 1;
this._parent.gotoAndStop("quizEnd"); }; //
Code executed when button 2 is
pressed. choice2_btn.onRelease = function () {
this._parent.q2answer = 2;
this._parent.gotoAndStop("quizEnd"); }; //
Code executed when button 3 is
pressed. choice3_btn.onRelease = function () {
this._parent.q2answer = 3;
this._parent.gotoAndStop("quizEnd"); };
code for question 2 answer buttons is identical to question 1
buttons except:
 user's choice is stored in q2answer (instead of q1answer)
 quiz end screen is displayed (instead of question 2)

ending the quiz


quiz is mostly functional
to finish it, we'll:
 build a final results screen
 calculate and display the user's score

building the results screen


frame 20, scripts layer, add a blank keyframe for score-
calculation code
frame 20, question 2 layer, add a blank keyframe
frame 20, choice buttons layer, add a blank keyframe
frame 20, quiz end layer, add a blank keyframe
frame 20, quiz end layer, add text "Thank you for taking the
quiz!"

calculating the user's score


the score-calculation code is attached to frame 20, scripts
layer
recall that the user's score is stored in the variable totalCorrect
if the answer to question 1 is correct, add one to totalCorrect (3
is the correct answer)
if (q1answer == 3) { totalCorrect =
totalCorrect + 1; }
if the answer to question 2 is correct, add another one to
totalCorrect (2 is the correct answer)
if (q2answer == 2) { totalCorrect++; }
the operator adds one to a variable
++
totalCorrect now stores the user's score

displaying the score on screen


to display the user's score, create a text field:
this.createTextField("totalOutput_txt", 1,
150, 200, 200,
20);
this is main movie timeline
createTextField() is a built-in MovieClip method
totalOutput_txt is the name of the text field
now display the score in the text field:
totalOutput_txt.text = "Your final score is: "
+ totalCorrect
+ "/2.";
notice that the text field is an object (lots of things are
objects)
the text property is the text to display on screen

a little fun
break time! let's make a mouse toy
see mouseTrailer-01.swf through mouseTrailer-04.swf in /examples/visuals
folder
experimentation is key
build something simple, then play with it (change values,
parameters, etc)

centralizing code
our quiz has two problems:
 the code is spread over three frames (hard to find, understand)
 the button handler code is very repetitious (prone to error)
to fix these problems, we'll:
 move all code to frame 1
 introduce two functions: answer() and gradeUser()

quiz v2, initialization


as before, we stop our quiz on question 1:
stop();
then initialize variables
we use q1answer and q2answer just like last time:
var q1answer; // User's answer for question 1
var q2answer; //
User's answer for question 2
and we add these new variables:
var numQuestions = 2; // Number of questions
in the quiz var
correctAnswer1 = 3; // The correct choice for
question 1 var correctAnswer2 = 2;
// The correct choice for question 2 var
currentQuestion = 1; // The question
being answered

the answer() function


purpose: to reduce code repetition in answer button handlers
each answer button will call answer() when pressed
answer() has two duties:
 record the user's choice
 advance the quiz to either: a) the next question, b) the end results screen
here's the answer function skeleton:
function answer (choice) { }
choice parameter stores the user's answer

asserting that the code works


first task in the function: debugging information
display the current question and choice in the Output
window:
function answer (choice) { trace("Question " +
currentQuestion
+ ". The user answered: " + choice); }
we can now check if the code is doing what we expect
build code incrementally: when one section works, build the
next section

setting the answer variables


when answer() runs, we must set either q1answer or q2answer
how do we know which one to set?
the currentQuestion variable tells us
when currentQuestion is 1, we should set q1answer
when currentQuestion is 2, we should set q2answer
here's how that looks in code:
function answer (choice) { // Display the
question and answer
in the Output window for debugging.
trace("Question " + currentQuestion + ". The
user answered: " + choice); // Record the
user's answer to
this question. if (currentQuestion == 1)
{ q1answer = choice; } else if
(currentQuestion == 2) { q2answer =
choice; } }
advancing the quiz
once the answer has been recorded, we advance the quiz
if the current question is the last question...
 ...calculate user's score and display the results screen
if the current question is not the last question...
 ...display the next question
here's the code:
function answer (choice) { // Display the
question and answer
in the Output window for debugging.
trace("Question " + currentQuestion + ". The
user answered: " + choice); // Record the
user's answer to this question. if
(currentQuestion == 1) { q1answer = choice; }
else if (currentQuestion == 2) {
q2answer = choice; } // If we're on the last
question... if
(currentQuestion == numQuestions) { // ...go
to the quiz end frame.
gotoAndStop("quizEnd"); // And grade the user.
gradeUser(); } else { //
...otherwise, go to the next question frame.
gotoAndStop("q"+ (currentQuestion +
1)); // Note that we're on the next question.
currentQuestion++; }
}

subcontracting labour
notice that the answer() function calls a separate function,
gradeUser()
the code in gradeUser() could have been contained within
answer()
but its wiser to do one-task-per-function
following the one-task-per-function rule makes code:
 easier to debug
 more reusable (each function can be independently)

new answer button handlers


here are the new event handler functions for the answer
buttons:
choice1_btn.onRelease = function ()
{ this._parent.answer(1);
}; choice2_btn.onRelease = function ()
{ this._parent.answer(2); };
choice3_btn.onRelease = function ()
{ this._parent.answer(3); };
code repetition is reduced
answer() function keeps track of the current question...
...hence, handlers for question 1 and question 2 answer
buttons can be the same!

grading the user


when the quiz is over, answer() calls gradeUser()
gradeUser() has two duties:
 calculate the user's score
 display the user's score on screen
once again, start the function with debugging information:
function gradeUser() { trace("Quiz complete.
Now grading...");
}

tallying the score


to store the user's score, we'll create a variable, totalCorrect:
function gradeUser() { trace("Quiz complete.
Now grading...");
var totalCorrect = 0; }
a variable defined within a function is called a local variable
local variables are deleted automatically when a function
ends

calculate the score with a loop


we'll use a loop to calculate the user's score
the loop runs once for every question in the quiz:
for (var i = 1; i <= numQuestions; i++) { }
the loop body checks each answer to see if it is correct
for (var i = 1; i <= numQuestions; i++) { if
(eval("q" + i + "answer") ==
eval("correctAnswer" + i)) {
totalCorrect++; } }
the built-in eval() function returns the value of the specified
variable
the first time the loop runs, i is 1...
...so the loop body reads:
if (eval("q" + 1 + "answer") ==
eval("correctAnswer" + 1)) { totalCorrect++; }
which is equivalent to:
if (q1answer == correctAnswer1)
{ totalCorrect++; }
the second time the loop runs, i is 2...
...so the loop body reads:
if (eval("q" + 2 + "answer") ==
eval("correctAnswer" + 2)) { totalCorrect++; }
which is equivalent to:
if (q2answer == correctAnswer2)
{ totalCorrect++; }
when the loop is finished, the final score is ready for display

displaying the score


the score-display code from quiz v1 has moved to gradeUser():
this.createTextField("totalOutput_txt", 1,
150, 200, 200, 20);
totalOutput_txt.text = "Your final score is: "
+ totalCorrect + "/" +
numQuestions;
add a little formatting to the text:
var format = new TextFormat(); format.size =
16; format.color
= 0xC7FF9C; format.font = "_sans"; format.bold
= true;
totalOutput_txt.setTextFormat(format);

quiz v2, final code


here's all the code for version 2 of the quiz:
// * INITIALIZATION * // Stop the
movie at the first question. stop(); // Init
quiz variables var numQuestions =
2; // Number of questions in the quiz var
q1answer; // User's answer for
question 1 var q2answer; // User's answer for
question 2 var correctAnswer1 = 3;
// The correct choice for question 1 var
correctAnswer2 = 2; // The correct
choice for question 2 var currentQuestion = 1;
// The question being answered.
// * FUNCTIONS * // Function: answer() //
Desc:
Registers the user's answers to quiz questions
and // advances the quiz through
its questions. function answer (choice) { //
Display the question and answer in
the Output window for debugging.
trace("Question " + currentQuestion + ". The
user answered: " + choice); // Record the
user's answer to this question. if
(currentQuestion == 1) { q1answer = choice; }
else if (currentQuestion == 2) {
q2answer = choice; } // If we're on the last
question... if (currentQuestion ==
numQuestions) { // ...go to the quiz end
frame. gotoAndStop("quizEnd"); // And
grade the user. gradeUser(); } else { // Note
that we're on the next question.
currentQuestion++; // ...otherwise, go to the
next question frame.
gotoAndStop("q"+ (currentQuestion +
1)); } } // Function: gradeUser() // Desc:
Tallys the user's score at the end of the
quiz. function gradeUser() { // Report
that we're about to grade the quiz in the
Output window. trace("Quiz complete.
Now grading..."); // Create a local variable
to track the // number of questions
user answered correctly. var totalCorrect = 0;
// Count how many questions the
user answered correctly. // For each
question... for (var i = 1; i <=
numQuestions; i++) { // If the user's answer
matches the correct answer.
if(eval("q" + i + "answer") ==
eval("correctAnswer" + i)) { // Give the user
a
point. totalCorrect++; } // Display the
correct answer and the user's answer //
in the Output window for debugging.
trace("Question " + i + ". Correct answer: "
+ eval("correctAnswer" + i) + ". User's
answer: " + eval("q" + i + "answer")); }
// Display the final score in the Output
window for debugging. trace("User's
score: " + totalCorrect + "/" + numQuestions);
// Create an onscreen text field
do display the user's score.
this.createTextField("totalOutput_txt", 1,
150,
200, 200, 20); // Show the user's score in an
onscreen text field.
totalOutput_txt.text = "Your final score is: "
+ totalCorrect + "/"
+numQuestions; // Customize the font face,
size, and color for the text field.
var formatObj = new TextFormat();
formatObj.size = 16; formatObj.color =
0xC7FF9C; formatObj.font = "_sans";
formatObj.bold = true;
totalOutput_txt.setTextFormat(formatObj); } //
* EVENT
HANDLERS * // Code executed when button 1 is
pressed.
choice1_btn.onRelease = function () { // Call
answer(), which records the user's
choice // and advances the quiz to the next
question. this._parent.answer(1); };
// Code executed when button 2 is pressed.
choice2_btn.onRelease = function () {
this._parent.answer(2); }; // Code executed
when button 3 is pressed.
choice3_btn.onRelease = function ()
{ this._parent.answer(3); };
improving the data structure
quiz code is now quite clean
but the data handling is awkward
each user choice and each correct answer require a variable
answer() function code increases with each question
consider the code required to record answers in a 10-
question quiz:
// Record the user's answer to this question.
if
(currentQuestion == 1) { q1answer = choice; }
else if (currentQuestion == 2) {
q2answer = choice; } else if (currentQuestion
== 3) { q3answer = choice; } else
if (currentQuestion == 4) { q4answer = choice;
} else if (currentQuestion == 5)
{ q5answer = choice; } else if
(currentQuestion == 6) { q6answer = choice; }
else if (currentQuestion == 7) { q7answer =
choice; } else if (currentQuestion
== 8) { q8answer = choice; } else if
(currentQuestion == 9) { q9answer = choice;
} else if (currentQuestion == 10) { q10answer
= choice; }
now imagine a 100-question quiz!
problems with the code:
 time consuming to create
 error prone

working with lists of information


the data in the quiz can be treated as lists of information:
 the list of user answers
 the list of correct answers
to handle these lists more efficiently use arrays
the anatomy of an array
an array is a list of data values
this code assigns string values to two variables:
fruit1 = "oranges"; // A single string value
fruit2 =
"apples"; // Another string value
this code creates an array to store both values:
var fruitList = ["oranges", "apples"];
two ways to create an array:
 array literal
["item1", "item2"]
 array constructor:
new Array("item1", "item2")
in ActionScript, arrays can contain any kind of data
here's an array with both strings and numbers:
shoppingList = ["oranges", 5, "apples", 2];

array elements
each item stored in an array is called an element
each element's position in the array is its index
indices start at 0
for example, here are the indices for shoppingList:
0: "oranges" 1: 5 2: "apples" 3: 2
the number of elements in an array is called its length
for example, the shoppingList's length is 4

retrieving an element's value


to get an element's value, use this syntax:
theArray[theElementIndex]
for example:
var numberOfOranges = shoppingList[1];
or use variables instead of numbers to specify the element
index
for example:
var index = 3; // Set numApples to 2 var
numberOfApples =
shoppingList[index];
the element index can also be calculated:
// Set numberOfApples to 2 var numberOfApples
= shoppingList[5
- 2];

setting an element's value


to set an element's value, use this syntax:
theArray[theElementIndex] = theValue;
for example:
// Make an array var cities = ["Toronto",
"Montreal",
"Vancouver", "Tokyo"]; // cities is now:
["Toronto", "Montreal", "Vancouver",
"Tokyo"] // Set the value of the array's first
element // cities becomes
["London", "Montreal", "Vancouver", "Tokyo"]
cities[0] = "London"; // Set the
value of the array's fourth element // cities
becomes ["London", "Montreal",
"Vancouver", "Hamburg"] cities[3] = "Hamburg";
or:
var i = 1; // Set the value of element i //
cities becomes
["London", "Prague", "Vancouver", "Hamburg"]
cities[i] = "Prague";
looping through an array's
elements
use a loop to systematically process the contents of an array
this code reports the location of the element with the value
"hip hop":
// Create an array var soundtracks =
["electronic", "hip hop",
"pop", "alternative", "classical"]; // Check
each element to see if it contains
"hip hop" for (var i = 0; i <
soundtracks.length; i++) { trace("now
examining
element: " + i); if (soundtracks[i] == "hip
hop") { trace("the location of 'hip
hop' is index: " + i); break; } }

array methods
an array is an object with methods to manage its elements
the push() method adds one or more elements to the end of
an array
for example:
// Create an array with 2 elements var
menuItems = ["home",
"quit"]; // Add an element // menuItems
becomes ["home", "quit", "products"]
menuItems.push("products"); // Add two more
elements // menuItems becomes
["home", "quit", "products", "services",
"contact"] menuItems.push("services",
"contact");
the pop() method removes the last element of an array
for example:
var numbers = [56, 57, 58]; numbers.pop(); //
numbers is now
56, 57 trace(numbers)
the unshift() method adds one or more elements to the
beginning of the array
for example:
// Create an empty array (notice the use of
the Array
constructor) var flashVersions = new
Array(); // Add an element flashVersions[0]
= 5; // Add another element, bumping the
previous 0 element up
flashVersions.unshift(4); // flashVersions is
now [4, 5] // Add two elements at
once flashVersions.unshift(2,3); //
flashVersions is now [2, 3, 4, 5]
the shift() method removes an element from the beginning of
an array
for example:
var sports = ["hackey sack", "snowboarding",
"inline
skating"]; sports.shift(); // Now
["snowboarding", "inline skating"]
sports.shift(); // Now ["inline skating"]
other methods perform various array manipulations:
 sort and reverse reorder the elements in an array
 splice() removes or adds elements from any part of an array
 slice() and concat() create new arrays based on existing arrays
 toString() and join() convert arrays to strings

a little more fun


time for some more visual experiments
 a random pattern generator (see randomPattern-01.swf through randomPattern-03.swf
in /examples/visuals folder)
 a mouse follower (see moveTowards.swf in /examples/visuals folder)
using arrays in quiz v3
update the quiz to track answers with arrays
we'll make changes to initialization code and functions
but answer button event handler code will not change

quiz v3, initialization


except for line 1, initialization code has completely changed
line 1, stop the movie at question 1:
stop()
next, q1answer and q2answer are replaced by userAnswers array:
var userAnswers = new Array();
likewise, correctAnswer1 and correctAnswer2 are replaced by
correctAnswers array:
var correctAnswers = [3, 2];
using correctAnswers, we can calculate the number of questions
in the quiz:
var numQuestions = correctAnswers.length;
if the number of questions in correctAnswers changes, numQuestions
updates automatically!

quiz v3, answer() function


quiz v3's answer() has the same duties as v2's answer():
 record the user's choice
 advance the quiz to either: a) the next question, b) the end results screen
so the function skeleton is the same:
function answer (choice) { }

quiz v3, recording the user's


choice
this time, the choice is stored in userAnswers instead of q1answer:
userAnswers.push(choice);
quiz v3, asserting that the code
works
once again, we assert that the code works
but this time, currentQuestion is based on the number of
questions answered so far:
var currentQuestion = userAnswers.length;
and the user's answer is the last element in the userAnswers
array
the index of the last element in an array is always one less
than the array's length:
theArray[theArray.length - 1]
so here's our new debugging code:
trace("Question " + currentQuestion + ". The
user answered: "
+ userAnswers[userAnswers.length - 1]);

quiz v3, advancing the quiz


quiz advancing in v3 is like v2 with one exception...
...the currentQuestion is not incremented
the userAnswers array length indicates the current question
automatically
// If we're on the last question... if
(currentQuestion ==
numQuestions) { // ...go to the quiz end
frame. gotoAndStop("quizEnd"); // And
grade the user. gradeUser(); } else { //
...otherwise, go to the next question
frame. this.gotoAndStop("q"+ (currentQuestion
+ 1)); }

quiz v3, gradeUser()


v3's gradeUser() has the same duties as v2's gradeUser():
 calculate user's score
 display score on screen
display code has not changed
only score calculation code has changed
old code:
for (var i = 1; i <= numQuestions; i++) { if
(eval("q" + i
+ "answer") == eval("correctAnswer" + i))
{ totalCorrect++; } }
new code:
for (var i=0; i < numQuestions; i++)
{ if(userAnswers[i] ==
correctAnswers[i]) { totalCorrect++; } }
note that new loop starts at 0 because array indices start at
0

quiz v3, final code


here's the final code for quiz v3:
// Stop the movie at the first question.
stop(); //
=================== // INIT QUIZ VARIABLES //
=================== // Create an
array to contain user's answers. var
userAnswers = new Array(); // Create an
array to contain each question's correct
answer. var correctAnswers = [3, 2]; //
Create a convenience variable to store the
number of // questions in the quiz.
var numQuestions = correctAnswers.length; //
===================== // CREATE
QUIZ FUNCTIONS // ===================== //
Function: answer() // Desc: Registers
the user's answers to quiz questions and //
advances the quiz through its
questions. // Params: choice The user's answer
for the current question.
function answer (choice) { // Add the current
answer to the list of user
answers. userAnswers.push(choice); // Create a
convenient variable to store the
number // of the current question. var
currentQuestion = userAnswers.length; //
Display the question and answer in the Output
window for debugging.
trace("Question " + currentQuestion + ". The
user answered: " +
userAnswers[userAnswers.length-1]); // If
we're on the last question... if
(currentQuestion == numQuestions) { // ...go
to the quiz end frame.
gotoAndStop("quizEnd"); // And grade the user.
gradeUser(); } else { //
...otherwise, go to the next question frame.
this.gotoAndStop("q"+
(currentQuestion + 1)); } } // Function:
gradeUser() // Desc: Tallys the user's
score at the end of the quiz. function
gradeUser() { // Report that we're about
to grade the quiz in the Output window.
trace("Quiz complete. Now grading...");
// Create a local variable to track the //
number of questions user answered
correctly. var totalCorrect = 0; // Count how
many questions the user answered
correctly. // For each question... for (var
i=0; i < numQuestions; i++) { //
If the user's answer matches the correct
answer. if(userAnswers[i] ==
correctAnswers[i]) { // Give the user a point.
totalCorrect++; } // Display the
correct answer and the user's answer // in the
Output window for debugging.
trace("Question " + (i + 1) + ". Correct
answer: " + correctAnswers[i] + ".
User's answer: " + userAnswers[i]); } //
Display the final score in the Output
window for debugging. trace("User's score: " +
totalCorrect + "/" +
numQuestions); // Create an onscreen text
field do display the user's score.
this.createTextField("totalOutput_txt", 1,
150, 200, 200, 20); // Show the
user's score in an onscreen text field.
totalOutput_txt.text = "Your final score
is: " + totalCorrect + "/" + numQuestions; //
Customize the font face, size, and
color of the text field. var format = new
TextFormat(); format.size = 16;
format.color = 0xC7FF9C; format.font =
"_sans"; format.bold = true;
totalOutput_txt.setTextFormat(format); } //
================================= //
DEFINE QUIZ BUTTON EVENT HANDLERS //
================================= // Code
executed when button 1 is pressed.
choice1_btn.onRelease = function () { // Call
answer(), which records the user's choice //
and advances the quiz to the next
question. this._parent.answer(1); }; // Code
executed when button 2 is pressed.
choice2_btn.onRelease = function ()
{ this._parent.answer(2); }; // Code
executed when button 3 is pressed.
choice3_btn.onRelease = function () {
this._parent.answer(3); };

building blocks
for our last bit of fun, we'll combine our earlier mouse
follower and random pattern experiments
remember that complex programs are just like lots of little
simple programs combined
see moveAway-01.swf through moveAway-07.swf in /examples/visuals

summary
code is fun, even when you only know a little!
you can learn a lot quite quickly
best way to improve: play and experiment