CPSC 110-08: Computing on Mobile Phones
Spring 2011

Memory Game App

In this tutorial we will build a simple game that tests the user's ability to remember a sequence of button (or ball) flashes. For this simple version, each ball flash will be associated with a musical note. So the user will be able both to see the ball flash and hear its note.

Acknowledgment

We thank Liz Looney of the Google App Inventor development team for showing us the control logic used in this animation -- i.e., the idea of using a timer to break the animation into frames during which a ball is either highlighted (black) or not (original color).

How the Game Works

The user interface for this app is four colored balls arranged as shown here plus two buttons and a label. The buttons control the progress of the game. The label reports the user's score.

When the user presses the "Play" button, the app will flash a random sequence of colored balls-- one ball in the first "round", two in the second, and so forth. After the balls are flashed, the user is asked to "repeat the sequence." The app is then put in "interactive mode" and the user clicks on the balls trying to match the random sequence. If successful, the game advances to the next round.

More flashes are added to the sequence unitlh the user is unable to repeat the sequence correctly.

Global Variables

This app uses the following global variables:

Event Handlers

The app has four types of event handlers. The first is the ClockFrame timer, which controls the animation. It is used in both interactive and non-interactive mode. In interactive mode it handles one click on a ball and in non-interactive mode it handles one flash of a ball.

Note that it uses procedures to handle the action that takes place during each of the modes. This is a good example of abstraction and modularity.

The handler for the play button starts a new round of the game. It increases the round number, generates a random sequence, displays the first frame in the sequence of flashes, and starts the ClockFrame timer. It uses the PlayOneFrame procedure to handle the details of what happens during one frame of the animation. Note that this is the same procedure that is called by the ClockFrame handler.

There are four handlers for ball touches but they all do the same exact thing. They set the CurBallTouched variable to their unique number, they toggle the frameToggle and they call ProcessBallTouched to handle the details of the action that occurs when a ball is clicked. Note that this is the same procedure that is called by the ClockFrame timer.

As you can see, both the play button and ball touched events use the same design pattern to control the animation -- the flashing of the balls. Then perform one frame of action and they start the ClockFrame timer, which controls the remaining frames.

The handler for the reset button simply reinitializes the state of the game.

Among other tasks this requires:

  • Resetting the round to 0.
  • Clearing the sequence
  • Updating the labels and buttons.

Procedures and Functions

This app uses a number of procedures. We show only the ones that figure prominently in the app's control logic.


The of MakeTheSeuqence procedure uses a simple while looop to create a random sequence of ball numbers, 1 through 4. The length of the sequence is controlled by the theRound argument.

The theRound argument will always be equal to the Round global variable. But using the argument here is an example of good procedure design. Well designed procedures should be modular and self-contained. Ideally, you shouldn't have to look outside the procedure block to understand what it does. By using the local argument here, we can see clearly that it is used to control the loop and the length of the sequence.


The of HighlightOneBall procedure simply turns the selected ball, indicated by the BallIndex argument, to black. It uses a standard if...elseif control structure.


The of PlayOneFrame procedure controls one frame of the animation in non-interactive mode, highlighting one ball every other time it is called, depending on the frameToggle variable. Note how the frameToggle's value is toggled (set from false to true or vice versa) at the end of the procedure.

The ball to be highlighted is selected from the Sequence as indicated by the SequenceIndex.

Note that it performs the highlighting only when frameToggle is false. When frameToggle is true, it unhighlights all the balls.

In addition to being called when the play button is clicked, this procedure is called repeatedly by the ClockFrame timer. Thus, every half second, it either highlight or unhighlights a ball, thereby controlling the animation.

When the SequenceIndex exceeds the length of the Sequence, this means the entire sequence has been displayed. In that case the timer is disabled and the game is put in interactive mode -- it is now the user's turn to match the sequence.


The ProcessBallClick procedure has the same basic structure as the PlayOneFrame procedure. When the frameToggle is true, it unhighlights the balls and disables the ClockFrame timer, thereby waiting for the user to click another ball, which will enable the timer.

When the frameToggle is false -- thus every other time the method is called -- it will hightlight the ball that was clicked and enable the timer. The ball will remain highlighted for as long as the next timer interval.

If the user clicked on the ball that matches the current ball in the Sequence, as determined by SequenceIndex, then the game continues. If the user's click does not match the sequence, the game is over.


The ProcessGameOver procedure resets the app to enable the user to try again. This means enabling and relabeling some of the buttons.

Test Your Memory

If you'd like to use the app to test your memory, here's the QR code:

qrcode

Download Source

Click here to download the source code and use it for the following exercise.

In-class Exercises, and Homework

  1. Adding Sound: Download the zip file and incorporate sound into the app so that each time a ball is clicked, a distictive sound will be played. The sounds should be associated 1-to-1 with the balls, the same ball always gets the same sound.
    Hint: Use a list to store the names of sound resources -- e.g., individual notes -- and then for each ball, select its associated sound from the list and assign it as the Sound component's Source property.

    Trick: Liz Looney at Google uses the following trick to initialize the sound component so that sounds play correctly the first time they are played.

  2. Psychology Question: Does one perform better on this memory task with sound included??