Week 12: Odds and Ends

Today we are going to cover a few useful things that didn’t fit anywhere else:

  • Uploading an image file into your swf
  • Dynamically setting masks
  • Printing from the swf
  • Setting the swf to display fullscreen

Week 12 examples


Here’s a simple script that allows you to upload an image through a class called FileReference. Because a bitmap image is actually stored on your computer as array of color values, it also uses a class called ByteArray to store the image data before it is loaded. This functionality only works with Flash Player 10 and only if you view the swf as embedded in an html file through a Web browser, locally or on a Web server.

File Upload Example

This example will display an image file from the user’s file system, but in order to save it to the Web server, you would need help from a server-side script (php, Cold Fusion …). The ActionScript was adapted from the tutorial here


Dynamic Masks

Setting a mask with ActionScript is very simple. You can set any Display Object in the Display List as the mask property of any other Display Object:

maskeeObject.mask = maskerObject;

Printing

To print from a .swf, you use the PrintJob object. PrintJob is a class of the flash.printing package. First, you create a new PrintJob object:

var myPrintJob = new PrintJob();

Next, begin the print job using the start method:

myPrintJob.start();

Then add a new page to the print job using the addpage method. This takes a number of arguments, some required, some optional:

myPrintJob.addpage(sprite:Sprite, printArea:Rectangle = null, options:PrintJobOptions = null, frameNum:int = 0);
  • sprite: The instance name of the Sprite object to print. (required)
  • printArea: The print area is passed as the name of a Rectangle object which must be defined earlier in the code. If you omit this, the entire area of the sprite will be printed.
  • options: You can use this to specify whether to print the page as a bitmap, as a Boolean value: {printAsBitmap:true}. If you do not specify this, the default is false. Printing as a bitmap will result in lower quality, but you must do this if your target has alpha values or color effects applied to it.
  • frameNum: This specifies a frame of the sprite to print. If omitted, it prints the current frame.

Next, you send the print job to the printer using the send method:

myPrintJob.send();

There are a number of other properties you can set for a print job, such as orientation and page attributes, detailed here:

PrintJob on Adobe LiveDocs

If you want your user to be able save a jpeg out of your swf rather that print, there is a tutorial here:

Saving Images from Flash

You’ll need to import some additional AS3 libraries to get this working.

AS3 Core Lib


Fullscreen Display

You can present a swf as a fullscreen application using the fscommand function of the flash.system package. fscommand takes two arguments: command and args.

Entering fullscreen mode:

fscommand("fullscreen","true");

Exit the fullscreen mode:

fscommand("fullscreen","true");

Prevents swf content from being scaled:

fscommand("allowscale","false");

Note: fscommand only working in the standalone Flash Player, or in a projector. It will not work in a Web browser or the test player in the Flash IDE.

Additional options for fscommand can be found here:

fscommand on Adobe LiveDocs


Homework

Final project presentations are in two weeks. Presentation of your project is mandatory. Each student will have 10 minutes to present and get comments.

Next week will be an in class work session. Your code should be at a point where you have identified issues that you can work through with me in class.

26
Apr
2010

Week 11: Audio/Video

Week 11 Example files

New Classes used in the examples:

And two useful sections in the Adobe help docs

19
Apr
2010

Week 10: Wireframe Presentations, Flow and Class Diagrams

Final Project: Flow Diagram and Class Diagram

You are going to produce two more documents for the planning phase of your final project, a flow diagram and a class diagram.

A flow diagram is a conceptual map of the process your application goes through when it executes. We aren’t at this point trying to figure out exactly how we are going to code the application, but the general steps that it needs to go through to accomplish your goal.

Process Flow Diagram

A class diagram details all the classes / objects of your application, including the properties and methods of each class.

Class Diagrams Explained


Homework

1. Create a flow diagram and class diagram for your final project and post them to your homework page. Start working on your interfaces, due in two weeks.

12
Apr
2010

Week 9: XML and ActionScript

Week 9 Examples

Livedocs > XMLList Class

What is XML?

XML stands for eXtensible Markup Language. An XML document is a text file that contains data formatted in a particular way. XML has a node based structure that is divided into parent node and child nodes. These nodes are designated by tags in much the same way that HTML is, the difference is that you can make up these tags to suit the needs of your particular application.

So, for example, if I wanted to create an XML document about a series of photos that held values for the image filename and an associated caption, I might lay it out like this:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<images>
  <photo>
   <image>images/1.jpg</image>
   <caption>Saharan on Sunset</caption>
  </photo>
  <photo>
   <image>images/2.jpg</image>
   <caption>Sedona Skyline</caption>
  </photo>
  <photo>
   <image>images/3.jpg</image>
   <caption>Cape Cod Beach Fence</caption>
  </photo>
</images>

What XML is useful for is to store data in a structured way to be used in another application.  It is also a way for us to abstract the content of our application from the presentation of it. You are probably already looking at all sorts of data that is stored in XML documents without knowing it. For example, RSS feeds are just an XML document with a special format, as are Podcast subscriptions.

All XML is made up of the following parts:

  1. XML version – tells the parser that this is an xml document, and what version and character encoding it is
  2. Root Node – This is the node that is the first and last tag in the document. It is the <images></image> part of the example above
  3. XML Elements – This is a unit of XML data, which must have balanced opening and closing tags. The <photo></photo> parts of the example above are elements.
  4. Attributes – My example doesn’t use these, but they are essentially values that are stored within the opening element tag: <photo id=”1″ size=”400×300″>
  5. Text Nodes – The content between the element tags. In the first image element above, the text node would be “image/1.jpg”

Note: In some cases you might want to pass HTML character data in your text node, but the presence of characters like < and > can cause problems because it looks like you are closing the element, or opening a new one. In this case you would want to wrap that content in a CDATA tag:

<caption><![CDATA[<b>Saharan on Sunset</b>]]></caption>

What this does is tell the parsing application to read this as literal character data.


Accessing an XML document with ActionScript

ActionScript has several built-in classes to allow you to access a properly formatted XML document. This is called “parsing” the XML, which involves reading in the data contain in the XML and turning it into a form that is useful to us within the application.

This works similarly to the Loader examples we looked at last week, in that we still use the URLRequest object to designate the external XML file you want to parse.

var galleryXML_URL:String = "gallery.xml";
var galleryXML_URLRequest:URLRequest = new URLRequest(galleryXML_URL);

However, instead loading that URLRequest to the the Loader class, this time we use the URLLoader class. The main difference here is that URLLoader class is part of the flash.net package, while the Loader class is a Display object. However, the two loader classes are similar in that they have many of the same events contained within them.

var galleryLoader:URLLoader = new URLLoader(galleryXML_URLRequest);

In order to use the data loaded into the URLLoader as XML, we need to put it into an XML object. There is a base XML class for this purpose, but we are going to use the XMLList class in our example instead, because it provides better methods for parsing the file. The difference between these two classes is that an XMLList can have more than one root node (not really applicable in this example). So, we create a new XMLList to hold the XML data.

var galleryXML:XMLList = new XMLList();

We can the populate the XMLList using the data property of the URLLoader, which is where it keeps the loaded content.

galleryXML = XMLList(galleryLoader.data);

But wait! You’ll find if you do it this way, you’ll get an error. This is because the data attribute of the URLLoader is not accessible until the document is fully loaded. So before you do anything with it, you need to wait for the “complete” event.

galleryLoader.addEventListener("complete", getNodes);

The event handler should then contain the code that assigns the URLLoader data to the XMLList object.

Once you have the data loaded into the XMLList Object, you can access all the elements within it.  You do this in much the same way that you access the elements in an array, but you also use object dot notation. For example, if I wanted to access the file name of the first image, I would use this code:

 galleryXML.photo[0].image;

There is a lot more info on this subject, including other ways to access nodes and elements, in Chapter 11 of the Foundation ActionScript 3.0 book.


Editing and Saving External XML Files

Last week we learned how to read an XML document into our Flash movie, this week we are going to learn how to write new values back to the XML document.

Because Flash and ActionScript work on the client side, we can’t write data back to a file on the server directly with ActionScript. We need a little help from a server-side scripting language. The example I am going to show you uses PHP, a popular open source language to do this.

Because PHP works on the server side, this example won’t work on your desktop, you will need to upload it to a server (like the A server) that has PHP installed. If you want to know more about the php function that makes this possible, you can read about it here


Homework

We’re going to start working on the Final Project in earnest now. Here are the parameter’s for the project:

  • Your project can be a game, a generative art piece, a teaching tool, a game. Really, it can be anything you wish to pursue. The one caveat to this is if you want to make and all-Flash Web site, you will need to justify why this site should be Flash instead of HTML/CSS/JavaScript
  • The project must be unique, not just simply duplicating a game or something that is already out there
  • The project should incorporate much of what you have learned in this class. I’m not looking for a certain number of lines of code, but instead a comprehensive and applied knowledge of ActionScript 3.0
  • You MUST use external classes. I won’t accept any project using timeline code.

Here’s the schedule:

  • Week 10 (4/12): Wireframes/Storyboards Due, present in class
  • Week 11 (4/19): Decision Tree / Class Diagram / Task Analysis  (I’ll explain what these are later)
  • Week 12 (4/26): Graphical Interface elements complete
  • Week 13 (5/3): 1/2 code written, Class work session
  • Week 14 (5/10): Final Project Presentations
  • Week 15 (5/17): Final Project Presentations, Final Project Files Due

For next week, I want you to create wireframes, storyboards, or a paper prototype for your project interface as a previsualization of how the project is going to function. Exactly how you do this is up to you, but I want to see how the user input will work and what output it will produce. You should not be thinking about final design at this point, but creating a blueprint for your project.

Here is a simple wireframe example for the XML editor we explored today:

05
Apr
2010

Week 8: Loading External Assets

Topics:

  • Another Hit Test Example
  • Loading External Assets
  • Preloaders
  • Loading Web Pages

Week 8 example files


Loading External Assets

ActionScript has the built-in ability to load external files via the Loader object, which, like MovieClip and Sprite is a subclass of the DisplayObjectContainer class. The Loader has a few special methods and properties that are tied to the loading and manipulating of an external file. You may load image files (jpg, png, or gif) and also other swf files, including swf files created with older versions of flash, with ActionScript 1.0 and 2.0.

The Loader works in conjunction with another class: URLRequest. This is a part of the flash.net package. When you create a new URLRequest you designate the path/filename of the asset to be loaded. This can either be an absolute path (http://www.mywebsite.com/image/myimage.jpg) or relative to the .swf file that will load the asset (image/myimage.jpg).

Once you have created instances of the Loader and URLRequest you can then use the load method of the Loader class to load the asset into the loader, something like this:

myLoader:Loader = new Loader();
myRequest:URLRequest = new URLRequest("images/myImage.jpg");
myLoader.load(myRequest);

A Loader instance can only hold one URLRequest at a time. If you load a new request into it, it will replace the existing request. However, you can have multiple Loader instances in a single movie.


Preloaders

Now that you are loading external files into your movie, you run a greater risk of the contents to take a long time to download to the user’s machine. Rather that make your user look at a blank screen during download, you should give them some indication of the progress of the loading.

To do this for a Loader object, you will take advantage of the contentLoaderInfo property of the loader class, and an event dispatcher object called LoaderInfo. This allows you to track events tied to the content of the Loader – when loading begins, the progress of loading, and when loading ends, among others.

Preloader Example


Loading Web Pages from your Flash Movie

If you want to load a normal Web page into a browser window from your  swf, you can use the navigateToURL function of the flash.net package.


Homework

1. Using externally loaded image files, create an Image Gallery that mimics the functionality of this example

EXTRA CREDIT:

  • Add a preloader to the gallery
  • Customize the appearance of the Button Components
29
Mar
2010

Week 7: More Events, UI Components, Tweens and Transitions

  • Drag and drop events
  • UI Components
  • Transitions
  • Tweens

Week 7 Example Files


Creating Drag and Drop Elements

The Sprite class has built into it several methods for allowing user input to grab an object on the stage and drag it to another location. These methods are called startDrag and stopDrag, can be used with any Sprite or MovieClip, and are generally triggered by mouse events. These methods are tied to a specific display object and triggered within an event handler.

The startDrag is called when the initial user event is dispatched, and causes the target object to be draggable. This method takes two optional arguments:

  • lockcenter – this is a Boolean that determines whether the Sprite is locked to the center of the mouse position (true) or to where the user first clicked on it (false). The default value is false.
  • bounds – specifies a boundary rectangle for the Sprite. The default value is null.

The stopDrag method is called when the terminal user event is dispatched, and causes the target object to cease being draggable. This method takes no arguments.

There is a property of the Sprite object that is related to these functions, called the dropTarget. This specifies the object which the sprite was dragged and released onto.


Using UI Components

UI components are MovieClips that have additional characteristics called parameters to help you control their appearance and behavior. Some of them, like the Button, are not that different than a button you would create yourself, while others, like the Radio Button or Color Picker, have complex functionality that would be laborious to recreate.

The key to using components is that the component and the component assets must be present in your .fla library at run time. This is true even if you are going to create and manipulate the components purely with You can do this either by dragging a component from the Components panel to the stage or directly into your library.

You will notice once you have added a component to the stage or library that your library now contains a folder called “Component Assets”. Inside are all the elements that combine to create a component. These elements can be altered in appearance to customize the look of your components in a movie.

We are going to look at three components today:

You can create new instances of components and add them to the stage with the same methods as the other display objects you’ve been working with, but components have the added advantage of extra properties, methods and in some cases events that give you a head start in your interface programming. Some of these extras are shared by all UI components, while others are specific to a component.

You can also customize the appearance of UI Components.

More information about using components is also detailed in Chapter 9 of Foundation ActionScript 3.0 with Flash CS3 and Flex.


Transitions

There are a number of transitions designed to bring content on or off the stage in the fl.transitions package. The Transition Manager class allows you to access these transitions:

Transition Manager Reference


Tweens

The Tween class allows you to animate the same properties you could using a Motion Tween on the timeline:

Tween Help Files


Embedding Fonts

In order to use a font that is not installed on a users computer it must be “embedded” in your swf. There are several ways to do this.

  • Create a text field on the stage and embed the font using the properties panel
  • Create a font symbol in the library and export for actionscript

Here’s a good tutorial on doing the latter:

Embedding fonts


Homework

  1. Using a drag event, create a matching game where the user has to match the object they are dragging to another object on the stage.
  2. Create a photo slideshow using a tween or transition. Use components to control the slideshow. Extra credit: Try one of the components we didn’t go over today!
22
Mar
2010

Week 6: Midterm Presentations, More Events

Homework

Due the Week After Spring Break (3/22)

Using what we learned last week about animating with actionscript:

1. Create an animation, using only code, with at least 10 objects. The objects should react when they hit each other. Be creative about what happens when objects collide!

08
Mar
2010

Week 5: Events

Topics

  • Part 1:
    • TextFields and AS
    • Events
    • Event Dispatchers
    • Event Listeners
    • Mouse Events
  • Part 2:
    • Animating With ActionScript
    • Drag and Drop!
    • Hit Testing

Some of the examples from today’s class came from another terrific Friends of Ed book, that you can also get from the 24/7 library – Foundation Actionscript 3.0 Animation: Making Things Move!

This book gets into much more detail about animating with ActionScript, so if your interests lie there, check it out!

Week 5 Examples Part 1

Week 5 Examples – Part 2


Text Fields and ActionScript

Today we are going to use some TextFields as well as the other display objects that we’ve already been playing with. They work much the same way, but you might want to check this out for the particulars:

Livedocs > TextField


Events

So far all of the code we have written has executed all at once, with no passage of time. It also has not allowed for any user interaction. In order for us to add temporality or interactivity to our ActionScript, we must take advantage of Events.

All events are instances of the Event class, with properties and methods like all classes. The Event model in ActionScript 3.0 has three objects associated with it:

  1. Events
  2. Event Dispatchers
  3. Event Listeners

The key to utilizing events is to set up an event listener. This is an object that keeps watch for a certain event to happen. When you set up a listener, you provide it with two things, the type of event you are listening for and the method that you want called when that event occurs. This is the syntax for an event listener:

yourObject.addEventListener(event_type, listener_method);

The event type includes Mouse and Keyboard inputs, frame events, and the loading of external data, among others.

The listener method is the method you want to call when the event happens. It is also sometimes referred to as the “event handler” This method takes a single parameter, specifying the type of event being listened for. Generally these will either be “Event” or “MouseEvent”. The return type for listener methods is always “void”. The method will look something like this:

private function methodName(event:EventClass):void {

// this code will execute when the event is dispatched

}

Working with Mouse Events

These are the AS 3.0 Mouse Events that you can set up a listener for:

  • CLICK
  • DOUBLE_CLICK
  • MOUSE_DOWN
  • MOUSE_MOVE
  • MOUSE_OUT
  • MOUSE_OVER
  • MOUSE_UP
  • MOUSE_WHEEL
  • ROLL_OUT
  • ROLL_OVER

Today we are going to take a look at three examples that use the mouse events:

  • Creating a custom cursor
  • Making a simple adding machine
  • Making a mouse drawing application (from the Book)

There are also Keyboard Events that you can set up listeners and handlers for. I’m not going to get into that, but if you are interested, check it out here:

Livedocs > Keyboard Events


Animating with ActionScript

Now that we are comfortable with working with and creating display objects, and using event listeners and event handlers, we can also create animation entirely from code, without involving the timeline. To do this, we use a new event type, onEnterFrame, or ENTER_FRAME event.

You might think that you could use a for loop for animation, like this:

for(i = 0; i < 500; i++){
    ball.x = i;
}

Where “ball” is a display object that you have defined elsewhere. You might think that this code would move the ball 1 pixel 500 times, and in a sense you would be right. The problem is that you would only see the result of the last loop, because all 500 loops are executed before the frame is rendered. To get around this, you need to introduce time between loops, which is where ENTER_FRAME comes in. The ENTER_FRAME event is dispatched at the frame rate of the .swf. Here’s a simple example of how you would use ENTER_FRAME to move a sprite across the stage by 1 pixel in the X axis every frame:

package {
    import flash.display.Sprite;
    import flash.events.Event;

    public class FirstAnimation extends Sprite {
        private var ball:Sprite;

        public function FirstAnimation() {
            init();
        }

        private function init():void {
            ball = new Sprite();
            addChild(ball);
            ball.graphics.beginFill(0xff0000);
            ball.graphics.drawCircle(0, 0, 40);
            ball.graphics.endFill();
            ball.x = 20;
            ball.y = stage.stageHeight / 2;
            ball.addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }

        private function onEnterFrame(event:Event):void {
            ball.x++;
        }

    }

Creating Drag and Drop Elements

The Sprite class has built into it several methods for allowing user input to grab an object on the stage and drag it to another location. These methods are called startDrag and stopDrag, can be used with any Sprite or MovieClip, and are generally triggered by mouse events. These methods are tied to a specific display object and triggered within an event handler.

The startDrag is called when the initial user event is dispatched, and causes the target object to be draggable. This method takes two optional arguments:

  • lockcenter – this is a Boolean that determines whether the Sprite is locked to the center of the mouse position (true) or to where the user first clicked on it (false). The default value is false.
  • bounds – specifies a boundary rectangle for the Sprite. The default value is null.

The stopDrag method is called when the terminal user event is dispatched, and causes the target object to cease being draggable. This method takes no arguments.

There is a property of the Sprite object that is related to these functions, called the dropTarget. This specifies the object which the sprite was dragged and released onto.


Hit Testing

It can be useful when creating dynamic code based animation to be able to detect when one display object collides with another. This is called “Hit Testing” and there are two DisplayObject methods for dealing with this.

  • hitTestObject takes a single argument, which is the name of the display object you want to test against
  • hitTestPoint takes a three arguments:
    • x:Number – an x coordinate to test against the object
    • y:Number – a y coordinate to test against the object
    • shapeFlag:Boolean – true checks against the actual pixels of the object, false against the boundary box

Homework

Next Week

Be prepared to present your midterm projects next week.  Remember, you need to be able to explain the code line by line, and if you use anyone else’s code, credit it!

The Week After Spring Break (3/22)

Using what we learned this week about animating with actionscript:

1. Using a drag event, create a matching game where the user has to match the object they are dragging to another object on the stage.

2. Create an animation, using only code, with at least 10 objects. The objects should react when they hit each other. Be creative about what happens when objects collide!

01
Mar
2010

Week 4: Display Objects

The Display List

In order for us to actually work with objects on the stage, instead of just using the Output window, we need to understand the Display List. Anything that appears on the stage is part of the Display List. The Display List is a hierarchy of the visual objects in your Flash movie. All Display Objects are descended from the DisplayObject class in the flash.display package. The Display List of any Flash movie has a tree structure that is made up of nested Display Objects:

The Display ListThe Display List

The Stage is the base container. Each movie has a main class associated with it. When the .swf is run, the movie calls the constructor method of that class.

Display Object Core ClassesDisplay Object Core Classes

The above diagram details all of the objects in the Display package. Today we are going to go over a portion of them.

Display Object

This is the base object, all other Display Objects inherit the properties and methods from this class. It contains generic properties such as x/y coordinates, width and height. All other Display Objects extend this class, either directly or indirectly.

Interactive Object

This class adds methods, properties and events that allow you to add user interactivity to a Display object.

Display Object Container

This class adds the ability of a Display Object to hold other Display Objects.

The three classes above are abstract classes, which means that you can’t create instances of them, they are designed only to hold properties and methods that will be utilized by the child classes.

Sprite

This is a new type of Object in ActionScript 3.0, and there is no way to create a Sprite through the IDE, only via ActionScript. The Sprite is a stripped down version of the MovieClip, without any properties, methods, or events related to the timeline. Because of this reduced functionality, the Sprite is much lighter weight than the MovieClip.

MovieClip

The most important of the Display Objects, MovieClip adds frames, frame labels and scenes to the Sprite.


Creating, Adding and Manipulating Display Objects with ActionScript

With every flash movie you have created so far, you’ve been working with Display Objects via the IDE. Now we are going to look at what we can do with the Display Object classes purely with ActionScript code.

Manipulating Display Object Properties

You can manipulate the properties of any display object on the stage that has an instance name. These properties include:

  • x
  • y
  • width
  • height
  • scaleX
  • scaleY
  • rotation
  • alpha

Getting and Manipulating the Depth of Display Objects

Each display object is assigned a depth according to the order in which it was added to the stage, starting with zero and ascending. There are a number of methods for getting and setting object depths:

  • getChildIndex(objectname)
  • getChildAt(indexnumber)
  • setChildIndex(objectname, depth)
  • swapChildren(object1,object2)
  • swapChildrenAt(index1, index2)

Adding Objects to the Display List

There are two steps to adding a new Object to the stage. The Object can either be one of the built in classes (MovieClip, Sprite, TextField, etc) or an item from the library. First you must create the object instance using the new operator:

var myObject:ObjectClass = new ObjectClass();

This instantiates the object, but it does not yet appear on the stage. You must add it as a child of the stage in order for it to become part of the Display List:

parentObject.addChild(myObject);

You can also put a new child at a specific depth, although you can’t skip depths. If you put a child at a depth where one already exists, that one will be bumped up a level.

parentObject.addChildAt(myObject,depth);

The parent object can be any DisplayObjectContainer that is already in the Display List. Remember, this includes the stage!

Remove Objects from the Display List

This is a one step process:

parentObject.removeChild(myObject);
Or
parentObject.removeChildAt(myObject,depth);


The Drawing API

If we are using simple shapes, as in the examples so far, we can actually avoid creating library symbols completely and instead use ActionScript 3.0’s Drawing API to create vector graphics.

The Drawing API (Application Programming Instance) is part of the Graphics class. Any Sprite or Shape instance you create includes a graphics instance that you can draw within. There are a number of methods you use to draw and fill vector shapes. Generally, you want to start by creating a container to draw within.

> Live Docs > Graphics Class

Set up a project

A good strategy for using the drawing API is to set up two classes, a Shape based class to do the actual drawing, and a Sprite based class as a container.

Setting a Line Style

The graphics.lineStyle method takes three arguments – thickness, color, and alpha:

graphics.lineStyle(1);

Drawing Straight Lines

To draw a straight line from the last point that the “pen” landed, use lineTo, which takes two arguments, x and y coordinates.

graphics.lineTo(50,0);

Moving the Pen

To move the pen position without drawing a line, use moveTo, which also takes x,y coordinates.

graphics.moveTo (-50,50);

Drawing Curved Lines

A curved line requires four points of reference – controlx, controy, anchorx, anchory

graphics.curveTo(0,-50,0,0);

Primitive Shapes

There are built in methods for creating circles, ellipses, rectangles and rounded rectangles in ActionScript 3.0. They take various arguments depending on the shape:

  • drawCircle(x:Number, y:Number, radius:Number)
  • drawEllipse(x:Number, y:Number, width:Number, height:Number)
  • drawRect(x:Number, y:Number, width:Number, height:Number)
  • drawRoundRect(x:Number, y:Number, width:Number, height:Number, ellipseWidth:Number, ellipseHeight:Number)

Fills

To fill in lines or shapes created with the drawing API, you define a fill style with beginFill, which takes two arguements, color and alpha:

graphics.beginFill(0xFFFF00,1);

All shapes will be filled with this style until you invoke the endFill method:

graphics.endFill();

Homework

Due Next Week:

1. Using an external class, add multiple versions of a symbol from the library onto the stage, creating a regular grid of rows and columns of the symbol. Hint: use addChild in conjunction with a for loop!

Extra credit: Using ActionScript, apply filters and blending modes to your symbols (something that is in the reading, but we didn’t cover in class)

2. Using external classes and the Drawing API, draw the scene you see outside a window where you live OR draw a self-portrait.

Midterm Project -  Due in Two Weeks!

You are going to present the next homework as your midterm project. You don’t have all the tools you will need to do this (yet!), but I wanted to give you a heads up. This project should be one of the following:

  1. Take the “Guess a Number” exercise and create a user interface for it so that a user can play the game. Add in a way for the user to “Play Again” once they have guessed the right number.
  2. Make a drawing application that lets the user draw on the screen using the mouse. Create interface elements that let the user change the line thickness, line color, and fill color. Here’s some student examples from previous years:
  3. Pick a simple game, like Tic Tac Toe, or Hangman, and create a user interface and the ActionScript to back it up.

For all of these exercises, you should use external .as files rather than code on the timeline!

If you feel like you need a challenge and want some extra credit, do two or more of the above!

22
Feb
2010

Week 3: Objects and Classes

  • Everything is an Object
    • Method and Properties
    • Built in Classes: Looking at the MovieClip Class
  • Creating and Manipulating Objects
    • Creating Objects using the New Operator
    • Accessing Properties and Calling Methods
    • Copying Objects
    • Casting Objects to a Type
    • The Object object
    • Inheritance
  • Using External .as Files
  • Creating a Custom Class
    • Adding Properties to Your Class
    • Adding Methods to Your Class
    • The Constructor Method
    • Controlling Access to Properties and Methods
    • Getter / Setter Methods
    • Read-only Methods
    • Static Properties and Methods
    • Using Inheritance
  • Packages
    • Defining Packages
    • Importing Packages
  • The Display List
    • Using and Manipulating Display Objects
    • Display Object Depth
    • Creating and Removing Display Objects From the Stage

Week 3 Examples – CS3!


ActionScript and OOP: Everything is an Object

Absolutely everything that you use in ActionScript is an Object, and each of those Objects is defined by a Class. Classes are stored in external .as files. When you installed the Flash IDE on your computer, you also installed the entire library of built-in classes that are the foundation of the ActionScript language. Objects represent a specific instance of a Class. Another way to look at it is that a Class is a blueprint for an Object.

Classes in ActionScript are composed of three elements: Methods, Properties, and Events.

  • Properties are what Objects are
  • Methods are what Objects do
  • Events track when something happens that ActionScript can respond to

We’re not going to get into Events just yet.

Methods and properties have a relationship to programming concepts that we have already explored. You can think of Properties as Variables that belong exclusively to a class, and Methods as Functions that do the same.

Let’s look at the MovieClip class in the Help system to see how it is organized.

You’ll notice that the first thing that is listed about the MovieClip class is its Package.

Packages

A package is a way of organizing classes. A package is a collection of associated .as files, each of which contains a class. For example, the package that contains the MovieClip class is the flash.display package. This package contains all the core classes which describe objects that are displayed visually on the stage (including the stage itself!).

Inheritance

One of the most powerful aspects of OOP is the concept of inheritance. Classes can inherit properties and methods from other classes. This sets up parent/child relationships in a hierarchy of classes that allow a class to share, or inherit, properties and method from the parent classes, in much the same way that you inherit biological traits from your parents. A better analogy is actually your relation as a organism to the human race. You share with all humans the trait (or properties) of having two arms, two legs, hair on your head, etc. You can do the things that humans do (methods!) like walk upright on two legs, and talk in human verbal language. Beyond that, you are a member of the larger class of mammals, and share traits and behaviors with that class, like being warm-blooded, and breathing oxygen. In fact, the whole taxonomy of biological classification that you learned in high school (you know, Kingdom, Phylum, Class, Order ….) could be looked at as a series of Objects or Classes in a OOP system.

The MovieClip class inherits properties and methods from the SpriteDisplayObjectContainer, InteractiveObjectDisplayObjectEventDispatcher, and  Object Classes.

Subclasses

The MovieClip is a subclass of all the classes it inherits from, and it has a subclass of its own, LivePreviewParent. Subclasses inherit the properties and methods of their parents, but also have characteristic that are unique to themselves. A well-defined OOP system has very generic classes at the top of the hierarchy, and gets more specific as you go down the hierarchy.

Properties

The next thing about the MovieClip class that we see, after the description of it, are its Properties. These are the Properties that are specific to the MovieClip class, currentFrame, currentLabels, currentScene, etc. You’ll perhaps notice that these properties are related to the timeline. This is because MovieClip is a display object with a timeline, and this is the primary difference between it and its parent, the Sprite!

Methods

Next are the methods, and you will notice that they are also pretty much timeline-related: goToAndPlay, goToAndStop, nextFrame, etc.


Creating and Manipulating Objects

We already explored how to create a new Array last week using the new operator. This works for any type of ActionScript Object. For instance we can make a new String object and populate it like this:

var greeting:String = new String("Hi there!");

This technique of creating a new object can be used with built-in classes as well as those classes you will write yourself.


Accessing Properties and Calling Methods

Again, we touched on this last week when we worked with arrays, but it extends to all objects. We access properties and call methods using the dot (.) operator. Before the dot you specify the name of the variable in which the object is stored, and after the dot the name of the property or method you wish to access.

For a string, you can access the length property like this:

greeting.length

Or call the String method charAt() like this:

greeting.charAt(4);

A string is actually an array of characters, and the charAt method allows you to access a character at a specifc place in the array.

Copying Objects

In the reading, you learned that primitive objects (Numbers, Booleans, Strings) are “passed by value” where complex objects like arrays are “passed by reference”. Passing by reference means that instead of actually setting a variables value to the value of another variable as it stands at that moment, you are instead just pointing it to the place in memory where that value is stored. This means that if that value changes for one object that is pointing to that reference, it will change for all objects that are pointing to that reference. This is one of the more difficult concepts in programming to grasp, but for the moment, just understand that this means that you can’t make a pure copy of an complex Object the same way you can a simple datatype.

In the case of an Array object, we can make a copy of the array using Array’s built in slice() method.

var array1:Array = new Array("one","two","three");
var array2:Array = array1.slice();

Now array2 will be unaffected by any changes you make to array1 later in the code.

The Object object

Almost all objects in ActionScript are the children of, and inherit properties and methods of, the Object object. An Object is the simplest type of object you can make.

You can create a new Object, like all objects, with the new operator:

var myObject:Object = new Object();

These generic objects are  “dynamic” objects, which means that you can assign properties to them on the fly without generating errors:

myObject.name = "Simple Object";
myObject.ID = 12345;

Like an Array, you can create a new Object instance by using an object literal, and define properties within it:

var myObject:Object = {name:"SimpleObject", ID:12345 };

Using the Object object allows you to create very generic, dynamic objects on the fly, but I would caution against overusing this ability in your code. It is better to use the built-in classes and to create your own custom classes.

And how about that? How do we make classes of our own?


Using External .as Files

Placing ActionScript on the timeline of your .fla files works, but it is not the most efficient way to write your code. It means that you or other developers must hunt through the timeline to find and edit code, and that it must be compiled everytime a change is made. Also, the code can only be utilized by that one file, not shared across multiple projects.

The preferred way of storing ActionScript is with external .as files. These are ordinary text files that can either be created with the Flash IDE or with any text editor.

To create a new .as file from the Flash IDE, choose File > New > ActionScript File.

You can type code into this file just as you do into the Actions panel in the Timeline of a .fla file.

Including Code from External Files

There are a number of ways to include code from external files. One way is by using an include statement, like so:

include "Import.as";

This will cause the code in the .as file to be compiled with the contents of the .fla file just as if it was in the timeline. While effective, this is still not the best way to access your ActionScript, since the include statement still had to be placed on the timeline. Our ultimate goal is free ourselves from dependence on the timeline.

The Document Class

The document class is a concept that is new to ActionScript with CS3. The purpose of the document class is to specify which ActionScript should run when a Flash movie plays. We do this by associating a particular .as file with the main timeline. We’ll talk about what a class is in a minute.

To associate a particular .as file with a .fla file, in the .fla file open the Properties window. At the bottom right you will see a text field labeled “Document Class”. In this field, you enter the name (excluding the .as extension) of the .as file you wish to designate as the document class of this movie file. This is a file that must exist in the same directory as your .fla file.


Creating Your Own Classes

To create a new class, you are first going to create a new external .as file to hold the class. You can’t create a class directly in the timeline of your .fla.

The first thing that you must do in your class is define the package that your class is part of. This is required in ActionScript 3.0, but wasn’t in 2.0.

A package is defined with the package keyword, followed by curly braces. The class is defined within the curly braces:

package {
}

Next, within the package curly braces, you will give your class a name.

package {
public class FirstClass {
}
}

A few things to note here:

  1. You can only define one class per .as file
  2. The .as file must have the same exact name as the class being defined within it!
  3. Class names can contain only letters, digits, the underscore (_) and the dollar sign ($) characters
  4. Class names can not start with a number
  5. Class names must be unique
  6. Class names can not be a reserved word
  7. It is conventional to create class names with modified camel case notation: MyClass
  8. It is conventional to name classes using nouns

Now you can create a new Object instance based on your custom class from within your Flash file.

var myFirstClass:FirstClass = new FirstClass();

This isn’t very interesting, however, since our class has no properties or methods associated with it.

Adding Properties to Your Class

Without some properties, defining your own class is pretty pointless. So let’s look at the example from Foundation ActionScript 3.0 book:
package {

public class IPod {
public var name:String = "";
public var volumeLevel:uint = 10;
public var tracks:Array;
public var currentTrack:uint = 0;
public var shuffle:Boolean = false;
}
}

Now the IPod class has inherent properties that can hold values for each IPod instance:

var myIPod:IPod = new IPod ();
myIPod.name = "Steve's iPod";
myIPod.volumeLevel = 11;
myIPod.tracks = ["Miles Davis - Kind of Blue","Coldplay - Yellow","Gorrilaz - Dirty Harry"];
myIPod.shuffle = true;

Adding Methods to Your Class

Right now, our IPod object has some characteristics (properties) but can’t really do anything. To this end, we want to add some methods. Methods are defined as functions within the class:

package {

public class IPod {
public var name:String = "";
public var volumeLevel:uint = 10;
public var tracks:Array;
public var currentTrack:uint = 0;
public var shuffle:Boolean = false;

public function play():void {
trace("Playing: "+ tracks[currentTrack]);
}
}
}

Now we can call the play() method.
myIPod.play();

If you run this code you’ll see that it still doesn’t do that much, we always “play” the same track. But now, let’s create a new method for our IPod class, and invoke a method of the built-in Math class to make things a little more interesting, using the shuffle property we previously defined for our iPod.

public function next():void {
if (shuffle) {
currentTrack = Math.floor(Math.random()*tracks.length);
}
}

Now, if the current value of the shuffle property is true, the next function, when invoked, will randomly set the value of the current track. Note a couple of clever things about this construction – the Math.floor method is applied because the tracks array index starts with 0, and the random number generated by Math.random is multiplied by tracks.length to give the proper range of numbers.

Now if we invoke the next() method, then the play() method, we will get a random currentTrack value returned.

What if our shuffle properties is instead set to false? If we aren’t shuffling, then really what we want our iPod to do is play the next item in the tracks array. We should add logic in the next function to handle this case.

public function next():void {
if (shuffle) {
currentTrack = Math.floor(Math.random()*tracks.length);
} else {
if (currentTrack == tracks.length -1) {
currentTrack = 0;
} else {
currentTrack++
}
}

This will play the next track in the tracks array, unless the currentTrack is the last track, in which case it will reset currentTracks back to the beginning.

Constructor Methods

A constructor method is a special method within a class that allows you to “initialize” a new object instance when it is created. This allows you to set up an object before you do any outside property accessing or method calling. The constructor method is automatically executed when you create a new object instance. There are some rules for the constructor method:

  1. Only one constructor method per class
  2. The constructor has exactly the same as the class

What the constructor method actually does is really up to you as the programmer, just as what properties and methods are part of your class. In the book’s example, the constructor is used to initialize some properties of the IPod so that they can be set in the same line as the new object instantiation. The difference here between the way the properties were originally set is that you can set the specific to your new IPod instance without having to do it separately for each property.

package {

public class IPod {
// define properties
public var name:String;
public var volumeLevel:uint;
public var shuffle:Boolean;
public var currentTrack:uint;
public var tracks:Array;

//constructor method
public function IPod(name:String=" ",volumeLevel:uint=10,shuffle:Boolean=false){
this.name = name;
this.volumeLevel = volumeLevel;
this.shuffle = shuffle;
currentTrack = 0;
tracks = new Array();
}

public function play():void {
trace("Playing: "+ tracks[currentTrack];
}
}
}

Now we can set the values of name, volumeLevel, and shuffle at the same time as we make a new IPod:

var myIPod:IPod = new IPod ("Katy's Nano", 11);

Note that we if we don’t set an initial (or default) value for a properties passed in the constructor method, it becomes mandatory to set it when you create a new instance of the object.

Controlling Access to Properties and Methods

Livedocs > Class Property Attributes

So far, we have listed all our properties and methods as “public”. This means they are readable and modifiable from anywhere in our code. There are cases when we may not want to make the properties and methods of an object quite so accessible. We can manipulate these access attributes to limit the access like so:

  • private – accessible only to methods of the class itself
  • public – accessible to any code in the application where the class exists
  • protected – can be accessed by the class and its children (subclasses or classes that extend the class)
  • internal – accessible to any class in the same package

The last two won’t make too much sense until we talk more about packages and inheritance.

Now we’ll add a private variable to the IPod object – _serialNumber:

private var _serialNumber:String;

We can set the initial value of this new property using the constructor method, but if we try to access it later, say using trace, we’ll get an error when we try to compile the code.

Static Properties and Methods

The static attributes allow use to create properties and methods that don’t belong to a specific instance of a class. A good example of this is the Math class. There is no “Math” object that we work with in ActionScript, but the Math class is a useful collection of mathematical properties and methods that we can access when we need them.

We define static properties and methods like this:
public class StaticExample {
public static const PI:Number = 3.1415;
public static function doStaticStuff():void {
//take some actions
}
}

You can then access the properties and methods of the StaticExample class without creating an associated object:

trace(StaticExample.PI);
StaticExample.doStuff();

Using Inheritance

You can create an inheritance relationship between classes by using the extends keyword. An inheritance relationship is an “is a” relationship. In other words, my relationship to the Garnier family is thus: Katy “is a” member of the Garnier family. This means that I have all the attributes of a Garnier.

A subclass is a specialization of the base, or parent, class:
public class SubClass extends BaseClass {
}

Let’s relate this back to the IPod class:
package {
public class PhotoIPod extends IPod {

//define properties specific to the subclass
public var photos:Array ;
public var currentPhoto:uint;

//define constructor for the subclass
public function PhotoIPod (serialNumber:String, name:String=" ", volumeLevel:uint=10, shuffle) {
super(
serialNumber, name, volumeLevel, shuffle );
photos = new Array();
currentPhoto = 0;
}
//This function shows the number of the current photo
public function showPhoto():void {
trace("Showing: "+ photos[currentPhoto]);
}
public function nextPhoto():void {
if (currentPhoto == photos.length -1) {
currentPhoto = 0;
} else {
currentPhoto++;
}
showPhoto();
}

Now you can create new instances of the PhotoIPod class. The PhotoIPod has all the properties and methods of the IPod class, in addition to the properties and methods that are unique to itself.

Using Packages to Group Classes

So far we have been putting classes into the default package. This isn’t really the best way to organize things, what we really want to do is create logical custom packages to hold our code:

package name {
....
}

It is the convention to name your packages by reversing the domain name of the company (com.companyname) that the code is coming from. You should organize your classes in a way that best makes sense to you.

Importing Classes Into a Package

If you want to utilize the code from built-in or custom classes within your own packages, you must import those classes. For example, if I want to use MovieClip objects in my class, I need to add this code before my class definition:

package advancedActionScript.fall08.catherineGarnier.week3 {
import flash.display.MovieClip;
}

If I want to import all the classes in a given package, I use the * character (also called a wild card):

package advancedActionScript.fall08.catherineGarnier.week3 {
import flash.display.*;
}

This only imports the classes that are directly in that package, not in subpackages.


Homework

  1. Take the “MadLibs” and “Pick A Number” exercises from the past weeks and rewrite them as external classes. Create a flash file for each with the associated class as the Document class of the .fla.
08
Feb
2010