This Flash game has you remember the location of playing cards, in order to locate matching pairs.
Download the FLA file// THIS IS AN ACTIONSCRIPT FILE, NOT AN .FLA FILE
package {
import flash.display.*;
import flash.events.*;
import flash.utils.*;
import flash.media.Sound;
import flash.media.SoundChannel;
public class As3_match_cards extends MovieClip {
var theFirstCardSound:FirstCardSound = new FirstCardSound();
var theMissSound:MissSound = new MissSound();
var theMatchSound:MatchSound = new MatchSound();
private static const pointsForCorrect:int = 200;
private static const pointsForIncorrect:int = -20;
private static const pointsForGameOver:int = 1000;
private var score:int = 0;
private static const leftMargin:int = 50;
private static const topMargin:int = 150;
private static const padding:uint = 5;
private static const cardColumns:uint = 8;
private static const cardRows:uint = 4;
private static const deckSize:uint = 54;
var xx:uint;
var yy:uint;
var i:uint;
var cardWidth:Number;
var cardHeight:Number;
var deckArray:Array = new Array();
var deckArrayIndex:uint;
var cardArray:Array = new Array();
var cardArrayIndex:uint;
var cardFace:uint;
var cardToPick:uint; // value 1 through 54
var cardsOnTable:uint = cardColumns * cardRows;
var cardPairs:uint = cardsOnTable / 2;
var firstCard:Card = null;
var secondCard:Card = null;
var pairsLeftToMatch:int = cardPairs;
public function As3_match_cards():void {
stop();
MovieClip(root).score_txt.text = 0;
// create an array of card numbers:
for (i=0; i<deckSize; i++) {
deckArray[i] = i + 1; // adding 1 gives the Ace of clubs a correct
// cardFace (frame number in Card movie clip
// timeline) of 1, instead of the incorrect
// cardFace of zero.
}
// pick 16 (or whatever "cardPairs" current value is) cards at random from deckArray:
for (i=0; i<cardPairs; i++) {
deckArrayIndex = Math.floor(Math.random() * deckArray.length);
cardToPick = deckArray[deckArrayIndex]; // pick a number from 1 to 54 that isn't taken yet
deckArray.splice(deckArrayIndex,1);
cardArray.push(cardToPick);
cardArray.push(cardToPick);
}
// arrange the chosen 16 pairs of cards randomly on the stage:
for (xx=0; xx<cardColumns; xx++) {
for (yy=0; yy<cardRows; yy++) {
var currCard:Card = new Card(); // card is the playing card library item I created
currCard.buttonMode = true; // make cursor same as for a button (pointing finger)
currCard.scaleX = 0.5;
currCard.scaleY = 0.5;
cardWidth=currCard.width;
cardHeight=currCard.height;
cardArrayIndex = Math.floor(Math.random()*cardArray.length); // cardArray.length keeps getting shorter
cardFace = cardArray[cardArrayIndex];
currCard.cardFace = cardFace;
currCard.cardColumn = xx;
currCard.cardRow = yy;
currCard.gotoAndStop("cardBack");
cardArray.splice(cardArrayIndex,1);
currCard.x = (xx * (cardWidth + padding)) + leftMargin;
currCard.y = (yy * (cardHeight + padding)) + topMargin;
currCard.addEventListener(MouseEvent.CLICK, clickCard);
currCard.addEventListener(MouseEvent.MOUSE_OVER, overCard);
currCard.addEventListener(MouseEvent.MOUSE_OUT, outCard);
addChild(currCard);
} // end of inner j loop
} // end of outer i loop
} // end of constructor
function overCard(myEvent:MouseEvent) {
var currentCard:Card = (myEvent.currentTarget as Card);
currentCard.alpha = .85;
}
function outCard(myEvent:MouseEvent) {
var currentCard:Card = (myEvent.currentTarget as Card);
currentCard.alpha = 1;
}
function clickCard(myEvent:MouseEvent) {
var clickedCard:Card = (myEvent.currentTarget as Card);
if ((firstCard == null) && (secondCard == null)) // first card in a pair was just clicked
{
playSound(theFirstCardSound);
firstCard = clickedCard;
firstCard.gotoAndStop(firstCard.cardFace);
}
else if ((firstCard != null) && (secondCard == null)) // second card in a pair was just clicked
{
secondCard = clickedCard;
if ((firstCard.cardColumn == secondCard.cardColumn) && (firstCard.cardRow == secondCard.cardRow))
{ //trace ("same card was clicked");
playSound(theMissSound);
clickedCard.gotoAndStop("cardBack");
firstCard = null;
secondCard = null;
}
else
{ trace ("a different card was clicked");
trace("first card face: " + firstCard.cardFace);
trace("second card face: " + secondCard.cardFace);
secondCard.gotoAndStop(secondCard.cardFace);
// at present the game is "easy", considering it a match
// even if suit is different, as long as value is the same.
// adding 13 to a cardFace gives you the same card in the next suit.
// The 2 Jokers don't act the same as the other cards, which is why I
// say that easy mode is only for cards with a cardFace < 53:
if ((firstCard.cardFace == secondCard.cardFace) ||
((firstCard.cardFace < 53) && (secondCard.cardFace < 53) && (firstCard.cardFace - secondCard.cardFace) % 13 == 0))
{ trace("match");
playSound(theMatchSound);
score += pointsForCorrect;
MovieClip(root).score_txt.text = score;
var myTimer:Timer = new Timer(100,1); // the "1" ensures that the timer runs just once
// and doesn't keep looping.
myTimer.addEventListener(TimerEvent.TIMER, removeMatchingPair);
myTimer.start();
}
else
{ //trace("no match");
playSound(theMissSound);
score += pointsForIncorrect; // yes, you want to ADD a negative number,
// not subtract a negative number!
MovieClip(root).score_txt.text = score;
var myTimer2:Timer = new Timer(1000,1); // the "1" ensures that the timer runs just once
// and doesn't keep looping.
myTimer2.addEventListener(TimerEvent.TIMER, hideCardPair);
myTimer2.start();
}
}
}
else if ((firstCard != null) && (secondCard != null)) // user wants to move on quickly, before
// timer kicks in and the program
// hides the two chosen cards.
{
playSound(theFirstCardSound);
firstCard.gotoAndStop("cardBack");
secondCard.gotoAndStop("cardBack");
firstCard = clickedCard;
secondCard = null;
firstCard.gotoAndStop(firstCard.cardFace);
}
else
{ trace("this branch of if-else hopefully never takes place");
}
}
function hideCardPair(myEvent:TimerEvent) {
if ((firstCard != null) && (secondCard != null))
{
firstCard.gotoAndStop("cardBack");
secondCard.gotoAndStop("cardBack");
firstCard = null;
secondCard = null;
}
}
function removeMatchingPair(myEvent:TimerEvent) {
removeChild(firstCard); // setting visible to false wasn't working correctly on
// one tester's pc, the cards were still clickable and visible,
// so hopefully removeChild will work better.
removeChild(secondCard);
firstCard = null;
secondCard = null;
pairsLeftToMatch--;
trace("pairsLeftToMatch: " + pairsLeftToMatch);
if (pairsLeftToMatch <= 0)
{
trace("game over");
score += pointsForGameOver;
/* instead of just saying root.gotoAndPlay("game_over"), the Flash compiler now
requires you to strict type it to "MovieClip(root)", after all, "root" doesn't
necesssarily have to be a movie clip -- it can also be a sprite:
*/
MovieClip(root).gotoAndPlay("game_over");
}
}
public function playSound(soundObject:Object) {
var channel:SoundChannel = soundObject.play();
}
} // end of class As3_match_cards
} // end of package
trace("now in frame 1 of main timeline...");
stop();
// sound defaults to on:
soundOnOff_mc.soundOff_mc.visible = false;
soundOnOff_mc.soundOn_mc.visible = true;
soundOnOff_mc.mouseEnabled = true;
soundOnOff_mc.buttonMode = true;
// add event listener for sound on/off button being clicked on:
soundOnOff_mc.addEventListener(MouseEvent.CLICK, toggleSound);
// set the sound to the opposite setting:
function toggleSound(myEvent:MouseEvent) {
trace("now in toggleSound");
var sTransform:SoundTransform = new SoundTransform(1,0);
// if sound is on, turn it off:
if (soundOnOff_mc.soundOn_mc.visible == true)
{ soundOnOff_mc.soundOn_mc.visible = false;
soundOnOff_mc.soundOff_mc.visible = true;
sTransform.volume = 0;
SoundMixer.soundTransform = sTransform;
}
// if sound is off, turn it on:
else
{ soundOnOff_mc.soundOn_mc.visible = true;
soundOnOff_mc.soundOff_mc.visible = false;
sTransform.volume = 1;
SoundMixer.soundTransform = sTransform;
}
} // end of toggleSound function
score_txt.visible = false;
start_btn.visible = true;
playAgain_btn.visible = false;
start_btn.addEventListener(MouseEvent.CLICK, startGame);
function startGame(myEvent:MouseEvent) {
trace("now in startGame");
MovieClip(root).gotoAndStop("game_play");
}
trace("now in frame 10 of main timeline");
score_txt.visible = true;
start_btn.visible = false;
playAgain_btn.visible = false;
stop();
start_btn.visible = false; playAgain_btn.visible = true;
stop();
playAgain_btn.addEventListener(MouseEvent.CLICK, playAgainFunction);
function playAgainFunction(myEvent:MouseEvent) {
trace("now in playAgainFunction");
removeEventListener(MouseEvent.CLICK, playAgainFunction);
MovieClip(root).gotoAndStop("game_play");
}