Konichiwa Tiggers,
I've been meaning to write an intro to programming for this site for a loong time, and I've finally started (Yes, started, there will hopefully be at least a couple more useful tutorials following this). I've tried to account for minimal programming experience, but if you are already a bit of a coder and interested in learning actionscript feel free to skimread. If you are experienced take a look at the last file to get a brief overview of the basic Actionscript 3.0 features.
This tutorial is an intro to some programming standards, using Actionscript 3.0 for flash. It costs nothing and won't take too long so give it a go. Sorry in advance if it's not all that captivating... I'm more of a coder than a writer.
If you are going to give this a shot, try to read through it and test bits of code in FlashDevelop as you go. It's the best way to learn. Attatched is an example of what could be your final product.
Required DownloadsFlashDevelop - Get the latest release (<4MB) Unfortunately it's Windows only for the time being, but it's well worth it.
Debug Flash PlayerFlex 3 SDK - Most recent stable build preferable (~100MB)
If you dont have
Java then get that, but its most likely already installed. Make sure to install this before FlashDevelop.
Setting up- Extract Flex SDK to somewhere on your harddrive (C:\flex_sdk_3 is a good location)
- Install FlashDevelop (just double click FlashDevelop-3.0.0-BetaX.exe and follow the instructions)
- Put the debug flash player in your Flex SDK directory
- Open up FlashDevelop
- Go to Tools->Program Settings->AS3Context->Flex SDK Location and point it to your FlexSDK install. If you extracted FlexSDK to flex_sdk_3 this should already be done
Lets get startedNow we can get started! Create a new project by going
Project->New Project and clicking
Empty Project under Actionscript 3. Today we'll be making a basic painting application to get you familiar with working with flash, so name the project Painter. Click Create directory for your project to put all the Painter files in one folder, and then hit OK.
You should see
Painter (AS3) has appeared on the right in the Project tab. Right click
Painter (AS3) and click
Add...->New Class and name it Main.as. That should produce a nice empty template for our project. A quick explanation of the terms:
package – A of grouping code, so it can be reused later in other projects. Don't worry about this too much, just make sure its there.
public – This is something that isn't really useful until you use properly use classes. Until then, just accept that it makes the class visible to the outside world.
class – Classes are a type of structure of code that mean you can reuse the code more easily. It's especially useful for when you want to have many of one type of thing (Such as in games. How convenient :D). Again, i'll go in to further detail next time.
Main– our class name.
function– In this case the function is our class contructor. That is, it creates Main. We'll go into more detail of functions soon.
To check everything is working smoothly lets run something. The following code shows some basic features of Actionscript 3.
Every time I give you some code, run it and try to understand why what happens happens. In order to run the code there are a few things you need to do first:
- Right click Main.as in the project tab and click Always Compile. This designates Main.as as the primary Actionscript file when you have multiple files.
- Name the output file by right clicking Painter (AS3) in the project tab and clicking properties. There you must give the output SWF a name, and you can also change the background colour or dimensions of the SWF.
- Save (Press Ctrl+s)
- Build and Run – The little blue arrow, or Ctrl+Enter
- If it doesnt work, and provides an error that ends with a '?', copy C:\Program Files\Java\jre1.6.0_07\bin\msvcr71.dll to your System32 folder.
- At the moment it shouldn't provide any output to you. Navagate to the folder with your SWF file, right click it, and Open With. Chose to always open it with the debug flash player we downloaded. That way, we'll see all output from the SWF.
package
{
import flash.display.Sprite; // Sprite is one of the basic flash classes
// we need to import it
public class Main extends Sprite // This means Main is a derivative of Sprite
/* your main class (in our case, its called Main)
* must extend DisplayObject. Sprite is far more useful than
* DisplayObject but luckily Sprite extends DisplayObject.
*/
{
public function Main() // This is a special type of function that we will go in to soon
{
trace(1+2); // simple arithmatic
trace(10+11); // not so simple arithmatic
yell("i'm angry!"); // this is calling the function yell
// traces are used for debugging and cannot be seen unless you have debug flash player. They are very useful when coding complex projects
var word1:String = "hello"; // creating a variable called word1 and giving it data
var word2:String; // creating a variable called word2
word2 = "tigs"; // giving word2 data
trace(word1 + " " + word2);
var values:Array = new Array( 3 );
// Here we have what is called a class constructor
// Array is a class (hover over it to see its details)
// so to create one you say someVariable = new ClassName();
// you can also say var values:Array = {10, "woopdawoop", 5.6};
values[0] = 10;
values[1] = "woopdawoop";
values[2] = 5.6;
for ( var i:int = 0; i < 3; i++ ) // i++ is the same as i = i+1 or i += 1
{
trace( "values[" + i + "] is " + values[i] );
}
var j:int = 5;
var isTrue:Boolean = true;
while ( isTrue ) // you could just have while j < 0 instead of the isTrue business
{
trace( j + "!" );
j--;
if ( j <= 0 ) isTrue = false;
}
trace("Go!");
}
public function yell( s:String ):void //This function returns nothing so we set its return type to void
// but it takes an argument of type String
{
trace( s.toUpperCase() + "!!!" ); // this line prints out the argument string in upper case
// and adds some exclamation marks
}
public function square( number:Number ):Number //This function returns a number
// and takes one argument, of type Number
{
return number*number;
}
}
}
Datatypes and Functions Overview
int– Positive and negative integers. Eg -10, 3, 42
Number – Numbers with decimal places eg 3.141, -1123.0
String – A word in quotation marks. \n is a newline, \t is tab.
Boolean – Either true or false.
Array – Stores a fixed number of variables. The variables can be of any type.
function - Functions take any number of arguements and may either return nothing (void) or a single object of a datatype.Hopefully none of this went over your head. If it did, don't hesistate to ask questions.
Now you know some of the basic syntax and features of Actionscript 3, let's do something more fun. In order to teach you some of the fundamental concepts of game programming, we'll write a program with some of the features of MS Paint.
package
{
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.MouseEvent;
public class Main extends Sprite
{
public var colour:int = 0xFF0000; // this is hexadecimal notation for RGB value of red
// 0x denotes hexadecimal, which is then converted to decimal for storage in colour
public var brushRadius:int = 1;
public function Main()
{
var title:TextField;
title = new TextField();
title.text = "Welcome to Painter!";
title.x = 10;
title.y = 10;
addChild(title);
stage.addEventListener( MouseEvent.MOUSE_DOWN, mouseDownListener );
graphics.lineStyle( 0, colour );
}
public function mouseDownListener( e:MouseEvent ):void
{
graphics.drawCircle( mouseX, mouseY, brushRadius );
}
}
}
Thanks to Adobe's descriptive function naming this code should be pretty easy to understand, but there may be a few things that seem confusing. Firstly, graphics is an element of Sprite that allows us to draw stuff on the screen. In FlashDevelop, hover your mouse over lineStyle and you'll see what it does, and what the arguments mean.
The most significant things here are addChild() and event listeners. In this case, when you call addChild(title) it is adding title to the Main class's objects. Since Main is by default “added” and drawn to the screen, title is also drawn to the screen. You could create another subtitle Textfield, and call title.addChild(subTitle), so subTitle would only be drawn when title was drawn. Another handy thing about that, is the x and y coordinates of subTitle become relative to that of title, rather than to the stage.
Speaking of stage... the stage in flash is the screen on to which stuff is drawn. stage.stageWidth and stage.stageHeight provide you with the width and height of the stage. Most significantly, in order to capture mouse clicks for the whole screen you need to add an EventListener to the screen. Event listeners are added to display objects (like the stage, or our title) and they capture user input or other events. Here we're adding a eventListener to the stage to listen for mouse clicks, and upon “hearing” a mouse click, it will call the function mouseDownListener (which is required to have an argument for the event type).
package
{
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.utils.Timer;
public class Main extends Sprite
{
public var colour:int = 0xFF0000;
public var brushRadius:int = 3;
public var mouseIsDown:Boolean = false;
public function Main()
{
var title:TextField;
title = new TextField();
title.text = "Welcome to Painter!";
title.x = 10;
title.y = 10;
addChild(title);
stage.addEventListener( MouseEvent.MOUSE_DOWN, mouseDownListener );
stage.addEventListener( MouseEvent.MOUSE_UP, mouseUpListener );
graphics.lineStyle( 1, colour );
var clock:Timer = new Timer( 1000 / 30 );
clock.addEventListener( TimerEvent.TIMER, update );
clock.start();
}
public function update( e:TimerEvent ):void
{
if ( mouseIsDown ) {
graphics.beginFill( colour ); // this makes the circle solid
graphics.drawCircle( mouseX, mouseY, brushRadius );
graphics.endFill();
}
}
public function mouseDownListener( e:MouseEvent ):void
{
mouseIsDown = true;
}
public function mouseUpListener( e:MouseEvent ):void
{
mouseIsDown = false;
}
}
}
If you've run the above block of code, you will have realised it doesn't too very much. In order to allow for dragging we need to constantly be drawing while the mouse button is down. To do this we'll create a timer. At the end of the Main function create a variable clock of type Timer (pressing tab while typing Timer should automatically insert import flash.utils.Timer; up the top). To give clock a value, we need to create an instance of the timer class, so call the Timer class constructor by typing = new Timer( 1000 / 30 ); 1000 / 30 will mean 30 frames per second which is a reasonable framerate (as it is expecting milliseconds). While the program is nice and simple 30 is pretty low, but for complex flash games 30 FPS is about right.
Now that we have a timer, we need to add an event listener to it so we know when its ticking. This time we have to import TimerEvent, so duplicate the line import flash.events.MouseEvent; and change MouseEvent to TimerEvent. Now add an event listener to clock to listen for TimerEvent, and call a function update, when it ticks.
Next we have to write update, or else the timer would be calling a function that doesnt exist. Create a new function called update, with one argument (it doesnt matter what its called, but the general standard is to call it e) of type TimerEvent. The return type should be void. Now copy and paste drawCircle line from mouseDownListener, and put it in update. If you want you can run the program now and it will constantly draw.
In order to only draw when the mouse button is down, we need to not only listen for mouse_down events but also mouse_up events. Duplicate the mouseDownListener function and listener, and instead make it a mouseUpListener. Remember, it should be listening for MOUSE_UP. Now we want to add another variable so we know when the mouse is down. In the same area that colour and brushRadius are defined, create a new variable mouseIsDown of type boolean. Now mouseDownListener should set mouseIsDown to true, and the up listener should set it to false. This allows us to put an if statement in our update function to control when we draw.
You will have noticed by now, that the drawing doesnt work very well. Try using
Adobe LiveDocs and the help avaliable to you in FlashDevelop to change the drawing method from circles to lines. A good way to do it is to draw a line from the last mouse position to the current mouse position. Also, try to add the ability to change colours using either buttons or keyboard input.
Hopefully you found this useful and not too boring! If you have any questions please feel free to ask. There may have been some things you felt I skimmed over but hopefully nothing too significant, and if there is something you don't understand,
LiveDocs is your friend!
Coming up next, classes, importing images and a half decent game. Happy coding!
For anyone interested, here is my final code (It's not spectacular, but it displays a good number of basic AS3 concepts).
package
{
import flash.display.Shape;
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.utils.Timer;
public class Main extends Sprite
{
public var colour:int = 0xFF0000;
public var brushRadius:int = 1;
public var mouseIsDown:Boolean = false;
public var colourButtons:Shape;
public var colours:Array;
public function Main()
{
var title:TextField;
title = new TextField();
title.text = "Welcome to Painter!";
title.x = 10;
title.y = 10;
addChild(title);
colours = [ 0x000000, 0xFFFFFF, 0xFF0000, 0x00FF00, 0x0000FF ];
colourButtons = new Shape();
colourButtons.x = 20;
colourButtons.y = stage.stageHeight - 50;
for (var i:int = 0; i < 5; i++)
{
colourButtons.graphics.lineStyle( 1, 0x000000 );
colourButtons.graphics.beginFill( colours[i] );
colourButtons.graphics.drawRect( i * 20, 0, 20, 20 );
colourButtons.graphics.endFill();
}
addChild( colourButtons );
stage.addEventListener( MouseEvent.MOUSE_DOWN, mouseDownListener );
stage.addEventListener( MouseEvent.MOUSE_UP, mouseUpListener );
graphics.lineStyle( 3, colour );
var clock:Timer = new Timer( 1000 / 30 );
clock.addEventListener( TimerEvent.TIMER, update );
clock.start();
}
public function update( e:TimerEvent ):void
{
if ( mouseIsDown )
{
graphics.lineTo( mouseX, mouseY );
}
}
public function isOverColourButtons( x:int, y:int ):Boolean
{
if ( x < colourButtons.x ) return false;
if ( x > colourButtons.x + colourButtons.width ) return false;
if ( y < colourButtons.y ) return false;
if ( y > colourButtons.y + colourButtons.height ) return false;
return true;
}
public function clickColourButtons( buttonNumber:int ):void
{
colour = colours[buttonNumber];
}
public function mouseDownListener( e:MouseEvent ):void
{
if ( isOverColourButtons( mouseX, mouseY ) )
{
var xpos:int = mouseX - colourButtons.x;
clickColourButtons( int(xpos / 20) )
}
else
{
mouseIsDown = true;
}
graphics.lineStyle( 3, colour );
graphics.moveTo( mouseX, mouseY );
}
public function mouseUpListener( e:MouseEvent ):void
{
mouseIsDown = false;
}
}
}
If you spot any errors or have any recommendations, i'd love to hear them.Look here for the source for my game, Pendulo. It should give you a good overview of how to code simple games in flash.