Tutorial: Coin Toss using ActionScript 3



Tutorial: Rock Paper Scissors using ActionScript 3.0.

This tutorial describes how to build a computer implementation of the playground game rock, paper, scissors (rps). The player plays against the computer.

Overview

My webpage for ActionScript 3.0 examples has a source file (rps3partial.fla) for you to download, examine and test. This partial implementation lacks the animated results for paper covers rock and scissors cuts paper and does not make changes in the picture displayed if there is a tie. You can try to complete it. This tutorial describes building the application from a blank (new) Flash document. It assumes you have some experience with Flash, such as building the coin toss application referenced on my page and that application will be referenced here.

The opening screen for Rock, Paper, Scissors (rps) is shown here:

[pic]

There aren’t any instructions. Hopefully, the interface is obvious enough for the player to click on one of the 3 pictures. These pictures are each buttons. If the player clicked on the rock, the application generates a move for ‘the computer’, that is, the opponent, and then applies the rules of the game. You could see a rock descend from the top of the screen and crush a scissors, resulting in the following screen:

[pic]

Another possibility is for a tie:

[pic]

The other possibility is for the computer move to be paper, in which case you would see the following.

[pic]

I will show one more situation: if the player clicked on paper and the computer played scissors, you would see an animation of the scissors cutting paper and this final screen:

[pic]

This application has things in common with the coin toss and also differences. Coin toss has a button from the Common Library. In rps, I use buttons I made myself. My code will establish a connection between the buttons and calls to a function in a similar way to how that was done in coin toss. One difference will be that rps has a function I named computerturn that has a parameter that indicates what the player played. Both applications make use of Math.random. Both applications use dynamic text fields to show the results.

The dramatic difference between rps and coin toss is the animation. One way of producing animation is to create a sequence of images and show them to the viewer fast enough that the mind/eye perceives animation. In Flash, we do this by creating frames and using the movie clip methods gotoAndPlay and stop. You can see the individual frames I drew for the rock falling on the scissors in the rps3partial.fla Flash document.

Implementation

Open Flash and under Create New select Flash file (ActionScript 3.0).

This will open up the Flash development environment. It should look something like this:

[pic]

Flash has many windows/panels, so you spend some time clicking on Window and selecting the ones you want at the moment. What the screen shot shows in the center is the Flash Stage. At the top, with the name Layer 1, the first (and only) frame is highlighted. This is the Timeline. On the right, below the panel with the rainbow, is the empty Library. On the left, is the Toolbox. You, the developer, will create symbols (movie clips, graphics and buttons) in the Library. Note: movie clips can consist of just one frame and no code or can be quite complex. You will bring instances of these to the Stage at particular frames. This application will have many frames. You also may draw directly on the Stage and create text fields (static, dynamic, or input) on the Stage. You will write code, ActionScript, in the frames, mostly in frame 1, and a small amount in certain of the other frames.

The first step for rps will be to create buttons to represent the 3 possible moves. In Flash click on Insert/New Symbol. You want to click on the Button option and give the new symbol a name. The screen shot shows where I typed in rock.

[pic]

The editor opens up a window to create the button symbol:

[pic]

|[pic] |The task is to create 4 frames for the button. The Up frame is |

| |the one shown when the mouse cursor is not on the button. The |

| |Over is when the cursor is on top of the material in that frame. |

| |The Down is when the cursor is over the material in the frame AND|

| |the mouse button is pressed down. The Hit frame, never displayed,|

| |indicates the material that will constitute a hit. You can do |

| |strange things with these 4 frames! The usual practice is to make|

| |some changes so the player gets feedback. |

| | |

| |Start by drawing a picture of a rock. Use the drawing tools to |

| |create a rock: the Paint brush (which has been selected) would |

| |serve well. Click to color box below the pouring pail of paint to|

| |get a suitable color. |

Next click on the Over frame and then click on Insert/Timeline/Keyframe.

[pic]

Now, in order to change the color of the rock, I click on the color patch and select a color from the palette shown:

[pic]

Since the rock is selected, this will make it be the new color.

Repeat this for Down and for Hit. When you have done this, you have a complete button: 4 frames! Click on Scene 1 to return to the main movie.

You should see something like this:

[pic]

There is nothing on the Stage (yet). There is a button named rock in the Library. Click and drag the rock to the Stage and in the Properties panel, type in rock as the button instance name. This is very important. The ActionScript code refers to objects by instance names.

[pic]

You need to go through the same steps to create a button for paper and a button for scissors. Remember that you can change the look of symbols in the Library and they will change all instances of the symbols on the Stage in all frames. This suggests that you should not spend too long, since you can enhance your drawings later.

I decided to use text and animation. I will describe the text first and then the animation.

Use the T tool to add 2 text fields to the Stage. Give one the name computer and the other the name result. The screen shot below shows the second, lower text field selected. Notice that the Property panel indicates that it is a Dynamic text field. You will need to set this if the initial value is Static. Also, notice that I have typed in the name result. You will need to do this as well. I didn’t put anything in either of these text fields. If you wanted, you could put instructions to start off.

[pic]

To use a cliché that is technically accurate, the Stage is set! You can write the code beforehand, but now it will make more sense.

Click to select the first frame in the Timeline and then Window/Actions to open the Actions panel. The code consists of the declaration of an array called options, the definition of a function called computerturn, and three rather complex statements connecting the event of clicking on each button with a particular call to the function.

The options array is a tactic for associating the terms for the 3 moves with numbers. I do this because I will use numbers to get the random move. The player never sees these numbers and I could use any order. An array is a construct common to programming language of putting together sequences of values. Each value is indexed by a number. In this case, the valid index values are 0, 1 and 2. In ActionScript, array indices start at zero, not 1. Notice the notation and the use of square brackets and commas. Notice also that you must type "rock" and not just rock. In this application "rock" is the character string that is used internally and also shown to the player. Any reference to rock will be to the rock button.

var options:Array= [

"rock",

"paper",

"scissors"

];

The next piece of code is the definition of the function. It does two things and it does not cheat! The header of the function sets up that this function will be invoked with a parameter that will be used internally to hold what the player played. It will have the name player and be valid 'inside' the function. Because ActionScript requires strict data typing, the datatype for the string is specified by a colon and then the keyword String.

Within the function definition, I use a variable I call cp. It will be a String also, so the declaration (the var statement) is

var cp: String;

Remember that Math.random() returns a decimal value from 0 to 1 (including zero, but not 1). If this is multiplied by 3, then you have a value from 0 up to but not including 3. Taking the Math.floor of this returns either 0, 1 or 2. This is exactly what is needed to index the options array.

The function displays to the player what the computer move is by setting computer.text. The next sequence of if statements carries out the rules of the game. The first if condition uses the double equal sign to check if cp and player are the same. The next if conditions each check for two things both being true, making use of &&, which is the logical AND operator. In each case, the results are displayed to the player by putting the results in result.text to show to the player.

function computerturn(player: String) {

var cp:String;

cp = options[Math.floor(Math.random()*3)];

computer.text = "Computer played "+cp;

if (cp==player) {

result.text = "TIE";

}

if ((cp=="rock")&&(player=="paper")) {

result.text="Player wins: paper covers rock.";

}

if ((cp=="rock")&&(player=="scissors")) {

result.text="Computer wins: rock breaks scissors";

}

if ((cp=="paper")&&(player=="scissors")) {

result.text="Player wins: scissors cuts paper.";

}

if ((cp=="paper")&&(player=="rock")) {

result.text="Computer wins: paper covers rock.";

}

if ((cp=="scissors")&&(player=="rock")) {

result.text="Player wins: rock breaks scissors.";

}

if ((cp=="scissors")&&(player=="paper")) {

result.text="Computer wins: scissors cuts paper.";

}

}

The last part of the ActionScript sets up the event handling. Since I plan to use the same function for all 3 buttons, except with different parameters, I need to make the second parameter to the addEventListener method be this function definition. Look at the notation carefully. You will see that the brackets and the parentheses do match up and are nested properly. This is called an anonymous function definition because it does not have a name. It is never used outside of the event handling. Notice also that event handlers are expected to have a parameter, so I put in the ev.

rockbtn.addEventListener(MouseEvent.CLICK, function (ev) {

computerturn("rock");} );

paperbtn.addEventListener(MouseEvent.CLICK, function (ev) {

computerturn("paper");} );

scissorsbtn.addEventListener(MouseEvent.CLICK, function (ev) {

computerturn("scissors");} );

You can test this application by going to Control/Test Movie. If I, as the player, clicked on the paper button, the following may appear:

[pic]

It is important to test all options for games. Don't stop as soon as you win.

Before going on, here are comments on functions! Why did I decide to define the function computerturn and why did I do it the way I did? First of all, I could have done it differently: I could have put code in each of the anonymous functions set up in the addEventListener statements or I could have defined 3 separate functions: computerturnAfterPaper, computerturnAfterRock and computerturnAfterScissors. Either of these two approaches would have meant duplication, though each individual function definition would have been shorter than computerturn. The reasoning in any decision may not be obvious or compelling. Generally speaking, if you find yourself writing the same code again and again, think of defining a function.

Now I can show you how to add the animation. On the Timeline, skip over several frames (this came in handy later—you do not need to economize on frames) and select an empty spot. Click on Insert/Timeline/Keyframe. Keyframes are used if you are adding new material to the Stage or ActionScript. Regular frames are used in Flash for placeholders to take time and for tweening animations. For the most part, my applications use just keyframes.

Notice that all the material from the previous keyframe is copied to the new keyframe. This generally is what you want. Use the Property panel to give the frame the name rockbreaks.

[pic]

The next steps will involve drawing on the Stage. My idea is to show a rock dropping on a scissors. I will re-use the drawing I have already made. Double click on the rock button in the Library. Use the arrow tool to select and then Edit/Copy the picture of the rock. This is graphics from the rock button—NOT the rock button as a whole. Go back to Scene I, the main movie, and Edit/Paste in Place. Then drag the rock over to the upper right part of the Stage. It can even be somewhat above the white area, meaning it won't all be visible. Do the same thing to get a picture of a scissors. When you drag the scissors graphic to the lower right side, you can click on Modify/Transform/Free transform

[pic]

A box will appear around the selected object, the scissors graphic:

[pic]

and you can move the mouse and manipulate the image. Flash segments, that is, divides graphics up into parts allowing you the ability to select parts, delete, move or transform them. To select multiple parts, hold the shift key down. (I'll repeat that below).

When this first frame suits you, click on the next frame in the Timeline and Insert/Timeline/Keyframe. A new frame, with the same material as the prior one, will appear. Select the rock graphic at the top and move it down the screen. Make sure you get the whole thing: it is easy in Flash to get just the fill and not the outline, if your graphic has both. Hold down the shift key to select in several steps. You also can use the lasso tool. Continue in this way to make the animated sequence.

When you have completed the sequence, click on the first frame in the Timeline and open the Actions window (Window/Actions). You need to make changes to what is there.

Move the var statement for cp from the function definition to outside the function definition. It can be right before it. Add the statement

var res: String;

These two variables are needed to set the dynamic text boxes in code in other frames. Because this code is outside the function definition, the variables need to be global variables, not local to a function. Within the function, replace all the statements that assigned something to result.text to assign it instead to res.

The code also needs to be modified to have control flow to the appropriate frame.

You haven't put in the other animated sequences yet, but here is what the new function definition will be, assuming you have frames named "tie", "covers", and "cuts".

function computerturn(player: String) {

cp = options[Math.floor(Math.random()*3)];

computer.text = "Computer played "+cp;

if (cp==player) {

res = "TIE";

result.text = "TIE";

gotoAndPlay("tie");

}

if ((cp=="rock")&&(player=="paper")) {

res="Player wins: paper covers rock.";

result.text = res;

gotoAndPlay("covers");

}

if ((cp=="rock")&&(player=="scissors")) {

res="Computer wins: rock breaks scissors";

result.text = res;

gotoAndPlay("rockbreaks");

}

if ((cp=="paper")&&(player=="scissors")) {

res="Player wins: scissors cuts paper.";

result.text = res;

gotoAndPlay("cuts");

}

if ((cp=="paper")&&(player=="rock")) {

res="Computer wins: paper covers rock.";

result.text = res;

gotoAndPlay("covers");

}

if ((cp=="scissors")&&(player=="rock")) {

res="Player wins: rock breaks scissors.";

result.text = res;

gotoAndPlay("rockbreaks");

}

if ((cp=="scissors")&&(player=="paper")) {

res="Computer wins: scissors cuts paper.";

result.text = res;

gotoAndPlay("cuts");

}

}

The default in Flash is to go to the next frame and, at the last frame, to loop back to the first frame. This means you need to add the statement:

stop();

to the first frame and to the last frame of each sequence. You will recognize very quickly if you have left out any necessary stop statements.

The last frame of each sequence also needs statements to set the text fields. So the ActionScript for the last frame for the sequence starting with the frame labeled rockbreaks is:

result.text = res;

computer.text = "Computer played "+cp;

stop();

You can test the program now. For the two situations in which the appropriate sequence is a rock breaking a scissors it should work properly. When you, as player, click on a piece, the program proceeds from which ever frame it is at. This is because the event handling for the buttons refers to them by name.

Go ahead and make the other sequences of keyframes. The first one needs a name and the last one needs the 3 statements just shown. When you add the keyframe after the last frame for a rock breaking a scissors, you will need to erase the graphics showing the rock and the crushed scissors.

What should the picture be for a tie? I chose to have no picture. What this means, however, is that I need to put in a frame without anything. Doing nothing will leave whatever the previous result was. So, I added a frame between the 1st one and the one added for rock breaking a scissors. I gave the frame the name tie and added the 3 statements.

Test the program. Try each piece several times to make sure all 3 results happen.

To produce a finished version of the program suitable for uploading to the Web, Click on File / Publish. This produces two files: an .html and a .swf . You need to upload both of these files along with a file named AC_RunActiveContent.js to the file folder, if that is not already present. This file is created by the Flash environment and will be in the folder with the other files. When setting up a link to your game, make the href be to the .html file.

ActionScript 2.0 to ActionScript 3.0

Only read this if you are familiar with previous versions of Flash and want to reflect on the differences.

First of all, consider that much is the same: you still bring material to the Stage; give things names; write a function that performs the logic, including calls to Math.random; and set up a connection between events involving buttons and functions. Flash still has a Timeline and the movie clip methods stop and gotoAndPlay are used to change the default behavior.

Now, here are the differences that I noticed:

The option to write code 'in' the button referring to on(Release) is not longer available. You must use frame code and, since the event handling I wanted made use of calls with specific parameters to a function, the format is

rockbtn.addEventListener(MouseEvent.CLICK, function (ev) {

computerturn("rock");} );

The anonymous function needed to have a parameter, I called it ev.

The option to use a VAR name for a dynamic text field is no longer available. You need to give text fields instance names and refer to the .text property. Moreover, the conversions between numbers and text must be done explicitly:

computer.text = "Computer played "+cp;

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download