MoleMash with Hall of Fame

Goal:

In this lesson, you will:

  • Learn how to use timers in your apps
  • Learn how to pick a random number
  • Use image sprites
  • Use procedures
  • Learn about databases

Step 0: Learn about Databases

Variables are great for storing information while your user is using your app, but what if you wanted to store information between the times when your user opens and closes her app? You can do this with a database. Databases can store information for later use, even when the app is closed! You can think of databases as a place to store information you can recall later. Here are some examples of databases you may use every day:

  • Contact list – you store your friend’s phone numbers so you can use them later
  • Messaging app – most messaging apps automatically store old messages so you can reread them later
  • Notebook – you write things down and read them later

In App Inventor, the component TinyDB allows you to save data on your user’s phone that will be there each time she logs into your app. It is important to know that TinyDB only allows you to store data locally. This means that two users cannot share data with the same TinyDB. When a user stores data into TinyDB, it will only be available on her phone, and no one else’s.

To use TinyDB, drag it onto your screen in the designer side of App Inventor. You can find it under the storage menu. It will appear as a non visible component and will look like this:

TinyDB

You can talk to your TinyDB by making calls to it. When you make a call, you can store things and get things from it. The way you store data in TinyDB is by giving it a tag. The tag is a name that you will use to retrieve the data. It is a lot like a variable name. If you use the same tag name to store data twice, the database will overwrite, or erase, the old data with the new data. This can be useful if you need to update what’s in your database but you should be careful never to repeat tag names otherwise! Here’s a few examples of how to make calls to TinyDB:

TinyDB store global fruits

The first block shows how to store values in TinyDB. In this case we stored our fruits list from earlier with the tag “Food”. The second block shows how to retrieve the fruits list from the database. The tag needs to be typed exactly as it was when the data was stored, including all capital letters.

To better understand this, let’s walk through an example. Let’s say you needed to store three things in a database for later use. One is our Fruits lists from the last section, one of them is your age, and the other is a list of your favorite things to do. You make three to calls to the database like this:

TinyDB store global fruits
Tiny DB my age
TinyDB store favorites list

You now have three entries in you database, and this what they look like:

Tag Name: “Food”

Data:

  • “Apples” (index = 1)
  • “Bananas” (index =2)
  • “Oranges” (index = 3)

Tag Name: “My Age”

Data:

  • 16

Tag Name: “Favorite”

Data:

  • “Learn how to Code” (index = 1)
  • “Visit Family” (index = 2)
  • “Listen to Music” (index =3)

Now, when you want to retrieve your favorite things to do, so you make a call like this:

TinyDB favorites value not tagged

When you use this block you will get “Learn how to Code Visit Family Listen to Music”. Now let’s say you want to retrieve your age, so you make a call like this:

TinyDB my age value tag if not there

When you use this block you just get a blank string: “ ”. This is because the tag “myage” does not exist in your database! However, the tag “MyAge” does exists. Since your database did not recognize the tag, it defaulted to show you the block next to “valueIfTagNotThere”, which is a blank string. You can make this string say anything you want. You can even make it be an error message to your user.

If you create an app with multiple screens (like your slideshow app), components and variables will not be able to talk to each other between each screen. You will need to use a TinyDB in order to transfer information from one screen of your app to another. Visit this page for more information: MIT Screens.

Step 1: Basic Design

In this game, a mole pops up at random positions on a playing field, and the player scores points by hitting the mole before it jumps away.

You will need to download this picture of a mole and save it on your computer.

The first components

You will need a few components to start:

  • A Canvas named “MyCanvas”. This is the area where the mole moves.
  • A Label named “ScoreLabel” that shows the score, i.e., the number of times the player has hit the mole.
  • A Button named “ResetButton”.

Drag these components from the Palette onto the Viewer and assign their names. Put MyCanvas on top and set its dimensions to 300 pixels wide by 300 pixels high. Set the Text of ScoreLabel to “Score: —“. Set the Text of ResetButton to “Reset”. Also add a Sound component and name it “Noise”. You’ll use Noise to make the phone vibrate when the mole is hit.

Timers and the Clock component

You need to arrange for the mole to jump periodically, and you’ll do this with the aid of a Clock component. The Clock component provides various operations dealing with time, like telling you what the date is. Here, you’ll use the component as a timer that fires at regular internals. The firing interval is determined by the Clock ‘s TimerInterval property. Drag out a Clock component; it will go into the non-visible components area. Name it “MoleTimer”. Set its TimeInterval to 500 milliseconds to make the mole move every half second. Make sure that TimerEnabled is checked.

Adding an Image Sprite

To add the moving mole we’ll use a sprite.

Sprites are images that can move on the screen within a Canvas. Each sprite has a Speed and a Heading, and also an Interval that determines how often the sprite moves at its designated speed. Sprites can also detect when they are touched. In MoleMash, the mole has a speed zero, so it won’t move by itself. Instead, you’ll be setting the mole’s position each time the timer fires. Drag an ImageSprite component onto the Viewer. You’ll find this component in the Drawing and Animation category of the Palette. Place it within MyCanvas area. Set these properties for the Mole sprite:

  • Picture: Use mole.png, which you downloaded to your computer at the beginning of this tutorial.
  • Enabled: checked
  • Interval: 500 (The interval doesn’t matter here, because the mole’s speed is zero: it’s not moving by itself.)
  • Heading: 0 The heading doesn’t matter here either, because the speed is 0.
  • Speed: 0.0
  • Visible: checked
  • Width: Automatic
  • Height: Automatic

You should see the x and y properties already filled in. They were determined by where you placed the mole when you dragged it onto MyCanvas. Go ahead and drag the mole some more. You should see x and y change. You should also see the mole on your connected phone, and the mole moving around on the phone as you drag it around in the Designer. You’ve now specified all the components. The Designer should look like this. Notice how Mole is indented under MyCanvas in the component structure list, indicating that the sprite is a sub-component of the canvas.

molemashdesigner

Excellent!  We are now ready to move onto the Blocks.

Step 2: Basic Building Blocks

Component Behavior and Event Handlers

Now you’ll specify the component behavior. This introduces some new App Inventor ideas. The first is the idea of a procedure. For an overview and explanation of procedures, check out the Procedures page.

A procedure is a sequence of statements that you can refer to all at once as single command. If you have a sequence that you need to use more than once in a program, you can define that as a procedure, and then you don’t have to repeat the sequence each time you use it. Procedures in App Inventor can take arguments and return values. This tutorial covers only the simplest case: procedures that take no arguments and return no values.

Define Procedures

Define two procedures:

  • MoveMole moves the Mole sprite to a new random position on the canvas.
  • UpdateScore shows the score, by changing the text of the ScoreLabel

Start with MoveMole:

  • In the Blocks Editor, under Built-In, open the Procedures drawer. Drag out a to procedure block and change the label “procedure” to “MoveMole”.
    Note: There are two similar blocks: procedure then do and procedure then resu;t. Here you should use procedure then do.

    The to MoveMole block has a slot labeled “do”. That’s where you put the statements for the procedure. In this case there will be two statements: one to set the mole’s x position and one to set its y position. In each case, you’ll set the position to be a random fraction, between 0 and 1, of the difference between the size of the canvas and the size of the mole. You create that value using blocks for random fraction and multiplication and subtraction. You can find these in the Math drawer.

  • Build the MoveMole procedure. The completed definition should look like this:
    movemole

MoveMole does not take any arguments so you don’t have to use the mutator function of the procedure block. Observe how the blocks connect together: the first statement uses the Mole.X set block to set mole’s horizontal position. The value plugged into the block’s socket is the result of multiplying:

  1. The result of the call random fraction block, which a value between 0 and 1
  2. The result of subtracting the mole’s width from the canvas width

The vertical position is handled similarly.

With MoveMole done, the next step is to define a variable called score to hold the score (number of hits) and give it initial value 0. Also define a procedure UpdateScore that shows the score in ScoreLabel. The actual contents to be shown in ScoreLabel will be the text “Score: ” joined to the value of score.

  • To create the “Score: ” part of the label, drag out a text block from the Text drawer. Change the block to read “Score: ” rather than ” “.
  • Use a join block to attach this to a block that gives the value of the score variable. You can find the join block in the Text drawer.

Here’s how score and UpdateScore should look:
updatescore

Add a Timer

The next step is to make the mole keep moving. Here’s where you’ll use MoleTimer. Clock components have an event handler called when … Timer that triggers repeatedly at a rate determined by the TimerInterval.

Set up MoleTimer to call MoveMole each time the timer fires, by building the event handler like this:
molemashtimereventhandler

Add a Mole Touch Handler

The program should increment the score each time the mole is touched. Sprites, like canvases, respond to touch events. So create a touch event handler for Mole that:

  1. Increments the score.
  2. Calls UpdateScore to show the new score.
  3. Makes the phone vibrate for 1/10 second (100 milliseconds).
  4. Calls MoveMole so that the mole moves right away, rather than waiting for the timer.

Here’s what this looks like in blocks. Go ahead and assemble the when Mole.Touched blocks as shown.

molemashtoucheventhandler

Here’s a tip: You can use typeblocking: typing to quickly create blocks.

  • To create a value block containing 100, just type 100 and press return.
  • To create a MoveMole block, just type MoveMole and select the block you want from the list

Reset the Score

One final detail is resetting the score. That’s simply a matter of making the ResetButton change the score to 0 and calling UpdateScore.

Step 3: High Score

At this point, you have a functioning game — way to go!  Next, we’ll modify our game to include a High Score for players to beat.

To do this, we’ll use a TinyDB component.  Remember that a TinyDB component is a database that lets us store data between each use of the app — so if the user closes the app and comes back later, the information we put in the database will still be there.

Components

On the Design tab, drag a TinyDB component into your app.  It will show up below the screen as a “Non-visible component.”

You will also need another label.  Draw another Label component in and name it “HighScoreLabel”.  Put “High score: 0” in the Text property of this label.

Your design should look something like this:
screen-shot-2017-02-01-at-10-09-06-am

Now we’re ready for blocks.

Build

The basic logic we want to follow goes like this:

  • When the player is done playing (ie, they click the “Reset” button),
  • If their score is greater than the high score,
  • Update the high score in the database and update the high score on the screen
  • Then reset the score (just like we’ve been doing)

We’ll need to build a few things to make this happen.

To do this, we need some more things to happen when the Reset button is clicked.  Find your “when Reset.clicked” block and add an “if” block from the control section:
screen-shot-2017-02-01-at-10-12-02-am

We are checking if our score is greater than the high score, so we need to compare the two values:
Screen Shot 2017-02-01 at 10.15.47 AM.png

If our score is greater than the high score, then what?  Then we need to update the high score in the database and update the high score on the screen.
screen-shot-2017-02-01-at-10-19-33-am

This looks great!  We’ve built the logic we planned out.

There’s one more trick to make this work — we need to make sure our app is prepared for a tricky situation.  Right now, when a player opens our app and hasn’t pressed the Reset button, they’ll see a high score of zero, no matter what!  To fix this, we need to add some behavior that controls what happens when the screen is very first initialized:
screen-shot-2017-02-01-at-10-21-15-am

That’s it!  Test it out — does it work?  If so, time to whack some moles!  If not, put on your best problem solving hat and get to tinkering!

Congrats!

You have a fabulous new game app that you made yourself — that’s awesome!

What’s next?

Credits

This tutorial is a melding of the following resources:

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s