26
Tutorial: Memory/Concentration using ActionScript 3.0. This tutorial describes how to build a computer implementation of a memory/concentration matching game. It will demonstrate the use of classes, packages, objects and separate .as files, Date objects used for timing, and the display hierarchy. Application The game begins with a [simulated] set of cards face down. The player clicks on first one and then a second card:

Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

Tutorial: Memory/Concentration using ActionScript 3.0.

This tutorial describes how to build a computer implementation of a memory/concentration matching game. It will demonstrate the use of classes, packages, objects and separate .as files, Date objects used for timing, and the display hierarchy.

ApplicationThe game begins with a [simulated] set of cards face down.

The player clicks on first one and then a second card:

Page 2: Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

For this game, matched pairs are not identical, but represent musical symbols and names of musical notes. This constitutes a match, so the two cards are removed:

Page 3: Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

The game continues: here is a non-match:

Page 4: Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

In the case of a non-match, the cards 'flip back' to show the back side.

When the player makes all the matches, the elapsed time is displayed:

Page 5: Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

(I must defend this very bad performance: the time elapsed includes the time for making the screen captures and copy and pasting the images into this Word document.)

Planning and concepts

The critical features for this application include:

A way to represent the cards, that is, a face image and a back image coupled together

Identifying the event of a card back being clicked and coding the event handler that 'flips' the card

A way to define matched pairs Checking of selected pairs to see if there was a match Putting in a pause before removing a matched pair or flipping unmatched pairs

back Keeping track of starting and completion times in order to display the elapsed

time when the game is complete

Shuffling the positions of the cards to produce a random arrangement of the cards

Page 6: Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

I want to share with you how I arrived at this implementation. Be patient: I will describe the details next.

My first idea for representing the cards was to use movie symbols with 2 frames, one frame showing the face and one frame showing the back. However, a goal for the implementation, as opposed to the game, is to separate the specifics of a particular set of cards with the coding for all memory games. I realized that what cards had in common was the card back and it was the card back that would be clicked on by the player. Therefore I decided to define a class I named Card to hold the general coding. The .fla file would contain movie clip symbol instances for the card faces and one more movie clip symbol to be the card back. This symbol would be the one to be the basis of the Card class. The face instances are placed on the Stage in an acceptable arrangement. That is, the general code does not have the burden of doing this positioning.

NOTE: when you make your own memory game, you will create movie symbols for the card faces of your game! You will move instances of these symbols to the Stage, give them instance names and arrange them on the Stage. You will write code in the Actions panel that refers to your instance names.

When you set up a class, you need to decide what data constitutes the class. The Card class would be linked to the MovieClip symbol that represented the card back. A variable would contain a reference to the corresponding face MovieClip instance. Another variable would hold a character string that would be used for checking for matches. The .fla file would contain calls to the constructor method Card to set up (create) Card instances. These instances would have all the information required to represent a whole, meaning front and back, card. The constructor method would require 2 parameters: one the instance name for the face and the other the character string. The card back and the card face are linked in another way. Objects are created by using the new keyword and invoking constructor methods. However, if the objects are to be displayed on the screen, this is not enough. Objects must be added to what is called the display hierarchy. For Card objects, I accomplish this using the addChild method of the face instance. Making the card back a child of the card face also means that shuffling the cards, that is, moving them around on the screen, moves card face and card back together.

The Card constructor method also sets up the event handling for clicking on the card symbol to invoke the method called uncover. The uncover method would set up a timer event. This is critical for inserting a pause so the player gets to look at the 'uncovered' cards. The event handler for the timed event would be a method I called check2 (checking two card faces for matches).

Certain coding and data is independent of any specific Card object. This means I used the static modifier to set up class variables and class methods. Class variables are used to manage the process of clicking on first one card and then the second. Class

Page 7: Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

variables also include the Timer object used to produce the pause, a reference to a Text Field to hold the final result and a Date object that holds the starting time. Lastly, an array named cards will hold references to all the Card objects created. The array is used to do the shuffling.

A class method called mixup is used to set up the Text Field reference, create and store the Date object, and perform the shuffling of the cards. Such initialization is frequently necessary in games and other applications. Shuffling is done by swapping pairs of cards.

Implementation

Class definitions are set up as elements of packages. This application has just one class definition by the name Card. I gave the package the name memory. The convention is for classes to start with capital letters and packages to start with lower-case letters. In Flash and ActionScript, you put the class definition files in a folder with the name of the package and you specify the location of this folder.

The symbol set up for the card back, named card, is linked to the Card class defined in the file Card.as, part of the package memory. Using the language of classes and objects, a Card is defined as a subclass of the MovieClip class. The constructor method to create new Card objects establishes what the face instance is for each card.

The design can handle more than 6 cards, but that is a good number for a first try. You need to make all the face symbols and the card (back) the same size and located in the same position.

Start with a new Flash .fla file. Insert/New Symbol and give it a name that identifies what it represents for you. Since I wanted to produce a music notation game, I used names such as halfnote. Draw a rectangle and then draw what you want.

Page 8: Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

A good technique is to copy the symbol, change the name, and then modify the graphics to be what you want, keeping the rectangle, and continue for all the faces and also for the back.

Bring an instance of each face symbol (but not the card symbol), to the Stage, give each one an instance name, and arrange neatly on the Stage. Notice that have two layers, named board and actions and the instances are in the board layer.

You can use the X and Y values to make the instances line up:

Page 9: Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

The Stage also contains a Dynamic Text field named res.

Page 10: Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

The card symbol must have the Linkage set up to associate it with a Class to be written next. You do this by right clicking on the card in the Library to get a panel. In Adobe CS3: click on Linkage. In Adobe CS4: click on Properties. If the panel has a button for Advanced, click this button. The screen show shown below is from the CS3. You do similar things in each case: click on Export for ActionScript.

Page 11: Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

On the Linkage or Properties panel, click to select Export for ActionScript. The other check will appear automatically as will the entry in Base class. For the Class field: type in memory.Card. This class has not been created yet, but I will describe

Page 12: Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

how to do that next. You can click on okay for message that says no such class exists and one will be created.

In the Flash CS4, the linking is done in the Properties Advanced panel. You get to this by right clicking on the symbol in the Library, click on Properties and then Advanced. You now do the same thing as in CS3: click to select the Export to ActionScript option. The Export in first frame will click on (you can turn this off if you have an application with many frames and you want to postpone when the class definition is available). You may need to change the default setting for what class will be used.

Page 13: Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

If you previously have prepared a class file, the next settings may already be made. Click on File/Publish Settings… and then click on Flash,

Page 14: Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

Click on Settings… next to ActionScript

Page 15: Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

Click on the plus and then the cross hairs, which opens up a browser. Select the folder in which you will put the memory folder.

Page 16: Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

This 'tells' Flash where to look to find any packages created. I will put the Card.as file in a folder named memory in C:\as3. I will describe this file later. NOTICE: for a PC, the as3 folder (you can use another name), must be at the top of the drive. For the Mac, it can be in the same folder as the .fla file.

There is code to put in the actions layer of this .fla file. I wrote it after I wrote the Card.as file, but I will show and explain it now.

Recall from the Concepts and Planning section that the constructor method Card requires two parameters: one the face instance name and the other a string used for matching. In this example, the picture of the note and the name of the note are to be matched. There is a class method called mixup that does certain initialization work and does the shuffling. Consequently, it requires the Text Field name as a parameter.

After creating a new layer and naming it actions, use Window/Actions to open up the Actions panel and insert code for importing the memory definition, setting up the Card objects, and then calling the mixup method. Think of the Card object as something that

Page 17: Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

puts together the common back-of-card with the distinct faces you have created. Here is MY code:

import memory.*;

var c1:Card = new Card(hn,"h");var c2:Card = new Card(hnname,"h");var c3:Card = new Card(qn,"q");var c4:Card = new Card(qnname,"q");var c5:Card = new Card(en,"e");var c6:Card = new Card(enname,"e");

Card.mixup(res);

The import statement is necessary to reference the package containing the Card class definition. The var statements create the Card objects. YOUR CODE WILL BE DIFFERENT BECAUSE IT WILL REFER TO THE FACE INSTANCES YOU HAVE CREATED. The hn, hnname, qn, etc. are all the instance names for the face movie clip instances. The strings indicate which pairs of faces constitute a match. This allows for the flexibility of using the same graphics or different graphics as well as the possibility to have more than 2 faces be matches. Lastly, I put in a call to Card.mixup, doing the initialization described, including the shuffling.

The main work for the application is in the Card.as file. The code sets up what we can think of as a card. It has a front and a back. It responds to the player clicking. When the player clicks on two cards in successive, the code implements the checking using the strings sent to it in the calls to Card. The code makes use of two timers. One timer is used to force a pause. That is, after the player clicks on the second card, there is a pause before the cards are removed or (virtually) flipped from the front to the back. The other timer is used to keep track of the total time used to do the puzzle.

In Flash, click on File/New and choose ActionScript file. Here is an outline for the Card.as file. Class variables are for the whole class: meaning there is just one copy of each one no matter how many objects there are. In contrast, there is one of each object variable for each object: each card in this case.

Note: I came to the import statements by trial-and-error. That is, in the initial testing, I got error messages if I used a method or attribute that used a built-in part of Flash that I did not import. Eventually, I realized that I needed the 6 import statements shown.

Here is an outline for the Card.as file. This is NOT to be copied over into the your application, but to give you an overview sense of what the coding is.

package memory { import statements: these indicate which built-in features of Flash are needed public class Card extends MovieClip {

Page 18: Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

class variables object variables constructor method: sets card face & matching info uncover method: called at the clicking of each card (back) check2 method: called after a pause after the second of the two cards is clicked mixup method: a class method, to do shuffling and other initialization }}

With this general outline in mind, here is the code, annotated, for Card.as:

package memory{ Open package import flash.events.*; Import statements import flash.display.*; import flash.utils.Timer; import flash.events.TimerEvent; import flash.ui.Keyboard; import flash.text.*; public class Card extends MovieClip { Open class definition.

Since it is linked to a movie clip symbol, it must extend (be a subclass of) MovieClip

private var clip:MovieClip; Used to refer to the face instance

private var match:String; Used to hold the match string

private static var matched:int = 0; Keeps overall count of

matched cards (matches times two)

private static var uncovered:int = 0; Keeps track of how many cards clicked.

private static var firstcard:Card; Reference to the first card private static var secondcard:Card; Reference to the second

card private static var mtimer:Timer = new Timer(2000,1);

Used for the pause. Set here for 2 seconds. Only one time.

private static var resultplace:TextField;

Holds reference to the Text Field on Stage that will show the result

private static var cards:Array = new Array();

Used for references to all the created cards

private static var startDate:Date; Used of keep track of time

Page 19: Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

public function Card(mclip:MovieClip, matchs:String) {

Constructor method. Takes as parameters the face clip and the match string.

this.clip = mclip; Set object variable mclip.addChild(this); Add the Card being

created as a child of the face instance, already displayed on stage, so the card back will be displayed (on top of the card face): see next

this.x = 0; Position the card back in the same x as the face

this.y = 0; Position the card back in the same y as the face.

this.match = matchs; Store the match string cards.push(this); Add the newly created

card to the cards array. this.addEventListener(MouseEvent.CLICK,uncover);

Set up (register) click event, event handler uncover

this.buttonMode = true; Set the card to receive these events

} Close method private function uncover(ev) { Open method. The

parameter is required, even though it is not used.

if (uncovered<2) { Do check to keep player from clicking on more than 2 cards

uncovered++; Increment uncovered this.clip.visible = true; Reveal the face card by

making it visible and this.visible = false; ….making the card back

invisible if (uncovered==1) { Is it the case of a first

card? Card.firstcard = this; … store reference} Close true clause else { else Card.secondcard = this; Store reference Set up (register) timed

Page 20: Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

Card.mtimer.addEventListener(TimerEvent.TIMER, check2);

event: this produces the pause. The method check2 will be invoked after 2 seconds.

Card.mtimer.start(); Start timer event } Close else clause (second

card) } Close true clause for being

first or second card } Close method private function check2 (ev) { Open method. The

parameter is required, but is not used.

Card.mtimer.removeEventListener(TimerEvent.TIMER, check2);

Remove event handling

if (Card.firstcard.match == Card.secondcard.match) {

Do the check if it is a match

Card.matched = Card.matched +2; Add to matched count (done by 2s)

Card.firstcard.clip.visible = false; Make first card not visible Card.secondcard.clip.visible = false;

Make second card not visible

if (Card.matched == Card.cards.length) {

Check if all the cards are matched

var startTime = startDate.getTime();

Extract the time (in milliseconds) at the start

var now = new Date(); Get current date and time var nowTime = now.getTime(); Extract the time var elapsed:Number = (nowTime-startTime)/1000;

Compute elapsed time in seconds by doing the subtraction and dividing by 1000

resultplace.text = "You win. "+elapsed + " secs.";

Display message

} Close clause for all matched

} Close clause for being a match

else { Else (not a match) Card.firstcard.visible = true; Make card back of first

card visible Card.secondcard.visible = true; Make card back of second

card visible } Close else clause

Page 21: Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

Card.uncovered = 0; Reset uncovered to 0 for the next round

} Close method public static function mixup(result) { Open method. Parameter

holds reference to the text field on stage.

Card.resultplace = result; Store reference var holderx:int; Used for the shuffling var holdery:int; Used for the shuffling var nc:int = Card.cards.length; Number of cards var i: int; Used to point to a random

card var j: int; Used to point to a random

card. var t: int; Counter of number of

swaps //loop does 2*nc swaps for (t=0;t<2 * nc;t++) { The loop for grabbing two

cards and swapping positions.

i = Math.floor(Math.random()*nc); Random card j = Math.floor(Math.random()*nc); Random card. NOTE: no

effect if i and j are equal //re-position clip, the Card (back) will move also //save i position holderx = Card.cards[i].clip.x; Store the ith x value holdery = Card.cards[i].clip.y; Store the ith y value //move i to jth position Card.cards[i].clip.x = Card.cards[j].clip.x;

Reposition the ith clip in x to be the x value of card j

Card.cards[i].clip.y = Card.cards[j].clip.y;

Reposition the ith clip in y to be the y value of card j

//move j to what was i position Card.cards[j].clip.x = holderx; Reposition the jth clip in x

to be the x value stored in holderx

Card.cards[j].clip.y = holdery; Reposition the jth clip in y to be the yvalue stored in holdery

} Close loop startDate = new Date(); Store date and time } Close method } Close class

Page 22: Tutorial: Coin Toss using ActionScript 3faculty.purchase.edu/jeanine.meyer/as30/memory.doc · Web viewThe convention is for classes to start with capital letters and packages to start

} Close package

Enter in the code given above. Go to File/Save As. Then browse to the folder you created at the top of the drive. Mine was c:/as3. Create a new folder called memory in as3. Then Save the Card.as in the folder memory.

Return to the .fla file and test the program Control/Test Movie. You may want to experiment with different pause times. Remember: your code in the .fla file will be similar, but not the same as mine.