Flash Tutorial Links:
Play Games: HTML5 Tutorials:

How To Make A Memory Game

There is seldom a game where you can enjoy playing from 6 years old to adulthood. This is one them.

Memory Games

One of the most popular games of all time, a game that suits the young or old! There is usually a spread of cards , with multiple sets of two same design, and you have a number of tries to open up any two cards at a time, hoping they match. The challenge is to match all cards with the least number of tries.

Download the Game Files

The files you need to create this game can be downloaded from here.

Part 1

import flash.display.*;
import flash.events.*;
import flash.ui.*;

public class Memory extends MovieClip
{
    private var score, life:Number;
    private var doLoseLife, gotoWin, gotoLose:Boolean;
    private var firstCard, secondCard:Card;
    private var cardValues, cards:Array;
    
    public function Memory()
    {
        
    }

The 3 standard packages are imported. You will almost always need display and events. As for ui, it'll be useful to import it in too.

The following variables will be used for the game. score keeps track of the score for the player.

life is a variable which tracks how many times a player gets to flip open the cards to find matches.

doLoseLife is a variable that will track if the player's life should be decreased after he opens two cards, but they do not match.

firstCard stores the reference to the first card that has been flipped, while secondCard stores the reference to the second card that has been flipped.

cardValues is an array that stores the value of the cards which we will denote with strings of "card1", "card2" and so on. Later on, we will be shuffling these values to create a sense of randomness. cards is an array that refers to the actual movieclips of cards the player will interact with.

gotoWin and gotoLose are standard boolean variables you'll see throughout the tutorials. Once they are set to true, the game jumps to the respective Win or Lose frames.

Part 2

    //All Start Functions
    public function startMenu()
    {
        stop();
        btnStartGame.addEventListener(MouseEvent.CLICK, gotoStartGame);
        btnHowToPlay.addEventListener(MouseEvent.CLICK, gotoHowToPlay);
    }
    
    public function startHowToPlay()
    {
        btnBack.addEventListener(MouseEvent.CLICK, gotoMenu);
    }
    
    public function startWin()
    {
        btnBack.addEventListener(MouseEvent.CLICK, gotoMenu);
    }
    
    public function startLose()
    {
        btnBack.addEventListener(MouseEvent.CLICK, gotoMenu);
    }

Take a look at the ActionScript embedded in the different frames in the FLA file. You will see that in the menu labelled frame, it has a single function call to startMenu. Likewise, the win labelled frame will call startWin.

All the functions here handle those calls. We often refrain from writing codes in the FLA file so that everything can be seen in the AS file, and it helps tremendously in debugging your codes.

Basically, the function calls here only set up the codes for the buttons in that frame to make them function.

Part 3

    public function startGame()
    {			
        score = 0;
        life = 10;
        doLoseLife = false;
        gotoWin = false;
        gotoLose = false;
        firstCard = null;
        secondCard = null;
        cards = new Array();
        
        setupGame();
        
        //Shuffle
        cardValues = new Array("card1","card1","card2","card2","card3","card3","card4",
                               "card4","card5","card5","card6","card6","card7","card7");
        for (var i=0; i < 100; i++)
        {
            var swap1 = Math.floor(Math.random()*14);
            var swap2 = Math.floor(Math.random()*14);
        
            var tempValue = cardValues[swap1];
            cardValues[swap1] = cardValues[swap2];
            cardValues[swap2] = tempValue;	
        }
        
        //Deal
        for (var i=0; i < 14; i++)
        {
            cards[i].hiddenValue = cardValues[i];
            cards[i].addEventListener(MouseEvent.CLICK, flipCard);
        }
        
        addEventListener(Event.ENTER_FRAME,update);
        
        stage.focus = this;
    }

startGame is called in the frame labelled game.

This will be the heaviest start-kind-of-function as you can see. Basically, the role of this function is to kick start all the necessary variables and states in the game. You can see that we set both the score to 0, because, well, at the start of the game, you should start with 0 score. life is similarly set to 10 to give the player 10 tries.

firstCard and secondCard are set to null because the player has yet to flip open any cards.

setupGame is a function that when called, looks at what movieclips you have on stage, and pushes them into the cards array if they are of the type Card.

cardValues is initialised with all matching pairs of strings from "card1" to "card7" because we're starting off with 14 cards. The loop then iterates through this array, and randomly swap the values of 2 points in the array. We do this random swapping 100 times to simulate a shuffling of the deck.

After that, we assign each cardValue to each element of the cards array. When cards[i].hiddenValue = cardValues[i] does is to create a new dynamic variable in the cards[i] object, and assign the value stored in cardValues[i] into it. Each cards[i] movieclip then gets assigned an event listener to listen out to when a player clicks on the card.

The game loop is created in the game by adding an event listener that listens to the ENTER_FRAME event. So, if you set the fps of the game to 30, this update function will run 30 times a second (assuming the computer is able to handle the complexity of each game loop).

What "stage.focus = this" does is to set the focus back into the game. When you clicked on a button to get from the Menu frame into the game, the focus is actually given to the button. Hence, if the game is played using the keys on the keyboard, they will not work unless you click on the game screen again to give it focus. You can try commenting this off to see what I mean.

Part 4

    //All Goto Functions
    private function gotoStartGame(evt:MouseEvent)
    {
        btnStartGame.removeEventListener(MouseEvent.CLICK, gotoStartGame);
        btnHowToPlay.removeEventListener(MouseEvent.CLICK, gotoHowToPlay);
        gotoAndStop("game");
    }
    
    private function gotoHowToPlay(evt:MouseEvent)
    {
        btnStartGame.removeEventListener(MouseEvent.CLICK, gotoStartGame);
        btnHowToPlay.removeEventListener(MouseEvent.CLICK, gotoHowToPlay);
        gotoAndStop("howtoplay");
    }
    
    private function gotoMenu(evt:MouseEvent)
    {
        btnBack.removeEventListener(MouseEvent.CLICK, gotoMenu);
        gotoAndStop("menu");
    }

These functions handle the interaction when the player clicks on the buttons in the menu, how to play section, etc.

Before it jumps to the right frame, it removes the event listener from the button first. This is just good programming practice.

Part 5

    private function flipCard(evt:MouseEvent)
    {
        if (firstCard == null)
        {
            firstCard = evt.currentTarget as Card;
            firstCard.gotoAndStop(firstCard.hiddenValue);
        }
        else if (secondCard == null)
        {
            if (firstCard == evt.currentTarget as Card)
                return;
                
            secondCard = evt.currentTarget as Card;
            secondCard.gotoAndStop(secondCard.hiddenValue);
            
            doLoseLife = true;
        }
        else
        {
            //this is the third card clicked,
            //means the cards clicked do not match
            //reset them
            firstCard.gotoAndStop("back");
            secondCard.gotoAndStop("back");
            secondCard = null;
            
            firstCard = evt.currentTarget as Card;
            firstCard.gotoAndStop(firstCard.hiddenValue);
        }
    }

The flipCard function is called when the player clicks on any of the cards. The game first checks if firstCard is null. It started off as null, so if it is still null, it means that this is the first card that the player clicked on. In that case, firstCard stores the reference to the card that was clicked, and the movieclip jumps to that particular value of the card so that the player can see what card he opened.

Otherwise, if firstCard is not null, we then check if secondCard is null. Again, secondCard started off as being null, so if it is still null, it means that this is the second card that was clicked. We make sure that the player did not click on the already opened card by if (firstCard == evt.currentTarget as Card). If it is, we simply return and not do anything.

If not, we will assign this new card to secondCard. We set doLoseLife to be true now because in the event that these 2 cards do not match, the player will lose a life.

The else portion here handles the situation when a third card is clicked. The only time when a third card can be clicked is if the first two do not match. In that case, we flip both cards back to the "back" frame, set secondCard to null, and conveniently set firstCard to point to this new card.

Part 6

    public function update(evt:Event)
    {
        handleUserInput();
        handleGameLogic();
        handleDraw();
        
        if (gotoWin)
            triggerGoToWin(); 
        if (gotoLose)
        	triggerGoToLose();
    }

This is how the game loop will look like. I've further broken down what the game loop should be doing by creating 3 other functions.

handleUserInput will take care of the player's inputs, be it mouse, or keyboard.

handleGameLogic will almost always be the biggest function. It handles everything from updating the player's movements, bullets' movements if any, to even more fanciful stuff like calculating advanced enemy AI.

handleDraw does little, but it is important in presenting the game states to the player by updating the UI. For example, if the player gains score, the Score textfield will be updated here to reflect the correct score.

After these 3 functions have executed, the gotoWin variable is checked to see if it is true. If so, the triggerGoToWin function will be called, and the game will end thereafter.

Likewise, gotoLose hadles the situation when the player exhausts all his lives but fail to get matches for all cards.

Part 7

    private function handleUserInput()
    {
        //All user input handled in placeSymbol function
    }

Usually, the handleUserInput function will have codes that will make the game react to the players' keyboard inputs, mouse inputs, etc.

Part 8

    private function handleGameLogic()
    {
        if (firstCard != null && secondCard != null)
        {
            //check if same
            if (firstCard.hiddenValue == secondCard.hiddenValue)
            {
                removeChild(firstCard);
                removeChild(secondCard);
                
                score += 10;
                
                firstCard = null;
                secondCard = null;
            }
            else if (doLoseLife)
            {
                life--; //considered as one attempt once both cards are flipped
                doLoseLife = false;
            }
            
            
        }
        
        if (score >= 70)
        {
            gotoWin = true;
        }
        if (life <= 0)
        {
            gotoLose = true;
        }
    }

Inside the handleGameLogic function which runs once every frame per second, we check the hiddenValues of the firstCard and the secondCard once they are proven to be non-null. If they are equal, it means that they match, and hence, we remove both cards, add 10 to the player's score, and set both firstCard and secondCard again to null.

Otherwise, once doLoseLife is set to be true, it means both cards are already opened, and we will deduct the player's life by 1.

If score is greater than or equal to 70, the game would have ended, and gotoWin is set to be true. If life has dropped to zero, gotoLose is set to be true.

Download the Game Files

The files you need to create this game can be downloaded from here.




How To Play

Objective:Open up two cards. If they match, you score, else you lose a life.

Controls: Click on the card you wish to open.


Content on this page requires a newer version of Adobe Flash Player.

Get Adobe Flash player

Flash Resources
Preloader FPS Display Sounds & Music
Keycodes Name Generator
Game Development Resources
Sprite Sheets


Posted by Tarso

on 2014-11-26 01:54:59

hey, I made a memory game from another tutorial and it all works great (the cards are all set up in one movie clip with all possible cards in it)

what I wanted to do, is to show the cards to the use for a couple of seconds before turning them over to start the game, how do I do that??


Posted by Francis Infante

on 2014-03-27 00:36:17

I just want to use this for my major subject. I just wanted to make a new one by analyzing your codes and all the content of your game. Thank you so much. God Bless you!


Posted by Izham

on 2014-02-11 16:54:58

@Joseph > thank's so much....
i'll try build new level, and learn more about Flash AS3


Posted by Joseph

on 2014-02-09 23:16:19

@Izham: You can try adding more frames with more cards. I created a version which you can get from the Downloads page : http://www.makeflashgames.com/tutorialsplus/tutorial-memory_files/fileDownload.php

Read through it and hope you understand. For the new frames that you add, do note that you have to give it a unique movie clip name, otherwise, Flash will be confused that these are the same cards that are removed in the previous levels.

Also, I've switched to using Flash CC, so hope you can open the new fla file.


Posted by Izham

on 2014-01-25 21:15:20

how to make, another level. when we win, we will go to next level and more difficult....??

please send answer to my email ..., thx before..,
i love this tutorial.. :)


Posted by Joseph

on 2013-12-14 17:45:54

@Zizou, Zied: Gotta need more info than that. :)


Posted by Zizou

on 2013-12-10 23:59:14

haw can i put other button in this game it dosen't work
answer me thnx :)


Posted by zied

on 2013-12-10 23:57:42

i need to put other button in the menu and dosnt work
answer me thnx :)


Posted by Arman

on 2013-11-23 02:46:34

Wow I never knew that it is possible to create dynamic variables of an object in ActionScript, as what you demonstrated above. Thanks.


Posted by Joseph

on 2013-11-03 22:26:53

Thousand apologies. Fixed!


Posted by John

on 2013-10-17 15:21:13

Why is the tutorial showing how to make a tic tac toe game instead of explaining the matching game code?


Posted by Joseph

on 2013-05-16 00:12:42

Sorry. Some problem with the hyperlink... Let me fix it.


Posted by Jason

on 2013-05-14 11:27:11

hi there, can you put up the codes and file for How To Make A Breakout Game


Flash Tutorial Links:
Play Games: HTML5 Tutorials:
gaming tools download on app store now!
Home | About Us | Contact Us
Powered by Make Flash Games. All Rights Reserved.
By Joseph Tan