Flash Tutorial Links:
Play Games: HTML5 Tutorials:

How To Make A Simon Game

Memory and music never tasted so good before ...

History of Simon

Ralph H. Baer invented this electronic game in the 1978, and it instantly became a hit. 4 lights light up in sequence, and tests your superb memory to remember it. Replay the sequence without any error, or LOSE!

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.*;
import flash.media.*;

public class Simon extends MovieClip
{
    private var score, life:Number;
    private var sndEffx1, sndEffx2, sndEffx3, sndEffx4:Sound;
    private var phase:String;
    private var delay, playCounter, playerInput:Number;
    private var checkAnswer, gotoWin, gotoLose:Boolean;
    private var answers:Array;

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.

sndEffx1 to sndEffx4 will be used to play a different sound for each of the four lights. These sounds are essential in helping the player differentiate the different lights and to remember the sequence.

phase denotes the different states of the game. A value of "player" indicates that it is currently the player's turn to guess the sequence. A value of "computer" indicates that the computer is generating a new note to add to the sequence, and playing it out once for the player to listen and remember.

delay is a variable which we'll use later on to add some sort of a pause in the gameplay.

playCounter, playerInput and checkAnswer are internal variables that should make sense later when you encounter them.

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.

answers store the long list of the sequence of the lights that will be checked against the player's inputs.

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;
        
        gotoWin = false;
        gotoLose = false;
        

        sndEffx1 = new SoundEffx1();
        sndEffx2 = new SoundEffx2();
        sndEffx3 = new SoundEffx3();
        sndEffx4 = new SoundEffx4();


        phase = "computer";
        answers = new Array();
        
        checkAnswer = false;
        delay = 20;
        playCounter = 0;
        playerInput = 0;
        
        generateNewNote();
        



        mcNote1.buttonMode = true;
        mcNote2.buttonMode = true;
        mcNote3.buttonMode = true;
        mcNote4.buttonMode = true;

        
        addEventListener(Event.ENTER_FRAME,update);
        stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDownHandler);
        stage.addEventListener(KeyboardEvent.KEY_UP,keyUpHandler);
        


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 the scoreto 0, because, well, at the start of the game, the player should start with 0 score.

sndEffx1 to sndEffx4 are instantiated with the 4 different sounds included in the FLA file (please open up the FLA to check). The constructor names SoundEffx1 to SoundEffx4 are already set in the linkage portion of the sound files. Right click on the sound files in the library and select properties to verify that.

phase is set to computer because the computer should generate the first note for the player to remember.

answers is instantiated to an empty array right at the start because the computer has yet to generate a new note to remember. As and when the game progresses and generates a new note for the player to remember, it will be pushed into this array.

The generateNewNote function basically randomizes a new number from 1 to 4, and push it into the answers array. You can see the implementation below.


Setting the buttonMode of the various movie clips mcNote1 to mcNote4 is just to change the pointed mouse cursor to a hand cursor when you mouse over them. This will help the player visualise his options better.


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 keyDownHandler(evt:KeyboardEvent)
    {
        
    }
    
    private function keyUpHandler(evt:KeyboardEvent)
    {
        
    }

The entire game is actually played with the mouse, so there's no need for any key handlers, up or down. I'm just leaving them here for consistency's sake because most of the other games have them.

If it bothers you, remove them.

Part 6

   public function update(evt:Event)
    {
        handleUserInput();
        handleGameLogic();
        handleDraw();
        
        //if (gotoWin)
        //	triggerGoToWin(); //Not possible to win in Simon
        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 gotoLose variable is checked to see if it is true. If so, the triggerGoToLose function will be called, and the game will end thereafter.

In this case, there is no win condition at all, because the computer will keep generating notes until the player's brains go kapuuuut from trying to remember so many things ^__^. I'm leaving the gotoWin codes here, albeit commented, so that you can get a sense of how a win state is implemented if need be. The other tutorials will use it.

Part 7

   private function handleUserInput()
    {
        if (phase == "player")
        {
            if (playerInput != 0)
            {
                if (playerInput != answers[playCounter])
                {
                    gotoLose = true;
                }
                else
                {
                    //Add score
                    score += 100;
                    
                    playCounter += 1;
                    playerInput = 0;
                    
                    if (playCounter == answers.length)
                    {
                        //player has guessed all answers
                        generateNewNote();
                        phase = "computer";
                        
                        mcNote1.removeEventListener(MouseEvent.CLICK,clickSound1);
                        mcNote2.removeEventListener(MouseEvent.CLICK,clickSound2);
                        mcNote3.removeEventListener(MouseEvent.CLICK,clickSound3);
                        mcNote4.removeEventListener(MouseEvent.CLICK,clickSound4);
                        
                        playCounter = 0;
                        delay = 60;
                    }
                }
            }
        }
    }

The handleUserInput function will take care of the user's interactions with the game. In this case, we first check if the phase is "player". If it isn't, it means that the computer is midway generating the notes, and the player's pressing on the lighted buttons will not be accepted.

When it is eventually the player's turn, phase will switch to "player", and we now check if the variable playerInput is anything but zero. Remember that it was instantiated as zero within startGame. It will only be set to a number other than zero when the player presses on any of the lighted buttons.

Just for the record, pressing on mcNote1 (green button) will set playerInput to a value of 1. Pressing on mcNote2 (red button) will set playerInput to a value of 2, and so on.

So, if the player pressed any of the buttons, we check playerInput to the current counter in the answers array. Since answers array stores the entire sequence of the buttons lighting up, how would we know which one to check against first? This is where playCounter comes into play (pun intended!). playCounter is previously set to 0 within startGame, so at the very first time of the player hitting any of the buttons to make his guess, his answer (which is playerInput) will be checked against the first element of answers (since playCounter is 0, and answers[0] means the first element).

If they are different, the gotoLose is immediately set to true, because this game, being so unforgiving, allows the player only 1 chance to get everything correct.

Otherwise, the player gains 100 points, the playCounter increases by 1, and playerInput is reset to 0 in wait for the player to press any one of the lighted buttons, mcNote1 to mcNote4.

If, however, the playCounter is equal to the length of answers, it means that the player has successfully answered the entire sequence he was made to remember, and the game will proceed on to the computer's phase, where a new note will be generated to add on to the sequence.

Part 8

    private function handleGameLogic()
    {
        if (phase == "computer")
        {
            if (playCounter == answers.length)
            {
                phase = "player";
                
                mcNote1.addEventListener(MouseEvent.CLICK,clickSound1);
                mcNote2.addEventListener(MouseEvent.CLICK,clickSound2);
                mcNote3.addEventListener(MouseEvent.CLICK,clickSound3);
                mcNote4.addEventListener(MouseEvent.CLICK,clickSound4);
                
                playCounter = 0;
            }
            else
            {
                if (delay <= 0)
                {
                    playSound(answers[playCounter]);
                    playCounter += 1;
                    delay = 20;
                }
                else
                {
                    delay -= 1;
                }
            }	
        }
    }

The handleGameLogic will handle how the computer plays out the musical notes for the player to remember. It first checks if the phase shows "computer". If it is "player", the game should not be interfering by displaying the answer again.

It will pass control over to the player when playCounter is equal to the length of answers. Since playCounter will start from 0, it will play out every single note associated with the value in answers.

This delay variable here is used to pause in between the musical notes played back to the player. Imagine if we don't have it, the game will quickly play out all the musical notes in succession. Pretty hard for the player to remember them. We check if the variable delay contains a number lesser than or equals to 0. If it is, it means to say that the game has already paused enough, and it is time to play back another note. The playSound function will take in the value stored in answers[playCounter] (which is either 1,2,3 or 4), and play out the corresponding note. Thereafter, we increase playCounter by 1 so that the next element in answers will be played, and set a delay of 20 frames per second.

Part 9

    private function handleDraw()
    {
        //Handle display
        txtScoreP1.text = String(score);
        
        if (phase == "computer")
            txtStatus.text = "Computer's Turn";
        else if (phase == "player")
            txtStatus.text = "Your Turn";
    }

Typically, we use the handleDraw function to update the UI displays. In this case, we update the text field that shows the score (txtScoreP1). Since score is a number data type, we need to cast it into a string by using String(score) before assigning it to the text field.

Depending on the current phase, the text field txtStatus will show the corresponding game status.

Part 10

    private function triggerGoToWin()
    {
        removeEventListener(Event.ENTER_FRAME, update);
        gotoAndStop("win");
    }
    
    private function triggerGoToLose()
    {
        removeEventListener(Event.ENTER_FRAME, update);
        gotoAndStop("lose");
    }

The two functions triggerGoToWin and triggerGoToLose are called whenever the respective win or lose states happen.

To prevent the game from continuing to run, we will remove the event listener to ENTER_FRAME, hence stopping the game loop.

Part 11

    //Misc Functions
    private function generateNewNote()
    {
        //generate a note in the sequence and 
        //add it into the sequence
        var newNote = Math.floor(Math.random()*4) + 1;
        answers.push(newNote);
    }
    
    private function clickSound1(evt:MouseEvent)
    {
        playSound(1);
        playerInput = 1;
        checkAnswer = true;
    }
    
    private function clickSound2(evt:MouseEvent)
    {
        playSound(2);
        playerInput = 2;
        checkAnswer = true;
    }
    
    private function clickSound3(evt:MouseEvent)
    {
        playSound(3);
        playerInput = 3;
        checkAnswer = true;
    }
    
    private function clickSound4(evt:MouseEvent)
    {
        playSound(4);
        playerInput = 4;
        checkAnswer = true;
    }
    
    private function playSound(note:Number)
    {
        this["sndEffx"+note].play();
        this["mcNote"+note].gotoAndPlay("on");
    }

In the generateNewNote function, we randomize a new number from 1 to 4. That number will then be pushed into the answers array, which will always store the correct sequence of music playback. A value of 1 here means that mcNote1 was lit up, and so on.

clickSound1 to clickSound4 basically plays the corresponding sound, and assigns a value to the variable playerInput. checkAnswer will also be set to true to alert the system that the player has made his guess, and that his input should be checked against the current sequence in the answers array.

The function playSound takes in a value from 1 to 4, and plays the corresponding sound file. Assuming that a value of 1 is used in this function, it will trigger this["sndEffx1"].play(), which essentially plays the sound file SoundEffx1. We also make the corresponding movieclip of the note light up by asking the movieclip to gotoAndPlay("on").

Download the Game Files

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

The Game

Now's the time to test your memory. Have fun playing!




How To Play

Objective: The 4 buttons will light up in sequence. Remember it, and click according to the sequence when prompted.

Controls: Click on the button.


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 srinivasa

on 2014-11-25 11:31:45

i like this tuoturial
i want starting to end script


Posted by lewis

on 2014-10-16 18:59:23

I got 8800


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