Explore MIT App Inventor - Sprites http://dev-explore.appinventor.mit.edu/tutorial-type/sprites en Mini Golf: Fling, TouchUp, TouchDown Gestures for App Inventor 2 http://dev-explore.appinventor.mit.edu/ai2/minigolf <div class="field field-name-body field-type-text-with-summary field-label-hidden view-mode-rss"><div class="field-items"><div class="field-item even" property="content:encoded"><p>This Mini Golf App demonstrates how to use the Fling, TouchUp, and TouchDown gestures for Sprites<br />Note that these event handlers are also available for the Canvas.</p> <p><img src="/sites/all/files/ai2tutorials/miniGolf/minigolfscreen.png" style="float: right;border:none" width="250" /></p> <p>To play this mini golf app, the player first positions his/her ball within the confines of the tee, and then flings the ball toward the hole. The ball will bounce off of the rectangular obstacle and the sides of the course. For each fling of the ball, the stroke count goes up by one. The total score is the number of strokes it takes to complete the entire course. </p> <p>This tutorial covers:</p> <ul><li>Using the <b>Sprite</b> component and the TouchUp, TouchDown, and Flung events</li> <li>Using a <b>Clock</b> component</li> <li>Dynamic Positioning of sprites on a canvas, based on the size of the screen</li> <li>Sprite Collisions</li> </ul><p>This tutorial assumes you are familiar with the basics of App Inventor-- using the Component Designer to build a user interface, and using the Blocks Editor to specify the app's behavior. If you are not familiar with the basics, try stepping through some of the <a href="http://appinventor.mit.edu/explore/ai2/tutorials.html">basic tutorials</a> before continuing.</p> <p><a href="/sites/all/files/ai2tutorials/miniGolf/MiniGolf_MIT.aia"><img src="/sites/all/files/tutorials/miniGolf/downloadSourcebutton.png" style="float: right; border:none" width="250" /></a><br /><br /><br /><br /></p> <hr /><h3>Part I: Start a new app and make a ball that responds to fling events</h3> <p>We'll build this app in stages, adding a little bit of the game at a time. Log into App Inventor and start a new project. Name it "MiniGolf". When the Design window opens notice that App Inventor automatically names the screen "Screen1", but you can set the Title of the screen, which will show up in the top bar of the app. Think of a title related to Mini Golf, or feel free to use the suggested title "Fling It Mini Golf", and type it into the Properties pane on the right side of the Designer.</p> <p>In the Screen Properties (shown in right-hand pane): Uncheck the checkbox labeled "Scrollable" so that the screen will not scroll when the app is running. Screens that are set to scroll do not have a height. We’ll need our screen to have a defined height in order to set up the golf course properly.</p> <p><strong>Add the following components in the Designer:</strong></p> <table cellpadding="0" cellspacing="0"><tbody><tr style="background-color: #EFEFEF; font-weight: bold;"><td> <p><strong>Component Type</strong></p> </td> <td> <p><strong>Palette Group</strong></p> </td> <td> <p><strong>What You'll Name It</strong></p> </td> <td> <p><strong>Purpose</strong></p> </td> <td> <p><strong>Properties</strong></p> </td> </tr><tr><td> <p>Canvas</p> </td> <td> <p>Basic</p> </td> <td> <p>Canvas1</p> </td> <td> <p>The canvas serves as the golf course</p> </td> <td> <p>Height: 300<br />Width: FillParent<br />BackgroundColor: Green (or whatever you like!)</p> </td> </tr><tr><td> <p>BallSprite</p> </td> <td> <p>Animation</p> </td> <td> <p>GolfBall</p> </td> <td> <p>This is the ball the player will fling to try to hit the Hole</p> </td> <td> <p>Radius = 10<br />Color: White (or your choice!)<br />Speed: 0<br />Interval: 1 (ms)</p> <p>Z = 2 (when sprites are overlapping, the one with the higher z will appear on top)</p> </td> </tr><tr><td> <p>BallSprite</p> </td> <td> <p>Animation</p> </td> <td> <p>Hole</p> </td> <td> <p>This will be the target for the GolfBall</p> </td> <td> <p>Radius = 15<br />Color: Black<br />Speed: 0</p> </td> </tr><tr><td> <p>Clock</p> </td> <td> <p>Basic</p> </td> <td> <p>Clock1</p> </td> <td> <p>The clock will fire continuously to control the movement of the ball</p> </td> <td> <p>Timer Always Fires</p> <p>Timer Enabled</p> <p>TimerInterval: 100</p> </td> </tr></tbody></table><p><strong>Open the Blocks Editor</strong></p> <p><strong>Program the behavior of the Ball:</strong></p> <p>First, use the <span class="eventblock">GolfBall.Flung</span> event handler to move the golf ball when it is flung. Notice how this event handler takes in 6 different arguments: </p> <ul><li><em>x</em>, the x position on the Canvas grid of the user's finger </li> <li><em>y</em>, the y position on the Canvas grid of the user's finger</li> <li><em>speed</em>, the speed of the user's flinging gesture</li> <li><em>heading</em>, the direction (in degrees) of the user's fling gesture</li> <li><em>xvel</em>, the speed in the x direction of the user's fling</li> <li><em>yvel</em>, the speed in the y direction of the user's fling</li> </ul><p>Essentially, you want to set the GolfBall sprite’s speed and heading to match the speed and heading of the player’s fling gesture. You may want to scale up the speed a little bit because the speed of the fling is a little slower than how a golf ball would move. You can play with this "scaling factor" to make the ball more or less responsive to a fling.</p> <p> <img src="/sites/all/files/ai2tutorials/miniGolf/golfBall.flung.png" /></p> <p><strong>Program the behavior of the clock:</strong></p> <p> Use timer event to slow ball down so it doesn’t bounce around forever.</p> <p>Each time the clock fires, it will reduce the speed of the ball slightly. Notice that if the ball is not moving then these blocks will do nothing. If you don’t have this then the ball will just bounce forever.</p> <p>You'll need to use the if mutator function to change the if block into an if-else block. For a summary of mutators, check out the <a href="http://appinventor.mit.edu/explore/ai2/support/concepts/mutators">Mutators page</a></p> <p><img src="/sites/all/files/ai2tutorials/miniGolf/clock1.timer.png" /></p> <p><strong>Program a new procedure called SetupNewHole:</strong></p> <p>This procedure will be called when a hole is scored and the ball has to be placed back at the starting point. Note that the <span class="callblock">Hole.MoveTo</span> block sets the hole up in a new random location for the next play.</p> <p><img src="/sites/all/files/ai2tutorials/miniGolf/setupNewHole.png" /></p> <p><strong>Program the Behavior of the Hole: </strong><span>When the ball collides with the hole, the ball disappears and resets at the bottom of the screen.</span></p> <p>Note: When you first drag out the <span class="eventblock">GolfBall.CollidedWith</span> event handler, the named parameter is called "other". Notice that the <span class="controlblock-ai2">if then</span> block tests to see if the object involved in the collision with the golf ball (<span class="variableblock">other</span>) is the black ball sprite representing the hole. You can't just put a text block with the word "Hole" in it, you must use the <span class="componentsetblock">component Hole</span><span> block, that can be found in the drawer for the Hole image sprite. Do not use a <span class="textblock-ai2">text block</span> here.</span></p> <p><img src="/sites/all/files/ai2tutorials/miniGolf/golfball.collidedwith.png" /></p> <pre class="ai-testing"><strong>Test this Behavior.</strong> Connect your device to AppInventor, or start the emulator to load your app. When you fling the ball it should move in the direction of your fling, with a speed similar to the strength of your fling. The ball should slow down as it moves, eventually stopping. When the ball hits the hole, the ball should reset at the bottom of the screen and the hole should move to a new random location.</pre><p> </p> <p><strong>Does your ball get stuck if it hits the edge? </strong></p> <p>This is easy to fix with the when <span class="eventblock">EdgeReached</span> event. Note that you can find the "edge" value block by using a <span class="variableblock">get</span> block and selecting "edge" from the dropdown.</p> <p><img src="/sites/all/files/ai2tutorials/miniGolf/golfBall.edgeReached.png" /></p> <p>Double check to make sure your code is right: fling the ball a few times and see that that ball now bounces off the edges of the course.</p> <h3>Part II: Keeping Score</h3> <p>Games are more fun if you have a way to see how you’re doing. Let’s add a stroke counter. In mini golf your score goes up as you take more strokes. The goal is to have the lowest score possible. Let’s show the player how many strokes she or he has taken on this hole. Let’s also show the number of strokes taken during the whole game.</p> <p> </p> <p>Go back to the Designer and set up the following components:</p> <p><a href="#" name="84f417a34cd2d904669a10a8f96b32bf41ae274b" id="84f417a34cd2d904669a10a8f96b32bf41ae274b"></a><a href="#" name="2" id="2"></a><br /></p><table cellpadding="0" cellspacing="0"><tbody><tr style="background-color: #EFEFEF; font-weight: bold;"><td> <p><strong>Component Type</strong></p> </td> <td> <p><strong>Palette Group</strong></p> </td> <td> <p><strong>What You’ll Name It</strong></p> </td> <td> <p><strong>Purpose</strong></p> </td> <td> <p><strong>Properties</strong></p> </td> </tr><tr><td> <p>Horizontal Arrangement</p> </td> <td> <p>Screen Arrangement</p> </td> <td> <p>HorizontalArrangement1</p> </td> <td> <p>Contains LabelScore and LabelStroke</p> </td> <td> <p>Place at top of screen</p> </td> </tr><tr><td> <p>Label1</p> </td> <td> <p>Basic</p> </td> <td> <p>LabelScore</p> </td> <td> <p>Displays the total stroke count for the entire game</p> </td> <td></td> </tr><tr><td> <p>Label2</p> </td> <td> <p>Basic</p> </td> <td> <p>LabelStroke</p> </td> <td> <p>Displays the stroke count for the hole the player is currently on</p> </td> <td></td> </tr></tbody></table><p>In the Blocks Editor, you can program updates to the Score and Stroke labels. First, set two new global variables called <span class="variableblock">StrokeCount</span> and <span class="variableblock">Score</span>, and set their initial values to 0.</p> <p><img src="/sites/all/files/ai2tutorials/miniGolf/scoreto0.png" /></p> <p>Then add the following blocks to the <span class="eventblock">GolfBall.Flung</span> event (red rectangle indicates new blocks):</p> <p><img src="/sites/all/files/ai2tutorials/miniGolf/golfball.flung_final.png" /></p> <p>Next add the following blocks to the Event that handles the ball hitting the hole:</p> <p><img src="/sites/all/files/ai2tutorials/miniGolf/golfball_collidewith.png" /></p> <pre class="ai-testing"><strong>Test the behavior.</strong> With these new changes, you should have a "Total Strokes" count and "This Hole" count at the top of the screen. When you fling the ball, the "This Hole" count  and "Total Strokes" count should both increase by one, and when you make the ball go into the hole the "This Hole" count should reset to 0.</pre><h3>Part III: Positioning Ball on Tee using TouchUp and TouchDown events</h3> <p>Ok, so now you’ve got a working game! Now let’s make it a little more interesting and fun. First we’ll add a Tee and let the player position the golf ball on the tee before they fling the ball.</p> <p><strong>Go back to the Designer and add three new image sprite components:</strong></p> <p><a href="#" name="f32e9ebd8bb0c367ac6b009ebba0af05e4eb1b4e" id="f32e9ebd8bb0c367ac6b009ebba0af05e4eb1b4e"></a><a href="#" name="1" id="1"></a><br /></p><table cellpadding="0" cellspacing="0"><tbody><tr style="background-color: #EFEFEF; font-weight: bold;"><td> <p><strong>Component Type</strong></p> </td> <td> <p><strong>Palette Group</strong></p> </td> <td> <p><strong>What You’ll Name It</strong></p> </td> <td> <p><strong>Purpose</strong></p> </td> <td> <p><strong>Properties</strong></p> </td> </tr><tr><td> <p>ImageSprite</p> </td> <td> <p>Animation</p> </td> <td> <p>Tee</p> </td> <td> <p>A rectangular area in which the player can position their ball before teeing off.</p> </td> <td> <p>Upload the Tee image (<a href="/sites/all/files/tutorials/miniGolf/tee_graphic.png">right click on this link</a>, or see below).</p> </td> </tr><tr><td> <p>ImageSprite</p> </td> <td> <p>Animation</p> </td> <td> <p>LeftSprite</p> </td> <td> <p>This is a left pointing arrow that the player will use to move the ball to the left on the tee</p> </td> <td> <p>Upload the left arrow graphic (<a href="/sites/all/files/tutorials/miniGolf/left_arrow.jpg">right click on this link</a></p> </td> </tr><tr><td> <p>ImageSprite</p> </td> <td> <p>Animation</p> </td> <td> <p>RightSprite</p> </td> <td> <p>This is a right pointing arrow that the player will use to move the ball to the left on the tee</p> </td> <td> <p>Upload the right arrow graphic (<a href="/sites/all/files/tutorials/miniGolf/right_arrow.jpg">right click on this link</a></p> </td> </tr></tbody></table><p><strong>Program the size of the canvas, and the placement of the ball and image sprites on the canvas:</strong></p> <p>First, program the setup of these components on the screen. It’s best to accommodate all different screen sizes by placing the sprites on the screen relative to the size of the screen. The blocks below show how to set up the screen <em>dynamically</em><span> so that everything fits the right way. We start off by making the canvas size based on the screen size, and then we place each sprite in relation to the width and height of the canvas. We'll make a procedure to do this for us. Try to understand all of these blocks before you move on.</span></p> <p><img src="/sites/all/files/ai2tutorials/miniGolf/preparescreen.png" /></p> <p><img src="/sites/all/files/ai2tutorials/miniGolf/golf_screen_init.png" /></p> <p><strong>Position the Golf Ball on the Tee using TouchUp and TouchDown on the Arrow sprites:</strong></p> <p>To handle this, first set up two global variables that are toggled each time an arrow is pressed.</p> <p><img src="/sites/all/files/ai2tutorials/miniGolf/global.png" /></p> <p><strong>Program the behavior of the Right and Left Arrows</strong></p> <p>The left and right arrows are image sprites, so they come equipped with the ability to know when the player is is holding his/her finger down on them. The following blocks toggle the global variables based on whether the user is pressing either of these arrows.</p> <p><img src="/sites/all/files/ai2tutorials/miniGolf/spriteTouchDown.png" /></p> <p><strong>Procedure MoveBallOnTee:</strong></p> <p>Make a new procedure <span class="callblock-ai2">MoveBallOnTee</span> that makes the golf ball move left or right on the tee depending on the global variables. Although the math here looks complicated, it’s pretty simple. If the ball is supposed to move left, you first check to make sure that moving the ball 2 pixels left will not exceed the left-most coordinate of the Tee. If moving the golf ball to the right, you first check that moving the ball right 2 pixels will not move it past the right-most coordinate of the Tee.</p> <p><em>Note: if blocks look different in this image than on your own screen, this is because they were aligned differently. If you right click on the blocks, a list of options will appear and one of them is external inputs. When you select this, it will change how the blocks are configured. It does not change how the blocks function. If you want to change this, right click again and select internal inputs.</em></p> <p><img src="/sites/all/files/ai2tutorials/miniGolf/moveBallOnTee.png" /></p> <p><strong>MoveBallOnCourse Procedure</strong></p> <p>Note that the blocks that we had inside the <span class="basicblock">Clock1.Timer</span> event are now moved over to a new procedure called <span class="callblock-ai2"> MoveBallOnCourse: </span></p> <p><img src="/sites/all/files/ai2tutorials/miniGolf/moveBallOnCourse.png" /></p> <p>On each new course, players can position the ball on the tee before attempting to fling the ball toward the hole. To program this, you first have to check to make sure this is a new course and the ball has not been flung yet. If <span class="variableblock">StrokeCount</span> = 0 then we know this course is brand new and the player has not yet attempted to get the ball into the hole.</p> <p><img src="/sites/all/files/ai2tutorials/miniGolf/timer_final.png" /></p> <p>As the blocks above show, after verifying that the StrokeCount is 0, you then want to proceed to move the golf ball left or right depending on which arrow is being pressed. </p> <pre class="ai-testing"><strong>Test the behavior.</strong> Make sure your app is doing what you expect: play the game on your device or emulator. Before you tee off, are you able to move the ball left and right on the tee by using the left and right arrows? After you tee off, you should no longer be able to use the left and right arrows (pressing them will do nothing). After the ball goes into the hole and the screen resets, you should then be able to move the ball left and right on the tee before teeing off again.</pre><p><strong>Keep track of the number of holes played, and allow a game reset</strong></p> <p>The game is working pretty well now, but what about giving the player a way to reset the game? Also, it would be nice to give the player some instructions so they know how to play the game. While we’re at it, let’s also give an indication of how many holes the player has completed. Add the following components in the Designer:</p> <p><a href="#" name="0899df2ccc45cb7f22bfe41d004593ed854f9f2c" id="0899df2ccc45cb7f22bfe41d004593ed854f9f2c"></a><a href="#" name="3" id="3"></a><br /></p><table cellpadding="0" cellspacing="0"><tbody><tr style="background-color: #EFEFEF; font-weight: bold;"><td> <p><strong>Component Type</strong></p> </td> <td> <p><strong>Palette Group</strong></p> </td> <td> <p><strong>What You’ll Name It</strong></p> </td> <td> <p><strong>Purpose</strong></p> </td> <td> <p><strong>Properties</strong></p> </td> </tr><tr><td> <p>Horizontal Arrangement2</p> </td> <td> <p>Screen Arrangement</p> </td> <td> <p>Horizontal Arrangement2</p> </td> <td> <p>Contains the NewGame button and the HoleNum label</p> </td> <td></td> </tr><tr><td> <p>Button</p> </td> <td> <p>Basic</p> </td> <td> <p>ButtonNewGame</p> </td> <td> <p>Resets the game to Hole #1 with a score of 0.</p> </td> <td> <p>Text: "New Game"</p> </td> </tr><tr><td> <p>Label3</p> </td> <td> <p>Basic</p> </td> <td> <p>LabelHoleNum</p> </td> <td> <p>Displays the current hole number, increments by one each time a hole is completed.</p> </td> <td> <p>Text = "Hole # 1"<br />Font: bold, 28, blue<br /></p> </td> </tr><tr><td> <p>Label4</p> </td> <td> <p>Basic</p> </td> <td> <p>LabelInstruct</p> </td> <td> <p>Displays instructions</p> </td> <td> <p>Text = "Use arrows to position ball on tee. Hit the ball by flinging it with your finger."</p> </td> </tr></tbody></table><p>Define a new global variable to keep track of the Hole Number:</p> <p><img src="/sites/all/files/ai2tutorials/miniGolf/holecount.png" /></p> <p>Add the following blocks to the <span class="callblock-ai2">SetupNewHole</span> procedure: set <span class="setblock">global HoleCount</span> and set <span class="setblock">LabelHoleNum.Text</span>...</p> <p><img src="/sites/all/files/ai2tutorials/miniGolf/setup_final.png" /></p> <p>Program the "New Game" button’s behavior, which is pretty simple. When the button is pressed, set up a new course and reset both the hole stroke counter and total stroke counter to zero. Also set the hole number back to 1, by displaying "Hole #1" in LabelHoleNum. The blocks look like this:</p> <p><img src="/sites/all/files/ai2tutorials/miniGolf/buttonNewGame.png" /></p> <pre class="ai-testing"><strong>Test the behavior.</strong><p> Go back to your device or emulator and play the game some more. Now you should see the Hole # displayed in the lower right. Hitting "New Game" button should reset the game, returning both scores to 0, resetting the screen, and setting the Hole number to #1.</p></pre><h3>Part IV: Introduce an Obstacle</h3> <p>Most mini golf courses have obstacles on them. Let’s add a simple rectangular obstacle that will randomly position itself on the course somewhere between the Tee and the Hole. Each time a new course is presented, the obstacle will move, just the same way the Hole moves each time a new course is set up.</p> <p><strong>Add the following component in the Designer:</strong></p> <p><a href="#" name="981d9864ae92d2e44bbc01311278b4463bf01a1e" id="981d9864ae92d2e44bbc01311278b4463bf01a1e"></a><a href="#" name="4" id="4"></a></p> <table cellpadding="0" cellspacing="0"><tbody><tr style="background-color: #EFEFEF; font-weight: bold;"><td> <p><strong>Component Type</strong></p> </td> <td> <p><strong>Palette Group</strong></p> </td> <td> <p><strong>What You’ll Name It</strong></p> </td> <td> <p><strong>Purpose</strong></p> </td> <td> <p><strong>Properties</strong></p> </td> </tr><tr><td> <p>ImageSprite</p> </td> <td> <p>Animation</p> </td> <td> <p>ObstacleSprite1</p> </td> <td> <p>This sprite will be somewhere between the golf ball and hole and will make it harder to get the ball into the hole</p> </td> <td> <p>Upload the obstacle (rectangle) graphic (<a href="/sites/all/files/tutorials/miniGolf/golf_obstacle1.png">right click on this link</a>, or see below).</p> </td> </tr></tbody></table><p>Program the behavior of the obstacle in the blocks editor. First, set the behavior for when the ball hits the obstacle.  *Note: Using Heading = 0 - heading works because we are dealing with bouncing off of horizonal surfaces, this will not work for bouncing off of vertical or inclined surfaces. For our purposes, it works all right. See Challenge #2 below for more information.</p> <p><img src="/sites/all/files/ai2tutorials/miniGolf/obstaclecollide.png" /></p> <p>Each time the course is reset, position the obstacle will be positioned randomly. Add these blocks to the <span class="callblock-ai2">SetupNewHole</span> procedure:</p> <p><img src="/sites/all/files/ai2tutorials/miniGolf/addtosetup.png" /></p> <pre class="ai-testing"><strong>Test the behavior.</strong> Play the game again. Notice that the ball bounces off when it hits the obstacle. When the ball goes into the hole, or when the New Game button is pressed, the obstacle appears in a new location somewhere between the tee and the hole.</pre><p>That’s it! Share your game with friends by building an APK or by downloading the source and sharing the zip file with other App Inventors!<br /></p> <h3>Part V: Challenges</h3> <p>Here are some extra challenges to make your game better.</p> <p><strong>Challenge 1:</strong> Program the Ball to Hole collision so that the ball only goes into the hole if the golf ball’s speed is not too fast. In real mini golf, the ball will bounce right over the hole if you hit the ball too hard.</p> <p><strong>Challenge 2:</strong> There is a slight bug when the ball hits the vertical sides of obstacle. Figure out how to program the ball to obstacle collision so that it bounces the way you would expect when the ball hits the vertical sides.</p> <p><strong>Challenge 3:</strong> Limit the number of holes per game. Keep track of the number of holes and end the game after a set number. (A typical mini golf course has 18 holes.)</p> <p>Below is a summary of all of the components:</p> <p><img src="/sites/all/files/ai2tutorials/miniGolf/components.png" /></p> <p>Scan the following barcode onto your phone to install and run the sample app. </p><p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/miniGolf/MiniGolfBarcode.png" /></p> <h4 class="ai-header">Download Source Code</h4> <p>If you'd like to work with this sample in App Inventor, download the <a href="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/miniGolf/MiniGolf_MIT.aia">source code</a> to your computer, then open App Inventor, go to the My Projects page, and choose <b>More Actions | Upload Source</b>.</p> <pre class="ai-box"><span style="color:black;">Done with Mini Golf?</span> <a href="http://explore.appinventor.mit.edu/ai2/tutorials">Return to the other tutorials</a>.</pre></div></div></div><section class="field field-name-field-version field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Version:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-version/app-inventor-2" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">App Inventor 2</a> </li> </ul> </section> <section class="field field-name-field-tutorial-difficulty field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Difficulty:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-difficulty/advanced" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Advanced</a> </li> </ul> </section> <section class="field field-name-field-tutorial-type field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Type:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-type/clock-timer" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Clock Timer</a> </li> <li class="field-item odd"> <a href="/tutorial-type/game" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Game</a> </li> <li class="field-item even"> <a href="/tutorial-type/sprites" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Sprites</a> </li> </ul> </section> Wed, 07 Aug 2013 14:13:24 +0000 joanie 379 at http://dev-explore.appinventor.mit.edu http://dev-explore.appinventor.mit.edu/ai2/minigolf#comments MoleMash for App Inventor 2 http://dev-explore.appinventor.mit.edu/ai2/molemash <div class="field field-name-body field-type-text-with-summary field-label-hidden view-mode-rss"><div class="field-items"><div class="field-item even" property="content:encoded"><p><img style="float:right;" src="/sites/all/files/ai2tutorials/moleMash/MoleOnEmulator.png" /></p> <p>In the game <span style="color:green;">MoleMash</span>, a mole pops up at random positions on a playing field, and the player scores points by hitting the mole before it jumps away. This tutorial shows how to build <span style="color:green;">MoleMash</span> as an example of a simple game that uses animation.</p> <p>The tutorial assumes that you have completed the <a href="http://explore.appinventor.mit.edu/ai2/hellopurr">HelloPurr</a> and <a href="/ai2/paintpot-part1">PaintPot</a> tutorials.</p> <p><a href="http://cs.usfca.edu/~wolber/appinventor/bookSplits/ch3MoleMash.pdf">Download Book Chapter (PDF)</a></p> <h4 class="ai-header">Getting Started</h4> <p>Connect to the App Inventor web site and start a new project. Name it "MoleMash", and also set the screen's <strong style="color:green;">Title</strong> to "MoleMash". Open the Blocks Editor and connect to the phone.</p> <p>Also download this <a href="/sites/all/files/ai2tutorials/moleMash/mole.png">picture of a mole</a> and save it on your computer.</p> <h4 class="ai-header">Introduction</h4> <p>You'll design the game so that the mole moves once every half-second. If it is touched, the score increases by one, and the phone vibrates. Pressing restart resets the score to zero.</p> <p>This tutorial introduces:</p> <ul><li>image sprites</li> <li>timers and the <strong>Clock</strong> component</li> <li>procedures</li> <li>picking random numbers between 0 and 1</li> <li>text blocks</li> <li>typeblocking</li> </ul><h4 class="ai-header">The first components</h4> <p>Several components should be familiar from previous tutorials:</p> <ul><li>A <strong>Canvas</strong> named "MyCanvas". This is the area where the mole moves.</li> <li>A <strong>Label</strong> named "ScoreLabel" that shows the score, i.e., the number of times the player has hit the mole.</li> <li>A <strong>Button</strong> named "ResetButton".</li> </ul><p>Drag these components from the Palette onto the Viewer and assign their names. Put <span style="color:green;">MyCanvas</span> on top and set its dimensions to 300 pixels wide by 300 pixels high. Set the <strong style="color:green;">Text</strong> of ScoreLabel to "Score: ---". Set the <strong style="color:green;">Text</strong> of ResetButton to "Reset". Also add a <strong>Sound</strong> component and name it "Noise". You'll use <span style="color:green;">Noise</span> to make the phone vibrate when the mole is hit, similar to the way you made the kitty purr in <span style="color:green;">HelloPurr</span>.</p> <h4 class="ai-header">Timers and the Clock component</h4> <p>You need to arrange for the mole to jump periodically, and you'll do this with the aid of a <strong>Clock</strong> 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 <strong style="color:green;">TimerInterval</strong> 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 <strong style="color:green;">Enabled</strong> is checked.</p> <h4 class="ai-header">Adding an Image Sprite</h4> <p>To add the moving mole we'll use a <em>sprite</em>.</p> <p>Sprites are images that can move on the screen within a Canvas. Each sprite has a <strong style="color:green;">Speed</strong> and a <strong style="color:green;">Heading</strong>, and also an <strong style="color:green;">Interval</strong> that determines how often the sprite moves at its designated speed. Sprites can also detect when they are touched. In <span style="color:green;">MoleMash</span>, 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 <strong>ImageSprite</strong> component onto the Viewer. You'll find this component in the Animation category of the Palette. Place it within <span style="color:green;">MyCanvas</span> area. Set these properties for the Mole sprite:</p> <ul><li><strong style="color:green;">Picture</strong>: Use mole.png, which you downloaded to your computer at the beginning of this tutorial.</li> <li><strong style="color:green;">Enabled</strong>: checked</li> <li><strong style="color:green;">Interval</strong>: 500 (The interval doesn't matter here, because the mole's speed is zero: it's not moving by itself.)</li> <li><strong style="color:green;">Heading</strong>: 0 The heading doesn't matter here either, because the speed is 0.</li> <li><strong style="color:green;">Speed</strong>: 0.0</li> <li><strong style="color:green;">Visible</strong>: checked</li> <li><strong style="color:green;">Width</strong>: Automatic</li> <li><strong style="color:green;">Height</strong>: Automatic</li> </ul><p>You should see the <strong style="color:green;">x</strong> and <strong style="color:green;">y</strong> properties already filled in. They were determined by where you placed the mole when you dragged it onto <span style="color:green;">MyCanvas</span>. Go ahead and drag the mole some more. You should see <strong style="color:green;">x</strong> and <strong style="color:green;">y</strong> 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 <span style="color:green;">Mole</span> is indented under <span style="color:green;">MyCanvas</span> in the component structure list, indicating that the sprite is a sub-component of the canvas.</p> <p><img src="/sites/all/files/ai2tutorials/moleMash/MoleMashDesigner.png" /></p> <h4 class="ai-header">Component Behavior and Event Handlers</h4> <p>Now you'll specify the component behavior. This introduces some new App Inventor ideas. The first is the idea of a <em>procedure</em>. For an overview and explanation of procedures, check out the <a href="/ai2/support/concepts/procedures">Procedures page</a>.</p> <p>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.</p> <h4 class="ai-header">Define Procedures</h4> <p>Define two procedures:</p> <ul><li><span class="callblock-ai2">MoveMole</span> moves the <span style="color:green;">Mole</span> sprite to a new random position on the canvas.</li> <li><span class="callblock-ai2">UpdateScore</span> shows the score, by changing the text of the <strong style="color:green;">ScoreLabel</strong></li> </ul><p>Start with MoveMole:</p> <ul><li>In the Blocks Editor, under Built-In, open the Procedures drawer. Drag out a <span class="callblock-ai2">to procedure</span> block and change the label "procedure" to "MoveMole".<br /><pre class="box">Note: There are two similar blocks: <span class="callblock-ai2">procedure then do</span> and <span class="callblock-ai2">procedure then resu;t</span>. Here you should use <span class="callblock-ai2">procedure then do</span>.</pre><p>The <span class="callblock-ai2">to MoveMole</span> 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 <span class="mathblock-ai2">random fraction</span> and multiplication and subtraction. You can find these in the Math drawer.</p></li> <li>Build the <span style="color:green;">MoveMole</span> procedure. The completed definition should look like this:<br /><img src="/sites/all/files/ai2tutorials/moleMash/MoveMole.png" /><br /><span style="color:green;">MoveMole</span> does not take any arguments so you don't have to use the <a href="/ai2/support/concepts/mutators">mutator</a> function of the procedure block. Observe how the blocks connect together: the first statement uses the <span class="setblock">Mole.X set</span> block to set mole's horizontal position. The value plugged into the block's socket is the result of multiplying: <ol><li>The result of the <span class="mathblock-ai2">call random fraction</span> block, which a value between 0 and 1</li> <li>The result of subtracting the mole's width from the canvas width</li> </ol><p>The vertical position is handled similarly.</p></li> </ul><p>With <span style="color:green;">MoveMole</span> done, the next step is to define a variable called <span style="color:green;">score</span> to hold the score (number of hits) and give it initial value 0. Also define a procedure <span class="callblock-ai2">UpdateScore</span> that shows the score in <span style="color:green;">ScoreLabel</span>. The actual contents to be shown in <span style="color:green;">ScoreLabel</span> will be the text "Score: " joined to the value of <span style="color:green;">score</span>.</p> <ul><li>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 "text".</li> <li>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.</li> </ul><p>Here's how <span style="color:green;">score</span> and <span class="callblock-ai2">UpdateScore</span> should look:</p> <p><img src="/sites/all/files/ai2tutorials/moleMash/UpdateScore.png" /></p> <h4 class="ai-header">Add a Timer</h4> <p>The next step is to make the mole keep moving. Here's where you'll use <span style="color:green;">MoleTimer</span>. Clock components have an event handler called <span class="eventblock">when ... Timer</span> that triggers repeatedly at a rate determined by the <strong style="color:green;">TimerInterval</strong>.</p> <p>Set up <span style="color:green;">MoleTimer</span> to call <span class="callblock-ai2">MoveMole</span> each time the timer fires, by building the event handler like this:</p> <p><img src="/sites/all/files/ai2tutorials/moleMash/MoleMashTimerEventHandler.png" /></p> <pre class="ai-box">Notice how the mole starts jumping around on the phone as soon as you define the event handler. This is an example of how things in App Inventor start happening instantaneously, as soon as you define them.</pre><h4 class="ai-header">Add a Mole Touch Handler</h4> <p>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 <span style="color:green;">Mole</span> that:</p> <ol><li>Increments the score.</li> <li>Calls <span class="callblock-ai2">UpdateScore</span> to show the new score.</li> <li>Makes the phone vibrate for 1/10 second (100 milliseconds).</li> <li>Calls <span class="callblock-ai2">MoveMole</span> so that the mole moves right away, rather than waiting for the timer.</li> </ol><p>Here's what this looks like in blocks. Go ahead and assemble the <span class="eventblock">when Mole.Touched</span> blocks as shown.</p> <p><img src="/sites/all/files/ai2tutorials/moleMash/MoleMashTouchEventHandler.png" /></p> <p>Here's a tip: You can use <a href="/tips/typeblocking">typeblocking</a>: typing to quickly create blocks.</p> <ul><li>To create a value block containing 100, just type 100 and press return.</li> <li>To create a <span class="callblock-ai2">MoveMole</span> block, just type <span class="callblock-ai2">MoveMole</span> and select the block you want from the list</li> </ul><h4 class="ai-header">Reset the Score</h4> <p>One final detail is resetting the score. That's simply a matter of making the <span style="color:green;">ResetButton</span> change the score to 0 and calling <span class="callblock-ai2">UpdateScore</span>.</p> <h4 class="ai-header">Complete Program</h4> <p>Here's the complete <span style="color:green;">MoleMash</span> program:</p> <p><img src="/sites/all/files/ai2tutorials/moleMash/MoleMashComplete.png" /></p> <h4 class="ai-header">Variations</h4> <p>Once you get the game working, you might want to explore some variations. For example:</p> <ul><li>Make the game vary the speed of the mole in response to how well the player is doing. To vary how quickly the mole moves, you'll need to change the <span style="color:green;">MoleTimer</span>'s <strong style="color:green;">Interval</strong> property.</li> <li>Keep track of when the player hits the mole and when the player misses the mole, and show a score with both hits and misses. To do this, you'll need do define touched handlers both for <span style="color:green;">Mole</span>, same as now, and for <span style="color:green;">MyCanvas</span>. One subtle issue, if the player touches the mole, does that also count as a touch for <span style="color:green;">MyCanvas</span>? The answer is yes. Both touch events will register.</li> </ul><h4 class="ai-header">Review</h4> <p>Here are some of the ideas covered in this project:</p> <ul><li>Sprites are touch-sensitive shapes that you can program to move around on a <strong>Canvas</strong>.</li> <li>The <strong>Clock</strong> component can be used as a timer to make events that happen at regular intervals.</li> <li>Procedures are defined using <span class="callblock-ai2">to</span> blocks.</li> <li>For each procedure you define, App Inventor automatically creates an associated call block and places it in the My Definitions drawer.</li> <li>Making a <span class="mathblock-ai2">random-fraction</span> block produces a number between 0 and 1.</li> <li>Text blocks specify literal text, similar to the way that number blocks specify literal numbers.</li> <li><a href="/tips/typeblocking">Typeblocking</a> is a way to create blocks quickly, by typing a block's name.</li> </ul><h4 class="ai-header">Scan the Sample App to your Phone</h4> <p>Scan the following barcode onto your phone to install and run the sample app. </p><p><img src="/sites/all/files/ai2tutorials/moleMash/MoleMashBarcode.png" /></p> <h4 class="ai-header">Download Source Code</h4> <p>If you'd like to work with this sample in App Inventor, download the <a href="/sites/all/files/ai2tutorials/moleMash/MoleMash.aia">source code</a> to your computer, then open App Inventor, go to the My Projects page, and choose <b>More Actions | Upload Source</b>.</p> <pre class="ai-box">Done with <span style="color:black;">MoleMash</span>? Return to the other tutorials <a href="/ai2/tutorials">here</a>.</pre></div></div></div><section class="field field-name-field-version field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Version:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-version/app-inventor-2" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">App Inventor 2</a> </li> </ul> </section> <section class="field field-name-field-tutorial-difficulty field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Difficulty:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-difficulty/basic" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Basic</a> </li> </ul> </section> <section class="field field-name-field-tutorial-type field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Type:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-type/clock-timer" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Clock Timer</a> </li> <li class="field-item odd"> <a href="/tutorial-type/game" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Game</a> </li> <li class="field-item even"> <a href="/tutorial-type/sprites" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Sprites</a> </li> </ul> </section> Wed, 03 Jul 2013 14:29:42 +0000 aaron 356 at http://dev-explore.appinventor.mit.edu http://dev-explore.appinventor.mit.edu/ai2/molemash#comments MoleMash 2 for App Inventor 2 http://dev-explore.appinventor.mit.edu/ai2/molemash-2 <div class="field field-name-body field-type-text-with-summary field-label-hidden view-mode-rss"><div class="field-items"><div class="field-item even" property="content:encoded"><style> <!--/*--><![CDATA[/* ><!--*/ li { padding-bottom: 7px; } .basicblock { border: 1px dashed #7AA81C; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #E7F2CB; font-size: 9pt; text-wrap: suppress; } .callblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #E0D1FF; font-size: 9pt; text-wrap: suppress; } .argblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #E5E5FF; font-size: 9pt; text-wrap: suppress; } .textblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #FADAA0; font-size: 9pt; text-wrap: suppress; } .setblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #C1D5F8; font-size: 9pt; text-wrap: suppress; } .controlblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #FAEDBB; font-size: 9pt; text-wrap: suppress; } .listblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #FCF5D7; font-size: 9pt; text-wrap: suppress; } /*--><!]]>*/ </style><h4 class="ai-header">What You're Building</h4> <p><img src="/sites/all/files/ai2tutorials/moleMash2/front-pic.png" style="float:right;" /></p> <p><a href="http://cs.usfca.edu/~wolber/appinventor/bookSplits/ch3MoleMash.pdf">Download Refined Version (Book Chapter PDF)</a></p> <p>This tutorial shows you how to build a game similar to the Whac-A-MoleTM arcade game. Specifically, your goal is to whack (tap) a mole that randomly pops out of one of five fixed holes. Every time you succeed, your score is increased by one point.</p> <p>In order to highlight new App Inventor features — the Advanced tab and Sprite Z-layering — this app takes a different approach than the <a href="http://explore.appinventor.mit.edu/ai2/molemash">original Mole Mash tutorial</a>, which you need not have read in order to do this one. You should, however, be familiar with the basics of App Inventor — using the Component Designer to build a user interface and using the Blocks Editor to specify event handlers. If you are not familiar with the basics, try stepping through some of the <a href="http://explore.appinventor.mit.edu/ai2/tutorials">basic tutorials</a> before continuing.</p> <h4 class="ai-header">Introduction</h4> <p>This tutorial includes:</p> <ol><li>Creating a list of components</li> <li>Using functionality from the Advanced section of the Blocks Editor to get and set properties of arbitrary components</li> <li>Having game events controlled by the <b>Clock</b> component</li> <li>Using Sprite Z-layering to ensure that one sprite (<b>ImageSprite</b> or <b>Ball</b>) appears in front of another</li> </ol><h4 class="ai-header">Getting Started</h4> <p>Connect to the App Inventor web site and start a new project. Set the screen's <b style="color:green;">Title</b> property to an appropriate name, such as "Mole Mash". Open the Blocks Editor and connect it to the phone. Download these image files (created by Yun Miao) by right-clicking on them, then add them to the project by pressing the "Add..." button in the Media pane.</p> <p><a href="/sites/all/files/ai2tutorials/moleMash2/hole.png"><img src="/sites/all/files/ai2tutorials/moleMash2/hole.png" /></a><a href="/sites/all/files/ai2tutorials/moleMash2/mole.png"><img src="/sites/all/files/ai2tutorials/moleMash2/mole.png" /></a></p> <h4 class="ai-header">Set up the Components</h4> <p>The user interface will contain a total of 6 ImageSprites: 5 unmoving holes and 1 mole, which will move on top of the holes. Use the component designer to create the user interface. When you are done, it should look something like the picture below. Don't worry about lining up the holes evenly. You will specify their locations through their <b style="color:green;">X</b> and <b style="color:green;">Y</b> properties. Additional instructions are below the picture.</p> <p><img src="/sites/all/files/ai2tutorials/moleMash2/designer1.png" /></p> <p>Create the following components by dragging them from the Palette into the Viewer.</p> <table><tr style="background-color: #EFEFEF; font-weight: bold;"><td> Component Type </td> <td> Palette Group </td> <td> What you'll name it </td> <td> Purpose of Component </td> </tr><tr><td> <b>Canvas</b> </td> <td>Basic</td> <td style="color:green;">GameCanvas</td> <td>The game field</td> </tr><tr><td> <b>ImageSprite</b> (5) </td> <td>Animation</td> <td style="color:green;">Hole1 ... Hole5</td> <td>Holes from which the mole can appear</td> </tr><tr><td> <b>ImageSprite</b> </td> <td>Animation</td> <td style="color:green;">Mole</td> <td>The mole</td> </tr><tr><td> <b>HorizontalArrangement</b> </td> <td>Screen Arrangement</td> <td style="color:green;">ScoreArrangement</td> <td>To display the score</td> </tr><tr><td> <b>Label</b> </td> <td>Basic</td> <td style="color:green;">ScoreTextLabel</td> <td>To hold "Score: "</td> </tr><tr><td> <b>Label</b> </td> <td>Basic</td> <td style="color:green;">ScoreValueLabel</td> <td>To hold the score (# of times the mole was hit)</td> </tr><tr><td> <b>Clock</b> </td> <td>Basic</td> <td style="color:green;">MoleClock</td> <td>To control the mole's movement</td> </tr><tr><td> <b>Sound</b> </td> <td>Media</td> <td style="color:green;">Buzzer</td> <td>To vibrate when the mole is touched</td> </tr></table><p>Make the following changes to the components' properties:</p> <table><tr style="background-color: #EFEFEF; font-weight: bold;"><td> Component </td> <td> Action </td> </tr><tr><td>Canvas1</td> <td>Set <b style="color:green;">BackgroundColor</b> to Green. Set <b style="color:green;">Width</b> to 320 pixels. Set <b style="color:green;">Height</b> to 320 pixels.</td> </tr><tr><td>Hole1</td> <td>Set <b style="color:green;">X</b> to 20 and <b style="color:green;">Y</b> to 60 (upper left).</td> </tr><tr><td>Hole2</td> <td>Set <b style="color:green;">X</b> to 130 and <b style="color:green;">Y</b> to 60 (upper center).</td> </tr><tr><td>Hole3</td> <td>Set <b style="color:green;">X</b> to 240 and <b style="color:green;">Y</b> to 60 (upper right)</td> </tr><tr><td>Hole4</td> <td>Set <b style="color:green;">X</b> to 75 and <b style="color:green;">Y</b> to 140 (lower left).</td> </tr><tr><td>Hole5</td> <td>Set <b style="color:green;">X</b> to 185 and <b style="color:green;">Y</b> to 140 (lower right).</td> </tr><tr><td>Mole</td> <td>Set <b style="color:green;">Picture</b> to "mole.png". Set <b style="color:green;">Z</b> to 2 so the mole appears in front of the other <b style="color:green;">ImageSprite</b> s, which have the default <b style="color:green;">Z</b> value of 1.</td> </tr><tr><td>ScoreTextLabel</td> <td>Set <b style="color:green;">Text</b> to "Score: ".</td> </tr><tr><td>ScoreTextValue</td> <td>Set <b style="color:green;">Text</b> to "0".</td> </tr></table><p>Don't worry now about setting the <b style="color:green;">Picture</b> property for the holes; we'll set the property in the Blocks Editor.</p> <h4 class="ai-header">Add Behaviors to the Components</h4> <p>Here is an overview of what we need to create blocks to do:</p> <ol><li>Create variables: <ol><li><b style="color:green;">holes</b>: a list of holes</li> <li><b style="color:green;">currentHole</b>: the hole the mole is currently coming out of</li> </ol></li> <li>When the app starts: <ol><li>Populate the list of holes.</li> <li>Set each hole's <b style="color:green;">Picture</b> property to "hole.png".</li> <li>Call procedure <span class="callblock">MoveMole</span> (below).</li> </ol></li> <li>Create a procedure <span class="callblock">MoveMole</span> to: <ol><li>Set <b style="color:green;">currentHole</b> to a random hole from the list <b style="color:green;">holes</b>.</li> <li>Move the mole to the location of <b style="color:green;">currentHole</b>.</li> </ol></li> <li>Make <b>MoleClock</b> call <span class="callblock">MoveMole</span> whenever its timer goes off (every second). </li> <li>Implement a handler that does the following when the mole is touched: <ol><li>Add one to the score.</li> <li>Make the phone briefly vibrate.</li> <li>Call <span class="callblock">MoveMole</span>.</li> </ol></li> </ol><p>To proceed, switch to the Blocks Editor.</p> <h4 class="ai-header">Creating Variables</h4> <p>Create the variables <b style="color:green;">holes</b> and <b style="color:green;">currentHole</b>. For now, we will give them "dummy" initial values; we'll set their real initial values in the <span class="basicblock">Screen1.Initialize</span> event handler, which is run when the app starts. (For technical reasons, components cannot be referred to in def blocks, which are run before the app has started.) Here is a picture and list of the blocks you will need:</p> <p><img src="/sites/all/files/ai2tutorials/moleMash2/blocks1.png" /></p> <table><tr style="background-color: #EFEFEF; font-weight: bold;"><td> Block type </td> <td> Drawer </td> <td> Purpose </td> </tr><tr><td><span class="setblock">def variable as</span> (holes)</td> <td>Definition</td> <td>Hold a list of holes.</td> </tr><tr><td><span class="listblock">make a list</span></td> <td>Lists</td> <td>Create an empty list, to be filled in when the program starts.</td> </tr><tr><td><span class="setblock">def variable as</span> (currentHole)</td> <td>Definition</td> <td>Hold the mole's current hole.</td> </tr><tr><td><span class="basicblock">number</span> (0)</td> <td>Numbers</td> <td>Provide a required initial value for <b style="color:green;">currentHole</b>.</td> </tr></table><p>As always, comments (created by right-clicking on a block) are encouraged but not required.</p> <h4 class="ai-header">Starting the App</h4> <p>The first event to occur in any program in <span class="basicblock">Screen1.Initialize</span>, so we will put start-up code in that handler. Specifically, we will add the hole components to the list holes, set each hole's <b style="color:green;">Picture</b> property to "hole.png", and call <span class="callblock">MoveMole</span>. Since we have not yet written MoveMole, we will create an empty procedure with that name, which we will fill in later.</p> <p>Below are a picture and table of the blocks you need to create. Note that the "Any ImageSprite" drawer is found under the "Advanced" tab to the right of "Built-In" and "My Blocks" in the Blocks Editor.</p> <p><img src="/sites/all/files/ai2tutorials/moleMash2/blocks2.png" /></p> <table><tr style="background-color: #EFEFEF; font-weight: bold;"><td> Block type </td> <td> Drawer </td> <td> Purpose </td> </tr><tr><td><span class="basicblock">Screen1.Initialize</span></td> <td>Screen1</td> <td>Specify what should happen when the app starts.</td> </tr><tr><td><span class="listblock">add items to list</span></td> <td>Lists</td> <td>Add the following values to...</td> </tr><tr><td><span class="argblock">holes</span></td> <td>My Definitions</td> <td>...the list of holes:</td> </tr><tr><td><span class="argblock">component Hole1</span></td> <td>Hole1</td> <td>-the upper left hole</td> </tr><tr><td><span class="argblock">component Hole2</span></td> <td>Hole2</td> <td>-the upper center hole</td> </tr><tr><td><span class="argblock">component Hole3</span></td> <td>Hole3</td> <td>-the upper right hole</td> </tr><tr><td><span class="argblock">component Hole4</span></td> <td>Hole4</td> <td>-the lower left hole</td> </tr><tr><td><span class="argblock">component Hole5</span></td> <td>Hole5</td> <td>-the lower right hole</td> </tr><tr><td><span class="controlblock">foreach</span></td> <td>Control</td> <td>Specify that we would like...</td> </tr><tr><td><span class="argblock">name</span> (hole)</td> <td>Definitions</td> <td>...a variable named "hole"...</td> </tr><tr><td><span class="argblock">holes</span></td> <td>My Definitions</td> <td>...to take on each of the values in the list holes .</td> </tr><tr><td><span class="setblock">ImageSprite.Picture</span></td> <td>Any Image Sprite</td> <td>Set the Picture property of...</td> </tr><tr><td><span class="argblock">value hole</span></td> <td>My Definitions</td> <td>...the ImageSprite referred to by the variable hole ...</td> </tr><tr><td><span class="textblock">text (hole.png)</span></td> <td>Text</td> <td>...to the picture of the empty hole.</td> </tr><tr><td><span class="callblock">to procedure</span> (MoveMole)</td> <td>Definition</td> <td>Create an procedure, to be filled in later, for moving the mole.</td> </tr><tr><td><span class="callblock">MoveMole</span></td> <td>My Definitions</td> <td>Call MoveMole to make the first placement of the mole.</td> </tr></table><p>Compare the <span class="controlblock">foreach</span> block to the equivalent blocks that would be necessary without it:</p> <p><img src="/sites/all/files/ai2tutorials/moleMash2/blocks_new_old.png" /></p> <p>Not only is the left set of blocks shorter, it is less repetitious, sparing the programmer from semi-mindless copy-and-pasting and making it easier to modify, for example, if the name of the picture is changed.</p> <h4 class="ai-header">Moving the Mole</h4> <p>Now let's fill in the body of the procedure MoveMole, which we'll call when the program starts, when the mole gets touched, and when our timer goes off every second. What we want it to do is to pick a random hole and move the mole on top of it. Here are a picture and list of the new blocks:</p> <p><img src="/sites/all/files/ai2tutorials/moleMash2/blocks4.png" /></p> <table><tr style="background-color: #EFEFEF; font-weight: bold;"><td> Block type </td> <td> Drawer </td> <td> Purpose </td> </tr><tr><td><span class="setblock">set currentHole to</span></td> <td>My Definitions</td> <td>Save the...</td> </tr><tr><td><span class="listblock">call pick random item</span></td> <td>Lists</td> <td>...randomly selected...</td> </tr><tr><td><span class="argblock">holes</span></td> <td>My Definitions</td> <td>...hole.</td> </tr><tr><td><span class="basicblock">call Mole.MoveTo</span></td> <td>Mole</td> <td>Move the mole to the...</td> </tr><tr><td><span class="argblock">ImageSprite.X</span></td> <td>Advanced/ImageSprite</td> <td>..x-coordinate of...</td> </tr><tr><td><span class="argblock">currentHole</span></td> <td>My Definitions</td> <td>...the chosen hole...</td> </tr><tr><td><span class="argblock">ImageSprite.Y</span></td> <td>Advanced/ImageSprite</td> <td>...and the y-coordinate of...</td> </tr><tr><td><span class="argblock">current Hole</span></td> <td>My Definitions</td> <td>...the chosen hole.</td> </tr></table><p>We now need to specify that MoveMole should be called whenever MoleClock's Timer goes off. We just need two blocks to accomplish that:</p> <p><img src="/sites/all/files/ai2tutorials/moleMash2/blocks5.png" /></p> <table><tr style="background-color: #EFEFEF; font-weight: bold;"><td> Block type </td> <td> Drawer </td> <td> Purpose </td> </tr><tr><td><span class="basicblock">MoleClock.Timer</span></td> <td>MoleClock</td> <td>When the timer goes off...</td> </tr><tr><td><span class="callblock">call MoveMole</span></td> <td>My Definitions</td> <td>...move the mole.</td> </tr></table><h4 class="ai-header">Registering Touches</h4> <p>Finally, we need to specify what happens when the mole is touched. Specifically, we want to:</p> <ol><li>Increment the score.</li> <li>Make the phone vibrate briefly.</li> <li>Move the mole.</li> </ol><p>We can easily translate these to blocks:</p> <p><img src="/sites/all/files/ai2tutorials/moleMash2/blocks6.png" /></p> <table><tr style="background-color: #EFEFEF; font-weight: bold;"><td> Block type </td> <td> Drawer </td> <td> Purpose </td> </tr><tr><td><span class="basicblock">Mole.Touched</span></td> <td>Mole</td> <td>When the mole is touched...</td> </tr><tr><td><span class="setblock">set ScoreValueLabel.Text to</span></td> <td>ScoreValueLabel</td> <td>...update the visible score to...</td> </tr><tr><td><span class="basicblock"> block</span></td> <td>Math</td> <td>...the result of adding...</td> </tr><tr><td><span class="basicblock">number</span> (1)</td> <td>Math</td> <td>...1 [and]...</td> </tr><tr><td><span class="argblock">ScoreValueLabel.Text</span></td> <td>ScoreValueLabel</td> <td>...the previous score.</td> </tr><tr><td><span class="callblock">call Buzzer.Vibrate</span></td> <td>Buzzer</td> <td>Make the phone vibrate for...</td> </tr><tr><td><span class="basicblock">number</span> (100)</td> <td>Math</td> <td>...100 milliseconds.</td> </tr><tr><td><span class="callblock">call MoveMole</span></td> <td>My Definitions</td> <td>Move the mole to a new location.</td> </tr></table><h4 class="ai-header">Final Program</h4> <p><img src="/sites/all/files/ai2tutorials/moleMash2/blocks-final.png" /></p> <h4 class="ai-header">Variations</h4> <p>Here are some variations you might want to implement:</p> <ul><li>Adding a Reset button to set the score back to 0.</li> <li>Having the score depend not just on the number of hits but also the number of misses and escaped moles.</li> <li>Increasing the speed of the game of mole movement if the player is doing well and decreasing it if the player is doing poorly.</li> <li>Adding a second mole on a different timer.</li> </ul><p>You can see how to implement the first two variations in the <a href="http://explore.appinventor.mit.edu/ai2/molemash">original Mole Mash tutorial</a>.</p> <h4 class="ai-header">Review</h4> <p>Here are some of the ideas covered in this tutorial:</p> <ul><li>Putting components in a <b>List</b>.</li> <li>Performing an operation on every component in a <b>List</b> using the <span class="controlblock">foreach</span> block and Advanced features.</li> <li>Placing an <b>ImageSprite</b> on top of another, using their <b style="color:green;">Z</b> properties to control which goes in front.</li> <li>Using the <b>Clock</b> component to control game play.</li> <li>Creating a procedure and calling it from multiple places.</li> </ul><pre class="ai-box">Done with <span style="color:black;">MoleMash 2</span>? Return to the other tutorials <a href="http://explore.appinventor.mit.edu/ai2/tutorials">here</a>.</pre><h4 class="ai-header">Scan the Sample App to your Phone</h4> <p>Scan the following barcode onto your phone to install and run the sample app. </p><p><img src="/sites/all/files/ai2tutorials/moleMash2/MoleMash2Barcode.png" /></p> <p>Or <a href="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/moleMash2/MoleMash2.apk">download the apk</a></p> <h4 class="ai-header">Download Source Code</h4> <p>If you'd like to work with this sample in App Inventor, download the <a href="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/moleMash2/MoleMash2.aia">source code</a> to your computer, then open App Inventor, go to the My Projects page, and choose <b>More Actions | Upload Source</b>.</p> </div></div></div><section class="field field-name-field-version field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Version:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-version/app-inventor-2" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">App Inventor 2</a> </li> </ul> </section> <section class="field field-name-field-tutorial-difficulty field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Difficulty:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-difficulty/advanced" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Advanced</a> </li> </ul> </section> <section class="field field-name-field-tutorial-type field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Type:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-type/clock-timer" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Clock Timer</a> </li> <li class="field-item odd"> <a href="/tutorial-type/game" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Game</a> </li> <li class="field-item even"> <a href="/tutorial-type/sprites" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Sprites</a> </li> </ul> </section> Tue, 02 Jul 2013 14:47:11 +0000 aaron 349 at http://dev-explore.appinventor.mit.edu http://dev-explore.appinventor.mit.edu/ai2/molemash-2#comments Get the Gold for App Inventor 2 http://dev-explore.appinventor.mit.edu/ai2/get-gold <div class="field field-name-body field-type-text-with-summary field-label-hidden view-mode-rss"><div class="field-items"><div class="field-item even" property="content:encoded"><style> <!--/*--><![CDATA[/* ><!--*/ .ButtonText { color:green; font-weight: bold; } li { padding-bottom: 7px; } .basicblock { border: 1px dashed #7AA81C; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #E7F2CB; font-size: 9pt; text-wrap: suppress; } .callblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #E0D1FF; font-size: 9pt; text-wrap: suppress; } .argblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #E5E5FF; font-size: 9pt; text-wrap: suppress; } .textblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #FADAA0; font-size: 9pt; text-wrap: suppress; } .setblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #C1D5F8; font-size: 9pt; text-wrap: suppress; } .controlblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #FAEDBB; font-size: 9pt; text-wrap: suppress; } .listblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #FCF5D7; font-size: 9pt; text-wrap: suppress; } /*--><!]]>*/ </style><h4 class="ai-header">What You're Building</h4> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/GetTheGold/GetTheGoldMain.png" style="float:right; height: 453px; width: 197px;" /></p> <p> By building the <span style="color:green;">Get The Gold App</span> you will get practice with setting visibility, using Clock components and Timers, and detecting collisions in App Inventor. You'll program an application that has a pirate ship whose goal is to collect all the gold on the screen.</p> <h4 class="ai-header">Getting Started</h4> <p>Connect to the App Inventor web site and start a new project. Name it <span style="color:green;">GetTheGold</span>, and also set the screen's <strong style="color:green;">Title</strong> to "GetTheGold". Switch to the Blocks view and connect to a device or emulator.</p> <h4 class="ai-header">Introduction</h4> <p>This tutorial introduces the following skills, useful for future game development:</p> <ul><li>Using the Clock component</li> <li>Using Clock.Timer to move sprites</li> <li>Using Sprite.Flung to move a sprite </li> <li>Using collision detection</li> </ul><h4 class="ai-header">Getting Ready</h4> <p>For this game, you will have two types of imagesprites: pirate and gold coin. Click below to download the image file for your sprites.</p> <p><a href="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/GetTheGold/pirateship.jpeg"><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/GetTheGold/pirateship.jpeg" /></a><br /><a href="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/GetTheGold/goldcoin.jpeg"><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/GetTheGold/goldcoin.jpeg" /></a></p> <h4 class="ai-header">Set up the Components</h4> <p>Use the component designer to create the interface for <span style="color:green;">GetTheGold</span>. When you finish, it should look something like the snapshot below (more detailed instructions below the snapshot).</p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/GetTheGold/GetTheGoldDesigner.png" /></p> <p>To create this interface, put the following components into the Designer by dragging them from the Component Palette into the Viewer.</p> <table><tr style="background-color: #EFEFEF; font-weight: bold;"><td> Component Type </td> <td> Palette Group </td> <td> What you'll name it </td> <td> Purpose of Component </td> </tr><tr><td><strong>Canvas</strong></td> <td>Basic</td> <td style="color:green;">Canvas1</td> <td>The background that we will be putting our imagesprites on</td> </tr><tr><td><strong>ImageSprite</strong></td> <td>Animation</td> <td style="color:green;">PirateSprite</td> <td>The pirate ship in our game</td> </tr><tr><td><strong>ImageSprite</strong></td> <td>Animation</td> <td style="color:green;">ImageSprite2</td> <td>One of the gold coins in the game</td> </tr><tr><td><strong>ImageSprite</strong></td> <td>Animation</td> <td style="color:green;">ImageSprite3</td> <td>One of the gold coins in the game</td> </tr><tr><td><strong>ImageSprite</strong></td> <td>Animation</td> <td style="color:green;">ImageSprite4</td> <td>One of the gold coins in the game</td> </tr><tr><td><strong>ImageSprite</strong></td> <td>Animation</td> <td style="color:green;">ImageSprite5</td> <td>One of the gold coins in the game</td> </tr><tr><td><strong>ImageSprite</strong></td> <td>Animation</td> <td style="color:green;">ImageSprite6</td> <td>One of the gold coins in the game</td> </tr><tr><td><strong>Clock</strong></td> <td>Basic</td> <td style="color:green;">Clock1</td> <td>We use the Clock for its Timer method to move the coins</td> </tr><tr><td><strong>Button</strong></td> <td>Basic</td> <td style="color:green;">ResetButton</td> <td>To reset the game so the player can play again</td> </tr></table><p>Set the properties of the components as described below:</p> <table><tr style="background-color: #EFEFEF; font-weight: bold;"><td><strong>Component</strong></td> <td><strong>Action</strong></td> <td> </td> </tr><tr><td><span style="color:green;">ResetButton</span> </td> <td> Change <span class="ButtonText">Text</span> property to "Reset". </td> <td> </td> </tr><tr><td><span style="color:green;">PirateSprite</span> </td> <td> Change <span class="ButtonText">Speed</span> property to 6. </td> <td> Upload the pirateship image and set <span class="ButtonText">Picture</span> property to pirateship. </td> </tr><tr><td><span style="color:green;">ImageSprite(2,3,4,5,6)</span> </td> <td> Upload the goldcoin image and set <span class="ButtonText">Picture</span> property to goldcoin. </td> <td> </td> </tr><tr><td><span style="color:green;">Clock</span> </td> <td> Change <span class="ButtonText">TimerInterval</span> property to 2000. </td> <td> </td> </tr></table><h4 class="ai-header">Moving the Pirate</h4> <p> To move the PirateSprite, we want the user to be able to "fling" the sprite in the direction that they choose. To do this, we will use the <span class="eventblock">PirateSprite.Flung</span> event handler. </p> <p> You may notice that <span class="eventblock">PirateSprite.Flung</span> takes in 6 attributes: x, y, xvel, yvel, speed, and heading. We want to reassign PirateSprite's current heading to the heading given to us from PirateSprite.Flung. This means that the user can now control the direction of the pirate ship with their fingers by flinging on the screen. </p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/GetTheGold/PirateSpriteFlung.png" /></p> <p>To prevent the pirate from moving off the screen, we will also use PirateSprite.Bounce when an edge is reached. </p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/GetTheGold/PirateSpriteBounce.png" /></p> <h4 class="ai-header">Moving the Coins</h4> <p> We want the coins to move to random positions on the screen. We will use <span class="eventblock">Clock1.Timer </span> and the ImageSprite's MoveTo method to do this. </p> <p> When the Clock1.Timer goes off, we want all of our gold coin ImageSprites to move to a new random location on the Canvas. We will do this by using the <span class="callblock-ai2">Sprite.MoveTo</span> block. </p> <p>MoveTo takes in two arguments: the x and y coordinates on the canvas of the new position we want the sprite to move to. We want the Sprite to move to a new <i>random</i> location so we will use the <span class="mathblock-ai2">random integer</span> block found in the Math box. Since we want each Gold ImageSprite to move to a new location, we repeat this process for each sprite's MoveTo function. </p> <p>For ImageSprite2, we want x to be a random integer from 0 to <i>Canvas1.Width-ImageSprite2.Width</i> and y to be a random integer from 0 to <i>Canvas1.Height-ImageSprite2.Height</i>. This is to be repeated for all the Gold Image Sprites.</p> <p>Remember that sprites are measured at the upper left corner as (0,0) so if we don't want them to go off the screen, we need to take the sprite's height/width into account when setting the range for our random numbers.</p> <p>We will do this by setting up our blocks as in the image below:</p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/GetTheGold/ClockTimer.png" /></p> <h4 class="ai-header">Detecting Collisions</h4> <p> App Inventor detects collisions by checking for an intersection between the bounding rectangles of each ImageSprite. We call this rectangle-based collision detection. As you can see in the image below, sprites with circular or polygon shape will appear to collide because of the rectangular bounds around them when they might not actually be colliding.</p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/GetTheGold/CollisionDetection.png" /></p> <p>We can use the <span class="eventblock">PirateSprite.CollidedWith </span> event handler to detect whenever the pirate ship collides with another sprite or gold coin. You may notice that <span class="eventblock">PirateSprite.CollidedWith </span> takes in an argument. This argument is the object that PirateSprite just collided with. We will be testing inside the handler for which object so the name of this argument is not significant. You can name it other. </p> <p>Whenever the pirate collides with a gold coin, we want the coin to disappear. We can do this by setting the coin's visibility to false. To find which coin the pirate collided with, we will use the <span class="eventblock">PirateSprite.CollidingWith</span>. </p> <p> We can use <span class="eventblock">PirateSprite.CollidingWith</span> to take in a component (each of the gold coin sprites) to detect which sprite was hit. This is a component block and NOT a text block with the words ImageSprite inside. The component block can be found in the drawer for each component. If a sprite was hit, we will set its visibility to false. </p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/GetTheGold/CollisionSprites.png" /></p> <h4 class="ai-header">Reset Button</h4> <p>After the user hits all of the gold sprites with the pirate ship, none of them will be visible. The reset button should set all of the gold sprites' visibility to true. </p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/GetTheGold/ResetVis.png" /></p> <h4 class="ai-header">Complete Program</h4> <p>Here's the complete <strong><span style="color:green;">GetTheGold</span></strong> program.</p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/GetTheGold/GetTheGoldAll.png" /></p> <p>Package the final version of the app by choosing <strong>Package For Phone | Barcode</strong> from the Component Designer menu. When the barcode appears, use the barcode scanner on your phone to download and install the app.</p> <h4 class="ai-header">Variations</h4> <p>Once you get this program running, you may want to do the following additional features to extend it. For example,</p> <ul><li>Create a label to display the time that it took you to get all the gold</li> <li>Change the speed of the ship or gold coins</li> <li>Add an enemy sprite that when collided with, causes your pirate to lose speed</li> <li>Use one of the phone's sensors to control movement of the pirate ship </li> </ul><h4 class="ai-header">Scan the Sample App to your Phone</h4> <p>Scan the following barcode onto your phone to install and run the sample app. </p><p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/GetTheGold/GetTheGoldBarcode.png" /></p> <h4 class="ai-header">Download Source Code</h4> <p>If you'd like to work with this sample in App Inventor, download the <a href="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/GetTheGold/GetTheGold.aia">source code</a> to your computer, then open App Inventor, go to the My Projects page, and choose <b>More Actions | Upload Source</b>.</p> <p>Done with <span style="color:black;">GetTheGold</span>? Return to to the other App Inventor 2 tutorials <a href="http://explore.appinventor.mit.edu/ai2/tutorials">here</a>.</p> </div></div></div><section class="field field-name-field-version field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Version:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-version/app-inventor-2" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">App Inventor 2</a> </li> </ul> </section> <section class="field field-name-field-tutorial-difficulty field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Difficulty:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-difficulty/advanced" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Advanced</a> </li> </ul> </section> <section class="field field-name-field-tutorial-type field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Type:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-type/clock-timer" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Clock Timer</a> </li> <li class="field-item odd"> <a href="/tutorial-type/game" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Game</a> </li> <li class="field-item even"> <a href="/tutorial-type/sprites" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Sprites</a> </li> </ul> </section> Mon, 01 Jul 2013 18:09:32 +0000 aaron 347 at http://dev-explore.appinventor.mit.edu http://dev-explore.appinventor.mit.edu/ai2/get-gold#comments Get the Gold http://dev-explore.appinventor.mit.edu/get-gold <div class="field field-name-body field-type-text-with-summary field-label-hidden view-mode-rss"><div class="field-items"><div class="field-item even" property="content:encoded"><style> <!--/*--><![CDATA[/* ><!--*/ .ButtonText { color:green; font-weight: bold; } li { padding-bottom: 7px; } .basicblock { border: 1px dashed #7AA81C; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #E7F2CB; font-size: 9pt; text-wrap: suppress; } .callblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #E0D1FF; font-size: 9pt; text-wrap: suppress; } .argblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #E5E5FF; font-size: 9pt; text-wrap: suppress; } .textblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #FADAA0; font-size: 9pt; text-wrap: suppress; } .setblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #C1D5F8; font-size: 9pt; text-wrap: suppress; } .controlblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #FAEDBB; font-size: 9pt; text-wrap: suppress; } .listblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #FCF5D7; font-size: 9pt; text-wrap: suppress; } /*--><!]]>*/ </style><h4 class="ai-header">What You're Building</h4> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/Teach/GetTheGold/GetTheGoldMain.png" style="float:right; height: 453px; width: 197px;" /></p> <p> By building the <span style="color:green;">Get The Gold App</span> you will get practice with setting visibility, using Clock components and Timers, and detecting collisions in App Inventor. You'll program an application that has a pirate ship whose goal is to collect all the gold on the screen.</p> <h4 class="ai-header">Getting Started</h4> <p>Connect to the App Inventor web site and start a new project. Name it <span style="color:green;">GetTheGold</span>, and also set the screen's <strong style="color:green;">Title</strong> to "GetTheGold". Open the Blocks Editor and connect to a device or emulator.</p> <h4 class="ai-header">Introduction</h4> <p>This tutorial introduces the following skills, useful for future game development:</p> <ul><li>Using the Clock component</li> <li>Using Clock.Timer to move sprites</li> <li>Using Sprite.Flung to move a sprite </li> <li>Using collision detection</li> </ul><h4 class="ai-header">Getting Ready</h4> <p>For this game, you will have two types of imagesprites: pirate and gold coin. Click below to download the image file for your sprites.</p> <p><a href="http://explore.appinventor.mit.edu/sites/all/files/Teach/GetTheGold/pirateship.jpeg"><img src="http://explore.appinventor.mit.edu/sites/all/files/Teach/GetTheGold/pirateship.jpeg" /></a><br /><a href="http://explore.appinventor.mit.edu/sites/all/files/Teach/GetTheGold/goldcoin.jpeg"><img src="http://explore.appinventor.mit.edu/sites/all/files/Teach/GetTheGold/goldcoin.jpeg" /></a></p> <h4 class="ai-header">Set up the Components</h4> <p>Use the component designer to create the interface for <span style="color:green;">GetTheGold</span>. When you finish, it should look something like the snapshot below (more detailed instructions below the snapshot).</p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/Teach/GetTheGold/GetTheGoldDesigner.png" /></p> <p>To create this interface, put the following components into the Designer by dragging them from the Component Palette into the Viewer.</p> <table><tr style="background-color: #EFEFEF; font-weight: bold;"><td> Component Type </td> <td> Palette Group </td> <td> What you'll name it </td> <td> Purpose of Component </td> </tr><tr><td><strong>Canvas</strong></td> <td>Basic</td> <td style="color:green;">Canvas1</td> <td>The background that we will be putting our imagesprites on</td> </tr><tr><td><strong>ImageSprite</strong></td> <td>Animation</td> <td style="color:green;">PirateSprite</td> <td>The pirate ship in our game</td> </tr><tr><td><strong>ImageSprite</strong></td> <td>Animation</td> <td style="color:green;">ImageSprite2</td> <td>One of the gold coins in the game</td> </tr><tr><td><strong>ImageSprite</strong></td> <td>Animation</td> <td style="color:green;">ImageSprite3</td> <td>One of the gold coins in the game</td> </tr><tr><td><strong>ImageSprite</strong></td> <td>Animation</td> <td style="color:green;">ImageSprite4</td> <td>One of the gold coins in the game</td> </tr><tr><td><strong>ImageSprite</strong></td> <td>Animation</td> <td style="color:green;">ImageSprite5</td> <td>One of the gold coins in the game</td> </tr><tr><td><strong>ImageSprite</strong></td> <td>Animation</td> <td style="color:green;">ImageSprite6</td> <td>One of the gold coins in the game</td> </tr><tr><td><strong>Clock</strong></td> <td>Basic</td> <td style="color:green;">Clock1</td> <td>We use the Clock for its Timer method to move the coins</td> </tr><tr><td><strong>Button</strong></td> <td>Basic</td> <td style="color:green;">ResetButton</td> <td>To reset the game so the player can play again</td> </tr></table><p>Set the properties of the components as described below:</p> <table><tr style="background-color: #EFEFEF; font-weight: bold;"><td><strong>Component</strong></td> <td><strong>Action</strong></td> </tr><tr><td><span style="color:green;">ResetButton</span> </td> <td> Change <span class="ButtonText">Text</span> property to "Reset". </td> <td> </td> </tr><tr><td><span style="color:green;">PirateSprite</span> </td> <td> Change <span class="ButtonText">Speed</span> property to 6. </td> <td> Upload the pirateship image and set <span class="ButtonText">Picture</span> property to pirateship. </td> </tr><tr><td><span style="color:green;">ImageSprite(2,3,4,5,6)</span> </td> <td> Upload the goldcoin image and set <span class="ButtonText">Picture</span> property to goldcoin. </td> <td> </td> </tr><tr><td><span style="color:green;">Clock</span> </td> <td> Change <span class="ButtonText">TimerInterval</span> property to 2000. </td> <td> </td> </tr></table><h4 class="ai-header">Moving the Pirate</h4> <p> To move the PirateSprite, we want the user to be able to "fling" the sprite in the direction that they choose. To do this, we will use the <span class="basicblock">PirateSprite.Flung</span> event handler. </p> <p> You may notice that <span class="basicblock">PirateSprite.Flung</span> takes in 6 attributes: x, y, xvel, yvel, speed, and heading. We want to reassign PirateSprite's current heading to the heading given to us from PirateSprite.Flung. This means that the user can now control the direction of the pirate ship with their fingers by flinging on the screen. </p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/Teach/GetTheGold/PirateSpriteFlung.png" /></p> <p>To prevent the pirate from moving off the screen, we will also use PirateSprite.Bounce when an edge is reached. </p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/Teach/GetTheGold/PirateSpriteBounce.png" /></p> <h4 class="ai-header">Moving the Coins</h4> <p> We want the coins to move to random positions on the screen. We will use <span class="basicblock">Clock1.Timer </span> and the ImageSprite's MoveTo method to do this. </p> <p> When the Clock1.Timer goes off, we want all of our gold coin ImageSprites to move to a new random location on the Canvas. We will do this by using the <span class="basicblock">Sprite.MoveTo</span> block. </p> <p>MoveTo takes in two arguments: the x and y coordinates on the canvas of the new position we want the sprite to move to. We want the Sprite to move to a new <i>random</i> location so we will use the <span class="basicblock">random integer</span> block found in the Math box. Since we want each Gold ImageSprite to move to a new location, we repeat this process for each sprite's MoveTo function. </p> <p>For ImageSprite2, we want x to be a random integer from 0 to <i>Canvas1.Width-ImageSprite2.Width</i> and y to be a random integer from 0 to <i>Canvas1.Height-ImageSprite2.Height</i>. This is to be repeated for all the Gold Image Sprites.</p> <p>Remember that sprites are measured at the upper left corner as (0,0) so if we don't want them to go off the screen, we need to take the sprite's height/width into account when setting the range for our random numbers.</p> <p>We will do this by setting up our blocks as in the image below:</p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/Teach/GetTheGold/ClockTimer.png" /></p> <h4 class="ai-header">Detecting Collisions</h4> <p> App Inventor detects collisions by checking for an intersection between the bounding rectangles of each ImageSprite. We call this rectangle-based collision detection. As you can see in the image below, sprites with circular or polygon shape will appear to collide because of the rectangular bounds around them when they might not actually be colliding.</p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/Teach/GetTheGold/CollisionDetection.png" /></p> <p>We can use the <span class="basicblock">PirateSprite.CollidedWith </span> event handler to detect whenever the pirate ship collides with another sprite or gold coin. You may notice that <span class="basicblock">PirateSprite.CollidedWith </span> takes in an argument. This argument is the object that PirateSprite just collided with. We will be testing inside the handler for which object so the name of this argument is not significant. You can name it other. </p> <p>Whenever the pirate collides with a gold coin, we want the coin to disappear. We can do this by setting the coin's visibility to false. To find which coin the pirate collided with, we will use the <span class="basicblock">PirateSprite.CollidingWith</span>. </p> <p> We can use <span class="basicblock">PirateSprite.CollidingWith</span> to take in a component (each of the gold coin sprites) to detect which sprite was hit. This is a component block and NOT a text block with the words ImageSprite inside. The component block can be found in the drawer for each component. If a sprite was hit, we will set its visibility to false. </p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/Teach/GetTheGold/CollisionSprites.png" /></p> <h4 class="ai-header">Reset Button</h4> <p>After the user hits all of the gold sprites with the pirate ship, none of them will be visible. The reset button should set all of the gold sprites' visibility to true. </p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/Teach/GetTheGold/ResetVis.png" /></p> <h4 class="ai-header">Complete Program</h4> <p>Here's the complete <strong><span style="color:green;">GetTheGold</span></strong> program.</p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/Teach/GetTheGold/GetTheGoldAll.png" /></p> <p>Package the final version of the app by choosing <strong>Package For Phone | Barcode</strong> from the Component Designer menu. When the barcode appears, use the barcode scanner on your phone to download and install the app.</p> <h4 class="ai-header">Variations</h4> <p>Once you get this program running, you may want to do the following additional features to extend it. For example,</p> <ul><li>Create a label to display the time that it took you to get all the gold</li> <li>Change the speed of the ship or gold coins</li> <li>Add an enemy sprite that when collided with, causes your pirate to lose speed</li> <li>Use one of the phone's sensors to control movement of the pirate ship </li> </ul><h4 class="ai-header">Scan the Sample App to your Phone</h4> <p>Scan the following barcode onto your phone to install and run the sample app. </p><p><img src="http://explore.appinventor.mit.edu/sites/all/files/Teach/GetTheGold/GetTheGoldBarcode.png" /></p> <h4 class="ai-header">Download Source Code</h4> <p>If you'd like to work with this sample in App Inventor, download the <a href="http://explore.appinventor.mit.edu/sites/all/files/Teach/GetTheGold/GetTheGold.zip">source code</a> to your computer, then open App Inventor, go to the My Projects page, and choose <b>More Actions | Upload Source</b>.</p> <p>Done with <span style="color:black;">GetTheGold</span>? Return to to the other modules <a href="/teach/module-2-2">here</a> or the tutorials <a href="/tutorials">here</a>.</p> </div></div></div><section class="field field-name-field-version field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Version:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-version/app-inventor-1" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">App Inventor 1</a> </li> </ul> </section> <section class="field field-name-field-tutorial-difficulty field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Difficulty:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-difficulty/advanced" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Advanced</a> </li> </ul> </section> <section class="field field-name-field-tutorial-type field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Type:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-type/clock-timer" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Clock Timer</a> </li> <li class="field-item odd"> <a href="/tutorial-type/game" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Game</a> </li> <li class="field-item even"> <a href="/tutorial-type/sprites" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Sprites</a> </li> </ul> </section> Fri, 28 Jun 2013 21:35:19 +0000 aaron 346 at http://dev-explore.appinventor.mit.edu http://dev-explore.appinventor.mit.edu/get-gold#comments MoleMash 2 http://dev-explore.appinventor.mit.edu/content/molemash-2 <div class="field field-name-body field-type-text-with-summary field-label-hidden view-mode-rss"><div class="field-items"><div class="field-item even" property="content:encoded"><style> <!--/*--><![CDATA[/* ><!--*/ li { padding-bottom: 7px; } .basicblock { border: 1px dashed #7AA81C; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #E7F2CB; font-size: 9pt; text-wrap: suppress; } .callblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #E0D1FF; font-size: 9pt; text-wrap: suppress; } .argblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #E5E5FF; font-size: 9pt; text-wrap: suppress; } .textblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #FADAA0; font-size: 9pt; text-wrap: suppress; } .setblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #C1D5F8; font-size: 9pt; text-wrap: suppress; } .controlblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #FAEDBB; font-size: 9pt; text-wrap: suppress; } .listblock { border: 1px dashed #000000; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #FCF5D7; font-size: 9pt; text-wrap: suppress; } /*--><!]]>*/ </style><h4 class="ai-header">What You're Building</h4> <p><img src="/sites/all/files/tutorials/moleMash2/front-pic.png" style="float:right;" /></p> <p><a href="http://cs.usfca.edu/~wolber/appinventor/bookSplits/ch3MoleMash.pdf">Download Refined Version (Book Chapter PDF)</a></p> <p>This tutorial shows you how to build a game similar to the Whac-A-MoleTM arcade game. Specifically, your goal is to whack (tap) a mole that randomly pops out of one of five fixed holes. Every time you succeed, your score is increased by one point.</p> <p>In order to highlight new App Inventor features — the Advanced tab and Sprite Z-layering — this app takes a different approach than the <a href="http://explore.appinventor.mit.edu/content/molemash">original Mole Mash tutorial</a>, which you need not have read in order to do this one. You should, however, be familiar with the basics of App Inventor — using the Component Designer to build a user interface and using the Blocks Editor to specify event handlers. If you are not familiar with the basics, try stepping through some of the <a href="/tutorials">basic tutorials</a> before continuing.</p> <h4 class="ai-header">Introduction</h4> <p>This tutorial includes:</p> <ol><li>Creating a list of components</li> <li>Using functionality from the Advanced section of the Blocks Editor to get and set properties of arbitrary components</li> <li>Having game events controlled by the <b>Clock</b> component</li> <li>Using Sprite Z-layering to ensure that one sprite (<b>ImageSprite</b> or <b>Ball</b>) appears in front of another</li> </ol><h4 class="ai-header">Getting Started</h4> <p>Connect to the App Inventor web site and start a new project. Set the screen's <b style="color:green;">Title</b> property to an appropriate name, such as "Mole Mash". Open the Blocks Editor and connect it to the phone. Download these image files (created by Yun Miao) by right-clicking on them, then add them to the project by pressing the "Add..." button in the Media pane.</p> <p><a href="/sites/all/files/tutorials/moleMash2/hole.png"><img src="/sites/all/files/tutorials/moleMash2/hole.png" /></a><a href="/sites/all/files/tutorials/moleMash2/mole.png"><img src="/sites/all/files/tutorials/moleMash2/mole.png" /></a></p> <h4 class="ai-header">Set up the Components</h4> <p>The user interface will contain a total of 6 ImageSprites: 5 unmoving holes and 1 mole, which will move on top of the holes. Use the component designer to create the user interface. When you are done, it should look something like the picture below. Don't worry about lining up the holes evenly. You will specify their locations through their <b style="color:green;">X</b> and <b style="color:green;">Y</b> properties. Additional instructions are below the picture.</p> <p><img src="/sites/all/files/tutorials/moleMash2/designer1.png" /></p> <p>Create the following components by dragging them from the Palette into the Viewer.</p> <table><tr style="background-color: #EFEFEF; font-weight: bold;"><td> Component Type </td> <td> Palette Group </td> <td> What you'll name it </td> <td> Purpose of Component </td> </tr><tr><td> <b>Canvas</b> </td> <td>Basic</td> <td style="color:green;">GameCanvas</td> <td>The game field</td> </tr><tr><td> <b>ImageSprite</b> (5) </td> <td>Animation</td> <td style="color:green;">Hole1 ... Hole5</td> <td>Holes from which the mole can appear</td> </tr><tr><td> <b>ImageSprite</b> </td> <td>Animation</td> <td style="color:green;">Mole</td> <td>The mole</td> </tr><tr><td> <b>HorizontalArrangement</b> </td> <td>Screen Arrangement</td> <td style="color:green;">ScoreArrangement</td> <td>To display the score</td> </tr><tr><td> <b>Label</b> </td> <td>Basic</td> <td style="color:green;">ScoreTextLabel</td> <td>To hold "Score: "</td> </tr><tr><td> <b>Label</b> </td> <td>Basic</td> <td style="color:green;">ScoreValueLabel</td> <td>To hold the score (# of times the mole was hit)</td> </tr><tr><td> <b>Clock</b> </td> <td>Basic</td> <td style="color:green;">MoleClock</td> <td>To control the mole's movement</td> </tr><tr><td> <b>Sound</b> </td> <td>Media</td> <td style="color:green;">Buzzer</td> <td>To vibrate when the mole is touched</td> </tr></table><p>Make the following changes to the components' properties:</p> <table><tr style="background-color: #EFEFEF; font-weight: bold;"><td> Component </td> <td> Action </td> </tr><tr><td>Canvas1</td> <td>Set <b style="color:green;">BackgroundColor</b> to Green. Set <b style="color:green;">Width</b> to 320 pixels. Set <b style="color:green;">Height</b> to 320 pixels.</td> </tr><tr><td>Hole1</td> <td>Set <b style="color:green;">X</b> to 20 and <b style="color:green;">Y</b> to 60 (upper left).</td> </tr><tr><td>Hole2</td> <td>Set <b style="color:green;">X</b> to 130 and <b style="color:green;">Y</b> to 60 (upper center).</td> </tr><tr><td>Hole3</td> <td>Set <b style="color:green;">X</b> to 240 and <b style="color:green;">Y</b> to 60 (upper right)</td> </tr><tr><td>Hole4</td> <td>Set <b style="color:green;">X</b> to 75 and <b style="color:green;">Y</b> to 140 (lower left).</td> </tr><tr><td>Hole5</td> <td>Set <b style="color:green;">X</b> to 185 and <b style="color:green;">Y</b> to 140 (lower right).</td> </tr><tr><td>Mole</td> <td>Set <b style="color:green;">Picture</b> to "mole.png". Set <b style="color:green;">Z</b> to 2 so the mole appears in front of the other <b style="color:green;">ImageSprite</b> s, which have the default <b style="color:green;">Z</b> value of 1.</td> </tr><tr><td>ScoreTextLabel</td> <td>Set <b style="color:green;">Text</b> to "Score: ".</td> </tr><tr><td>ScoreTextValue</td> <td>Set <b style="color:green;">Text</b> to "0".</td> </tr></table><p>Don't worry now about setting the <b style="color:green;">Picture</b> property for the holes; we'll set the property in the Blocks Editor.</p> <h4 class="ai-header">Add Behaviors to the Components</h4> <p>Here is an overview of what we need to create blocks to do:</p> <ol><li>Create variables: <ol><li><b style="color:green;">holes</b>: a list of holes</li> <li><b style="color:green;">currentHole</b>: the hole the mole is currently coming out of</li> </ol></li> <li>When the app starts: <ol><li>Populate the list of holes.</li> <li>Set each hole's <b style="color:green;">Picture</b> property to "hole.png".</li> <li>Call procedure <span class="callblock">MoveMole</span> (below).</li> </ol></li> <li>Create a procedure <span class="callblock">MoveMole</span> to: <ol><li>Set <b style="color:green;">currentHole</b> to a random hole from the list <b style="color:green;">holes</b>.</li> <li>Move the mole to the location of <b style="color:green;">currentHole</b>.</li> </ol></li> <li>Make <b>MoleClock</b> call <span class="callblock">MoveMole</span> whenever its timer goes off (every second). </li> <li>Implement a handler that does the following when the mole is touched: <ol><li>Add one to the score.</li> <li>Make the phone briefly vibrate.</li> <li>Call <span class="callblock">MoveMole</span>.</li> </ol></li> </ol><p>To proceed, open the Blocks Editor.</p> <h4 class="ai-header">Creating Variables</h4> <p>Create the variables <b style="color:green;">holes</b> and <b style="color:green;">currentHole</b>. For now, we will give them "dummy" initial values; we'll set their real initial values in the <span class="basicblock">Screen1.Initialize</span> event handler, which is run when the app starts. (For technical reasons, components cannot be referred to in def blocks, which are run before the app has started.) Here is a picture and list of the blocks you will need:</p> <p><img src="/sites/all/files/tutorials/moleMash2/blocks1.png" /></p> <table><tr style="background-color: #EFEFEF; font-weight: bold;"><td> Block type </td> <td> Drawer </td> <td> Purpose </td> </tr><tr><td><span class="setblock">def variable as</span> (holes)</td> <td>Definition</td> <td>Hold a list of holes.</td> </tr><tr><td><span class="listblock">make a list</span></td> <td>Lists</td> <td>Create an empty list, to be filled in when the program starts.</td> </tr><tr><td><span class="setblock">def variable as</span> (currentHole)</td> <td>Definition</td> <td>Hold the mole's current hole.</td> </tr><tr><td><span class="basicblock">number</span> (0)</td> <td>Numbers</td> <td>Provide a required initial value for <b style="color:green;">currentHole</b>.</td> </tr></table><p>As always, comments (created by right-clicking on a block) are encouraged but not required.</p> <h4 class="ai-header">Starting the App</h4> <p>The first event to occur in any program in <span class="basicblock">Screen1.Initialize</span>, so we will put start-up code in that handler. Specifically, we will add the hole components to the list holes, set each hole's <b style="color:green;">Picture</b> property to "hole.png", and call <span class="callblock">MoveMole</span>. Since we have not yet written MoveMole, we will create an empty procedure with that name, which we will fill in later.</p> <p>Below are a picture and table of the blocks you need to create. Note that the "Any ImageSprite" drawer is found under the "Advanced" tab to the right of "Built-In" and "My Blocks" in the Blocks Editor.</p> <p><img src="/sites/all/files/tutorials/moleMash2/blocks2.png" /></p> <table><tr style="background-color: #EFEFEF; font-weight: bold;"><td> Block type </td> <td> Drawer </td> <td> Purpose </td> </tr><tr><td><span class="basicblock">Screen1.Initialize</span></td> <td>Screen1</td> <td>Specify what should happen when the app starts.</td> </tr><tr><td><span class="listblock">add items to list</span></td> <td>Lists</td> <td>Add the following values to...</td> </tr><tr><td><span class="argblock">holes</span></td> <td>My Definitions</td> <td>...the list of holes:</td> </tr><tr><td><span class="argblock">component Hole1</span></td> <td>Hole1</td> <td>-the upper left hole</td> </tr><tr><td><span class="argblock">component Hole2</span></td> <td>Hole2</td> <td>-the upper center hole</td> </tr><tr><td><span class="argblock">component Hole3</span></td> <td>Hole3</td> <td>-the upper right hole</td> </tr><tr><td><span class="argblock">component Hole4</span></td> <td>Hole4</td> <td>-the lower left hole</td> </tr><tr><td><span class="argblock">component Hole5</span></td> <td>Hole5</td> <td>-the lower right hole</td> </tr><tr><td><span class="controlblock">foreach</span></td> <td>Control</td> <td>Specify that we would like...</td> </tr><tr><td><span class="argblock">name</span> (hole)</td> <td>Definitions</td> <td>...a variable named "hole"...</td> </tr><tr><td><span class="argblock">holes</span></td> <td>My Definitions</td> <td>...to take on each of the values in the list holes .</td> </tr><tr><td><span class="setblock">ImageSprite.Picture</span></td> <td>Any Image Sprite</td> <td>Set the Picture property of...</td> </tr><tr><td><span class="argblock">value hole</span></td> <td>My Definitions</td> <td>...the ImageSprite referred to by the variable hole ...</td> </tr><tr><td><span class="textblock">text (hole.png)</span></td> <td>Text</td> <td>...to the picture of the empty hole.</td> </tr><tr><td><span class="callblock">to procedure</span> (MoveMole)</td> <td>Definition</td> <td>Create an procedure, to be filled in later, for moving the mole.</td> </tr><tr><td><span class="callblock">MoveMole</span></td> <td>My Definitions</td> <td>Call MoveMole to make the first placement of the mole.</td> </tr></table><p>Compare the <span class="controlblock">foreach</span> block to the equivalent blocks that would be necessary without it:</p> <p><img src="/sites/all/files/tutorials/moleMash2/molemash2.JPG" /></p> <p>Not only is the left set of blocks shorter, it is less repetitious, sparing the programmer from semi-mindless copy-and-pasting and making it easier to modify, for example, if the name of the picture is changed.</p> <h4 class="ai-header">Moving the Mole</h4> <p>Now let's fill in the body of the procedure MoveMole, which we'll call when the program starts, when the mole gets touched, and when our timer goes off every second. What we want it to do is to pick a random hole and move the mole on top of it. Here are a picture and list of the new blocks:</p> <p><img src="/sites/all/files/tutorials/moleMash2/blocks4.png" /></p> <table><tr style="background-color: #EFEFEF; font-weight: bold;"><td> Block type </td> <td> Drawer </td> <td> Purpose </td> </tr><tr><td><span class="setblock">set currentHole to</span></td> <td>My Definitions</td> <td>Save the...</td> </tr><tr><td><span class="listblock">call pick random item</span></td> <td>Lists</td> <td>...randomly selected...</td> </tr><tr><td><span class="argblock">holes</span></td> <td>My Definitions</td> <td>...hole.</td> </tr><tr><td><span class="basicblock">call Mole.MoveTo</span></td> <td>Mole</td> <td>Move the mole to the...</td> </tr><tr><td><span class="argblock">ImageSprite.X</span></td> <td>Advanced/ImageSprite</td> <td>..x-coordinate of...</td> </tr><tr><td><span class="argblock">currentHole</span></td> <td>My Definitions</td> <td>...the chosen hole...</td> </tr><tr><td><span class="argblock">ImageSprite.Y</span></td> <td>Advanced/ImageSprite</td> <td>...and the y-coordinate of...</td> </tr><tr><td><span class="argblock">current Hole</span></td> <td>My Definitions</td> <td>...the chosen hole.</td> </tr></table><p>We now need to specify that MoveMole should be called whenever MoleClock's Timer goes off. We just need two blocks to accomplish that:</p> <p><img src="/sites/all/files/tutorials/moleMash2/blocks5.png" /></p> <table><tr style="background-color: #EFEFEF; font-weight: bold;"><td> Block type </td> <td> Drawer </td> <td> Purpose </td> </tr><tr><td><span class="basicblock">MoleClock.Timer</span></td> <td>MoleClock</td> <td>When the timer goes off...</td> </tr><tr><td><span class="callblock">call MoveMole</span></td> <td>My Definitions</td> <td>...move the mole.</td> </tr></table><h4 class="ai-header">Registering Touches</h4> <p>Finally, we need to specify what happens when the mole is touched. Specifically, we want to:</p> <ol><li>Increment the score.</li> <li>Make the phone vibrate briefly.</li> <li>Move the mole.</li> </ol><p>We can easily translate these to blocks:</p> <p><img src="/sites/all/files/tutorials/moleMash2/blocks6.png" /></p> <table><tr style="background-color: #EFEFEF; font-weight: bold;"><td> Block type </td> <td> Drawer </td> <td> Purpose </td> </tr><tr><td><span class="basicblock">Mole.Touched</span></td> <td>Mole</td> <td>When the mole is touched...</td> </tr><tr><td><span class="setblock">set ScoreValueLabel.Text to</span></td> <td>ScoreValueLabel</td> <td>...update the visible score to...</td> </tr><tr><td><span class="basicblock"> block</span></td> <td>Math</td> <td>...the result of adding...</td> </tr><tr><td><span class="basicblock">number</span> (1)</td> <td>Math</td> <td>...1 [and]...</td> </tr><tr><td><span class="argblock">ScoreValueLabel.Text</span></td> <td>ScoreValueLabel</td> <td>...the previous score.</td> </tr><tr><td><span class="callblock">call Buzzer.Vibrate</span></td> <td>Buzzer</td> <td>Make the phone vibrate for...</td> </tr><tr><td><span class="basicblock">number</span> (100)</td> <td>Math</td> <td>...100 milliseconds.</td> </tr><tr><td><span class="callblock">call MoveMole</span></td> <td>My Definitions</td> <td>Move the mole to a new location.</td> </tr></table><h4 class="ai-header">Final Program</h4> <p><img src="/sites/all/files/tutorials/moleMash2/blocks-final.png" /></p> <h4 class="ai-header">Variations</h4> <p>Here are some variations you might want to implement:</p> <ul><li>Adding a Reset button to set the score back to 0.</li> <li>Having the score depend not just on the number of hits but also the number of misses and escaped moles.</li> <li>Increasing the speed of the game of mole movement if the player is doing well and decreasing it if the player is doing poorly.</li> <li>Adding a second mole on a different timer.</li> </ul><p>You can see how to implement the first two variations in the <a href="http://explore.appinventor.mit.edu/content/molemash">original Mole Mash tutorial</a>.</p> <h4 class="ai-header">Review</h4> <p>Here are some of the ideas covered in this tutorial:</p> <ul><li>Putting components in a <b>List</b>.</li> <li>Performing an operation on every component in a <b>List</b> using the <span class="controlblock">foreach</span> block and Advanced features.</li> <li>Placing an <b>ImageSprite</b> on top of another, using their <b style="color:green;">Z</b> properties to control which goes in front.</li> <li>Using the <b>Clock</b> component to control game play.</li> <li>Creating a procedure and calling it from multiple places.</li> </ul><pre class="ai-box">Done with <span style="color:black;">MoleMash 2</span>? Return to the other tutorials <a href="/tutorials">here</a>.</pre><h4 class="ai-header">Scan the Sample App to your Phone</h4> <p>Scan the following barcode onto your phone to install and run the sample app. </p><p><img src="/sites/all/files/tutorials/moleMash2/MoleMash2Barcode.png" /></p> <p>Or <a href="http://explore.appinventor.mit.edu/sites/all/files/tutorials/moleMash2/MoleMash2.apk">download the apk</a></p> <h4 class="ai-header">Download Source Code</h4> <p>If you'd like to work with this sample in App Inventor, download the <a href="http://explore.appinventor.mit.edu/sites/all/files/tutorials/moleMash2/MoleMash2.zip">source code</a> to your computer, then open App Inventor, go to the My Projects page, and choose <b>More Actions | Upload Source</b>.</p> </div></div></div><section class="field field-name-field-version field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Version:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-version/app-inventor-1" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">App Inventor 1</a> </li> </ul> </section> <section class="field field-name-field-tutorial-difficulty field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Difficulty:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-difficulty/advanced" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Advanced</a> </li> </ul> </section> <section class="field field-name-field-tutorial-type field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Type:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-type/clock-timer" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Clock Timer</a> </li> <li class="field-item odd"> <a href="/tutorial-type/game" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Game</a> </li> <li class="field-item even"> <a href="/tutorial-type/sprites" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Sprites</a> </li> </ul> </section> Wed, 26 Jun 2013 19:45:48 +0000 aaron 338 at http://dev-explore.appinventor.mit.edu http://dev-explore.appinventor.mit.edu/content/molemash-2#comments Mini Golf: Fling, TouchUp, TouchDown Gestures http://dev-explore.appinventor.mit.edu/content/minigolf <div class="field field-name-body field-type-text-with-summary field-label-hidden view-mode-rss"><div class="field-items"><div class="field-item even" property="content:encoded"><p>This Mini Golf App demonstrates how to use the Fling, TouchUp, and TouchDown gestures for Sprites<br />Note that these event handlers are also available for the Canvas.</p> <p><img src="/sites/all/files/tutorials/miniGolf/GolfSampleScreen.png" style="float: right;border:none" width="250" /></p> <p>To play this mini golf app, the player first positions his/her ball within the confines of the tee, and then flings the ball toward the hole. The ball will bounce off of the rectangular obstacle and the sides of the course. For each fling of the ball, the stroke count goes up by one. The total score is the number of strokes it takes to complete the entire course. </p> <p>This tutorial covers:</p> <ul><li>Using the <b>Sprite</b> component and the TouchUp, TouchDown, and Flung events</li> <li>Using a <b>Clock</b> component</li> <li>Dynamic Positioning of sprites on a canvas, based on the size of the screen</li> <li>Sprite Collisions</li> </ul><p>This tutorial assumes you are familiar with the basics of App Inventor-- using the Component Designer to build a user interface, and using the Blocks Editor to specify the app's behavior. If you are not familiar with the basics, try stepping through some of the <a href="http://appinventor.mit.edu/explore/tutorials.html">basic tutorials</a> before continuing.</p> <p><a href="/sites/all/files/tutorials/miniGolf/FlingitMiniGolfTutorial.zip"><img src="/sites/all/files/tutorials/miniGolf/downloadSourcebutton.png" style="float: right; border:none" width="250" /></a><br /><br /><br /><br /></p> <hr /><h3>Part I: Start a new app and make a ball that responds to fling events</h3> <p>We'll build this app in stages, adding a little bit of the game at a time. Log into App Inventor and start a new project. Name it "MiniGolf". When the Design window opens notice that App Inventor automatically names the screen "Screen1", but you can set the Title of the screen, which will show up in the top bar of the app. Think of a title related to Mini Golf, or feel free to use the suggested title "Flingit Mini Golf", and type it into the Properties pane on the right side of the Designer.</p> <p>In the Screen Properties (shown in right-hand pane): Uncheck the checkbox labeled "Scrollable" so that the screen will not scroll when the app is running. Screens that are set to scroll do not have a height. We’ll need our screen to have a defined height in order to set up the golf course properly.</p> <p><strong>Add the following components in the Designer:</strong></p> <table cellpadding="0" cellspacing="0"><tbody><tr style="background-color: #EFEFEF; font-weight: bold;"><td> <p><strong>Component Type</strong></p> </td> <td> <p><strong>Palette Group</strong></p> </td> <td> <p><strong>What You'll Name It</strong></p> </td> <td> <p><strong>Purpose</strong></p> </td> <td> <p><strong>Properties</strong></p> </td> </tr><tr><td> <p>Canvas1</p> </td> <td> <p>Basic</p> </td> <td> <p>Canvas1</p> </td> <td> <p>The canvas serves as the golf course</p> </td> <td> <p>Height: 300<br />Width: FillParent<br />BackgroundColor: Green (or whatever you like!)</p> </td> </tr><tr><td> <p>BallSprite</p> </td> <td> <p>Animation</p> </td> <td> <p>GolfBall</p> </td> <td> <p>This is the ball the player will fling to try to hit the Hole</p> </td> <td> <p>Radius = 10<br />Color: White (or your choice!)<br />Speed: 0<br />Interval: 1 (ms)</p> <p>Z = 2 (this makes the sprite appear on top of sprites with lower numbers)</p> </td> </tr><tr><td> <p>BallSprite</p> </td> <td> <p>Animation</p> </td> <td> <p>Hole</p> </td> <td> <p>This will be the target for the GolfBall</p> </td> <td> <p>Radius = 15<br />Color: Black<br />Speed: 0</p> </td> </tr><tr><td> <p>Clock1</p> </td> <td> <p>Basic</p> </td> <td> <p>Clock1</p> </td> <td> <p>The clock will fire continuously to control the movement of the ball</p> </td> <td> <p>Timer Always Fires</p> <p>Timer Enabled</p> <p>TimerInterval: 100</p> </td> </tr></tbody></table><p><strong>Open the Blocks Editor</strong></p> <p><strong>Program the behavior of the Ball:</strong></p> <p>First, use the <span class="basicblock">GolfBall.Flung</span> event handler to move the golf ball when it is flung. Essentially, set the GolfBall sprite’s speed and heading to match the speed and heading of the player’s fling gesture. You may want to scale up the speed a little bit because the speed of the fling is a little slower than how a golf ball would move. You can play with this "scaling factor" to make the ball more or less responsive to a fling.</p> <p> <img height="312" src="/sites/all/files/tutorials/miniGolf/golfBall.flung.png" width="564" /></p> <p><strong>Program the behavior of the clock:</strong></p> <p> Use timer event to slow ball down so it doesn’t bounce around forever.</p> <p>Each time the clock fires, it will reduce the speed of the ball slightly. Notice that if the ball is not moving then these blocks will do nothing. If you don’t have this then the ball will just bounce forever.</p> <p><img height="257" src="/sites/all/files/tutorials/miniGolf/clock1.timer.png" width="554" /></p> <p><strong>Program a new procedure called SetupNewHole:</strong></p> <p>This procedure will be called when a hole is scored and the ball has to be placed back at the starting point. Note that the <span class="callblock">Hole.MoveTo</span> block sets the hole up in a new random location for the next play.</p> <p><img height="301" src="/sites/all/files/tutorials/miniGolf/setupNewHole.png" width="671" /></p> <p><strong>Program the Behavior of the Hole: </strong><span>When the ball collides with the hole, the ball disappears and resets at the bottom of the screen.</span></p> <p>Note: When you first drag out the <span class="basicblock">GolfBall.CollidedWith</span> event handler, the named parameter is called "other". You can rename this by clicking once on the word "other" and typing in something new. Use a name that makes sense, as in this example where we use "ObjectHitByGolfBall". Notice that the <span class="controlblock">if then</span> block tests to see if the object involved in the collision with the golf ball (<span class="argblock">ObjectHitByGolfBall</span>) is the black ball sprite representing the hole. You can't just put a text block with the word "Hole" in it, you must use the <span class="argblock">component Hole</span><span> block, that can be found in the Hole drawer under "My Blocks". Do not use a text block here.</span></p> <p><img height="196" src="/sites/all/files/tutorials/miniGolf/golfBall.collidedWith.png" width="502" /></p> <pre class="ai-testing"><strong>Test this Behavior.</strong> Connect your device to AppInventor, or start the emulator to load your app. When you fling the ball it should move in the direction of your fling, with a speed similar to the strength of your fling. The ball should slow down as it moves, eventually stopping. When the ball hits the hole, the ball should reset at the bottom of the screen and the hole should move to a new random location.</pre><p> </p> <p><strong>Does your ball get stuck if it hits the edge? </strong></p> <p>This is easy to fix with the when <span class="basicblock">EdgeReached</span> event. Note that you can find the "edge" value block under My Definitions. You can also use a developer’s shortcut by clicking anywhere on the workspace background and typing the word "edge". You’ll see a dropdown box appear. If you click the word "edge" you’ll see the value edge block appear on the screen. Big time saver!</p> <p><img height="101" src="/sites/all/files/tutorials/miniGolf/golfBall.edgeReached.png" width="334" /></p> <p>Double check to make sure your code is right: fling the ball a few times and see that that ball now bounces off the edges of the course.</p> <h3>Part II: Keeping Score</h3> <p>Games are more fun if you have a way to see how you’re doing. Let’s add a stroke counter. In mini golf your score goes up as you take more strokes. The goal is to have the lowest score possible. Let’s show the player how many strokes she or he has taken on this hole. Let’s also show the number of strokes taken during the whole game.</p> <p> </p> <p>Go back to the Designer and set up the following components:</p> <p><a href="#" name="84f417a34cd2d904669a10a8f96b32bf41ae274b" id="84f417a34cd2d904669a10a8f96b32bf41ae274b"></a><a href="#" name="2" id="2"></a><br /></p><table cellpadding="0" cellspacing="0"><tbody><tr style="background-color: #EFEFEF; font-weight: bold;"><td> <p><strong>Component Type</strong></p> </td> <td> <p><strong>Palette Group</strong></p> </td> <td> <p><strong>What You’ll Name It</strong></p> </td> <td> <p><strong>Purpose</strong></p> </td> <td> <p><strong>Properties</strong></p> </td> </tr><tr><td> <p>Horizontal Arrangement</p> </td> <td> <p>Screen Arrangement</p> </td> <td> <p>HorizontalArrangement1</p> </td> <td> <p>Contains LabelScore and LabelStroke</p> </td> <td> <p>Place at top of screen</p> </td> </tr><tr><td> <p>Label1</p> </td> <td> <p>Basic</p> </td> <td> <p>LabelScore</p> </td> <td> <p>Displays the total stroke count for the entire game</p> </td> <td></td> </tr><tr><td> <p>Label2</p> </td> <td> <p>Basic</p> </td> <td> <p>LabelStroke</p> </td> <td> <p>Displays the stroke count for the hole the player is currently on</p> </td> <td></td> </tr></tbody></table><p>In the Blocks Editor, you can program updates to the Score and Stroke labels. First, set two new global variables called <span class="setblock">StrokeCount</span> and <span class="setblock">Score</span>, and set their initial values to 0.</p> <p><img height="101" src="/sites/all/files/tutorials/miniGolf/strokeCount.png" width="265" /></p> <p>Then add the following blocks to the <span class="basicblock">GoflBall.Flung</span> event (red rectangle indicates new blocks):</p> <p><img height="500" src="/sites/all/files/tutorials/miniGolf/golfBall.flung_final.png" width="592" /></p> <p>Next add the following blocks to the Event that handles the ball hitting the hole:</p> <p><img height="462" src="/sites/all/files/tutorials/miniGolf/golf_collidewith.png" width="607" /></p> <pre class="ai-testing"><strong>Test the behavior.</strong> With these new changes, you should have a "Total Strokes" count and "This Hole" count at the top of the screen. When you fling the ball, the "This Hole" count  and "Total Strokes" count should both increase by one, and when you make the ball go into the hole the "This Hole" count should reset to 0.</pre><h3>Part III: Positioning Ball on Tee using TouchUp and TouchDown events</h3> <p>Ok, so now you’ve got a working game! Now let’s make it a little more interesting and fun. First we’ll add a Tee and let the player position the golf ball on the tee before they fling the ball.</p> <p><strong>Go back to the Designer and add three new image sprite components:</strong></p> <p><a href="#" name="f32e9ebd8bb0c367ac6b009ebba0af05e4eb1b4e" id="f32e9ebd8bb0c367ac6b009ebba0af05e4eb1b4e"></a><a href="#" name="1" id="1"></a><br /></p><table cellpadding="0" cellspacing="0"><tbody><tr style="background-color: #EFEFEF; font-weight: bold;"><td> <p><strong>Component Type</strong></p> </td> <td> <p><strong>Palette Group</strong></p> </td> <td> <p><strong>What You’ll Name It</strong></p> </td> <td> <p><strong>Purpose</strong></p> </td> <td> <p><strong>Properties</strong></p> </td> </tr><tr><td> <p>ImageSprite</p> </td> <td> <p>Animation</p> </td> <td> <p>Tee</p> </td> <td> <p>A rectangular area in which the player can position their ball before teeing off.</p> </td> <td> <p>Upload the Tee image (<a href="/sites/all/files/tutorials/miniGolf/tee_graphic.png">right click on this link</a>, or see below).</p> </td> </tr><tr><td> <p>ImageSprite</p> </td> <td> <p>Animation</p> </td> <td> <p>LeftSprite</p> </td> <td> <p>This is a left pointing arrow that the player will use to move the ball to the left on the tee</p> </td> <td> <p>Upload the left arrow graphic (<a href="/sites/all/files/tutorials/miniGolf/left_arrow.jpg">right click on this link</a></p> </td> </tr><tr><td> <p>ImageSprite</p> </td> <td> <p>Animation</p> </td> <td> <p>RightSprite</p> </td> <td> <p>This is a right pointing arrow that the player will use to move the ball to the left on the tee</p> </td> <td> <p>Upload the right arrow graphic (<a href="/sites/all/files/tutorials/miniGolf/right_arrow.jpg">right click on this link</a></p> </td> </tr></tbody></table><p><strong>Program the size of the canvas, and the placement of the ball and image sprites on the canvas:</strong></p> <p>First, program the setup of these components on the screen. It’s best to accommodate all different screen sizes by placing the sprites on the screen relative to the size of the screen. The blocks below show how to set up the screen <em>dynamically</em><span> so that everything fits the right way. We start off by making the canvas size based on the screen size, and then we place each sprite in relation to the width and height of the canvas. Try to understand all of these blocks before you move on.</span></p> <p><img src="/sites/all/files/tutorials/miniGolf/golf_screen_init.png" /></p> <p><strong>Position the Golf Ball on the Tee using TouchUp and TouchDown on the Arrow sprites:</strong></p> <p>To handle this, first set up two global variables that are toggled each time an arrow is pressed.</p> <p><img height="96" src="/sites/all/files/tutorials/miniGolf/globalMoveRight.png" width="249" /></p> <p><strong>Program the behavior of the Right and Left Arrows</strong></p> <p>The left and right arrows are image sprites, so they come equipped with the ability to know when the player is is holding his/her finger down on them. The following blocks toggle the global variables based on whether the user is pressing either of these arrows.</p> <p><img height="383" src="/sites/all/files/tutorials/miniGolf/leftSprite.touchDown.png" width="599" /></p> <p><strong>Procedure MoveBallOnTee:</strong></p> <p>Make a new procedure <span class="callblock">MoveBallOnTee</span> that makes the golf ball move left or right on the tee depending on the global variables. Although the math here looks complicated, it’s pretty simple. If the ball is supposed to move left, you first check to make sure that moving the ball 2 pixels left will not exceed the left-most coordinate of the Tee. If moving the golf ball to the right, you first check that moving the ball right 2 pixels will not move it past the right-most coordinate of the Tee.</p> <p><img height="368" src="/sites/all/files/tutorials/miniGolf/moveBallOnTee.png" width="701" /></p> <p>On each new course, players can position the ball on the tee before attempting to fling the ball toward the hole. To program this, you first have to check to make sure this is a new course and the ball has not been flung yet. If <span class="argblock">StrokeCount</span> = 0 then we know this course is brand new and the player has not yet attempted to get the ball into the hole.</p> <p><img height="188" src="/sites/all/files/tutorials/miniGolf/clock1.timer_final.png" width="448" /></p> <p>As the blocks above show, after verifying that the StrokeCount is 0, you then want to proceed to move the golf ball left or right depending on which arrow is being pressed. </p> <p>Note that the blocks that we had inside the <span class="basicblock">Clock1.Timer</span> event are now moved over to a new procedure called <span class="callblock">MoveBallOnCourse:</span></p> <p><strong>MoveBallOnCourse Procedure</strong></p> <p><img height="214" src="/sites/all/files/tutorials/miniGolf/moveBallOnCourse.png" width="512" /></p> <pre class="ai-testing"><strong>Test the behavior.</strong> Make sure your app is doing what you expect: play the game on your device or emulator. Before you tee off, are you able to move the ball left and right on the tee by using the left and right arrows? After you tee off, you should no longer be able to use the left and right arrows (pressing them will do nothing). After the ball goes into the hole and the screen resets, you should then be able to move the ball left and right on the tee before teeing off again.</pre><p><strong>Keep track of the number of holes played, and allow a game reset</strong></p> <p>The game is working pretty well now, but what about giving the player a way to reset the game? Also, it would be nice to give the player some instructions so they know how to play the game. While we’re at it, let’s also give an indication of how many holes the player has completed. Add the following components in the Designer:</p> <p><a href="#" name="0899df2ccc45cb7f22bfe41d004593ed854f9f2c" id="0899df2ccc45cb7f22bfe41d004593ed854f9f2c"></a><a href="#" name="3" id="3"></a><br /></p><table cellpadding="0" cellspacing="0"><tbody><tr style="background-color: #EFEFEF; font-weight: bold;"><td> <p><strong>Component Type</strong></p> </td> <td> <p><strong>Palette Group</strong></p> </td> <td> <p><strong>What You’ll Name It</strong></p> </td> <td> <p><strong>Purpose</strong></p> </td> <td> <p><strong>Properties</strong></p> </td> </tr><tr><td> <p>Horizontal Arrangement2</p> </td> <td> <p>Screen Arrangement</p> </td> <td> <p>Horizontal Arrangement2</p> </td> <td> <p>Contains the NewGame button and the HoleNum label</p> </td> <td></td> </tr><tr><td> <p>Button</p> </td> <td> <p>Basic</p> </td> <td> <p>ButtonNewGame</p> </td> <td> <p>Resets the game to Hole #1 with a score of 0.</p> </td> <td> <p>Text: "New Game"</p> </td> </tr><tr><td> <p>Label3</p> </td> <td> <p>Basic</p> </td> <td> <p>LabelHoleNum</p> </td> <td> <p>Displays the current hole number, increments by one each time a hole is completed.</p> </td> <td> <p>Text = "Hole # 1"<br />Font: bold, 28, blue<br /></p> </td> </tr><tr><td> <p>Label4</p> </td> <td> <p>Basic</p> </td> <td> <p>LabelInstruct</p> </td> <td> <p>Displays instructions</p> </td> <td> <p>Text = "Use arrows to position ball on tee. Hit the ball by flinging it with your finger."</p> </td> </tr></tbody></table><p>Define a new global variable to keep track of the Hole Number:</p> <p><img height="44" src="/sites/all/files/tutorials/miniGolf/holeCount.png" width="234" /></p> <p>Add the following blocks to the <span class="callblock">SetupNewHole</span> procedure: set <span class="setblock">global HoleCount</span> and set <span class="setblock">LabelHoleNum.Text</span>...</p> <p><img height="291" src="/sites/all/files/tutorials/miniGolf/setupNewHole_add.png" width="557" /></p> <p>Program the "New Game" button’s behavior, which is pretty simple. When the button is pressed, set up a new course and reset both the hole stroke counter and total stroke counter to zero. Also set the hole number back to 1, by displaying "Hole #1" in LabelHoleNum. The blocks look like this:</p> <p><img height="412" src="/sites/all/files/tutorials/miniGolf/buttonNewGame.click.png" width="450" /></p> <pre class="ai-testing"><strong>Test the behavior.</strong><p> Go back to your device or emulator and play the game some more. Now you should see the Hole # displayed in the lower right. Hitting "New Game" button should reset the game, returning both scores to 0, resetting the screen, and setting the Hole number to #1.</p></pre><h3>Part IV: Introduce an Obstacle</h3> <p>Most mini golf courses have obstacles on them. Let’s add a simple rectangular obstacle that will randomly position itself on the course somewhere between the Tee and the Hole. Each time a new course is presented, the obstacle will move, just the same way the Hole moves each time a new course is set up.</p> <p><strong>Add the following component in the Designer:</strong></p> <p><a href="#" name="981d9864ae92d2e44bbc01311278b4463bf01a1e" id="981d9864ae92d2e44bbc01311278b4463bf01a1e"></a><a href="#" name="4" id="4"></a></p> <table cellpadding="0" cellspacing="0"><tbody><tr style="background-color: #EFEFEF; font-weight: bold;"><td> <p><strong>Component Type</strong></p> </td> <td> <p><strong>Palette Group</strong></p> </td> <td> <p><strong>What You’ll Name It</strong></p> </td> <td> <p><strong>Purpose</strong></p> </td> <td> <p><strong>Properties</strong></p> </td> </tr><tr><td> <p>ImageSprite</p> </td> <td> <p>Animation</p> </td> <td> <p>ObstacleSprite1</p> </td> <td> <p>This sprite will be somewhere between the golf ball and hole and will make it harder to get the ball into the hole</p> </td> <td> <p>Upload the obstacle (rectangle) graphic (<a href="/sites/all/files/tutorials/miniGolf/golf_obstacle1.png">right click on this link</a>, or see below).</p> </td> </tr></tbody></table><p>Program the behavior of the obstacle in the blocks editor. First, set the behavior for when the ball hits the obstacle.  *Note: Using Heading = 0 - heading works because we are dealing with bouncing off of horizonal surfaces, this will not work for bouncing off of vertical or inclined surfaces. For our purposes, it works all right. See Challenge #2 below for more information.</p> <p><img height="181" src="/sites/all/files/tutorials/miniGolf/obstacleSprite1.png" width="604" /></p> <p>Each time the course is reset, position the obstacle will be positioned randomly. Add these blocks to the <span class="callblock">SetupNewHole</span> procedure:</p> <p><img height="277" src="/sites/all/files/tutorials/miniGolf/setupNewHole_final.png" width="706" /></p> <pre class="ai-testing"><strong>Test the behavior.</strong> Play the game again. Notice that the ball bounces off when it hits the obstacle. When the ball goes into the hole, or when the New Game button is pressed, the obstacle appears in a new location somewhere between the tee and the hole.</pre><p>That’s it! Share your game with friends by building an APK or by downloading the source and sharing the zip file with other App Inventors!<br /></p> <h3>Part V: Challenges</h3> <p>Here are some extra challenges to make your game better.</p> <p><strong>Challenge 1:</strong> Program the Ball to Hole collision so that the ball only goes into the hole if the golf ball’s speed is not too fast. In real mini golf, the ball will bounce right over the hole if you hit the ball too hard.</p> <p><strong>Challenge 2:</strong> There is a slight bug when the ball hits the vertical sides of obstacle. Figure out how to program the ball to obstacle collision so that it bounces the way you would expect when the ball hits the vertical sides.</p> <p><strong>Challenge 3:</strong> Limit the number of holes per game. Keep track of the number of holes and end the game after a set number. (A typical mini golf course has 18 holes.)</p> <p>Below is a summary of all of the components, and a screen shot of all the blocks (some are collapsed to save space.)</p> <p><img height="455" src="/sites/all/files/tutorials/miniGolf/components.png" width="231" /></p> <p><img height="642" src="/sites/all/files/tutorials/miniGolf/finalCode.png" width="710" /></p> <p>Scan the following barcode onto your phone to install and run the sample app. </p><p><img src="http://explore.appinventor.mit.edu/sites/all/files/tutorials/miniGolf/MiniGolfBarcode.png" /></p> <h4 class="ai-header">Download Source Code</h4> <p>If you'd like to work with this sample in App Inventor, download the <a href="http://explore.appinventor.mit.edu/sites/all/files/tutorials/miniGolf/FlingitMiniGolfTutorial.zip">source code</a> to your computer, then open App Inventor, go to the My Projects page, and choose <b>More Actions | Upload Source</b>.</p> <pre class="ai-box"><span style="color:black;">Done with Mini Golf?</span> <a href="/tutorials">Return to the other tutorials</a>.</pre></div></div></div><section class="field field-name-field-version field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Version:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-version/app-inventor-1" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">App Inventor 1</a> </li> </ul> </section> <section class="field field-name-field-tutorial-difficulty field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Difficulty:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-difficulty/advanced" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Advanced</a> </li> </ul> </section> <section class="field field-name-field-tutorial-type field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Type:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-type/clock-timer" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Clock Timer</a> </li> <li class="field-item odd"> <a href="/tutorial-type/game" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Game</a> </li> <li class="field-item even"> <a href="/tutorial-type/sprites" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Sprites</a> </li> </ul> </section> Fri, 14 Jun 2013 15:45:30 +0000 aaron 308 at http://dev-explore.appinventor.mit.edu http://dev-explore.appinventor.mit.edu/content/minigolf#comments MoleMash http://dev-explore.appinventor.mit.edu/content/molemash <div class="field field-name-body field-type-text-with-summary field-label-hidden view-mode-rss"><div class="field-items"><div class="field-item even" property="content:encoded"><p><img style="float:right;" src="/sites/all/files/tutorials/moleMash/MoleOnEmulator.png" /></p> <p>In the game <span style="color:green;">MoleMash</span>, a mole pops up at random positions on a playing field, and the player scores points by hitting the mole before it jumps away. This tutorial shows how to build <span style="color:green;">MoleMash</span> as an example of a simple game that uses animation.</p> <p>The tutorial assumes that you have completed the <a href="http://explore.appinventor.mit.edu/hellopurr">HelloPurr</a> and <a href="/content/paintpot-part-1">PaintPot</a> tutorials.</p> <p><a href="http://cs.usfca.edu/~wolber/appinventor/bookSplits/ch3MoleMash.pdf">Download Book Chapter (PDF)</a></p> <h4 class="ai-header">Getting Started</h4> <p>Connect to the App Inventor web site and start a new project. Name it "MoleMash", and also set the screen's <strong style="color:green;">Title</strong> to "MoleMash". Open the Blocks Editor and connect to the phone.</p> <p>Also download this <a href="/sites/all/files/tutorials/moleMash/mole.png">picture of a mole</a> and save it on your computer.</p> <h4 class="ai-header">Introduction</h4> <p>You'll design the game so that the mole moves once every half-second. If it is touched, the score increases by one, and the phone vibrates. Pressing restart resets the score to zero.</p> <p>This tutorial introduces:</p> <ul><li>image sprites</li> <li>timers and the <strong>Clock</strong> component</li> <li>procedures</li> <li>picking random numbers between 0 and 1</li> <li>text blocks</li> <li>typeblocking</li> </ul><h4 class="ai-header">The first components</h4> <p>Several components should be familiar from previous tutorials:</p> <ul><li>A <strong>Canvas</strong> named "MyCanvas". This is the area where the mole moves.</li> <li>A <strong>Label</strong> named "ScoreLabel" that shows the score, i.e., the number of times the player has hit the mole.</li> <li>A <strong>Button</strong> named "ResetButton".</li> </ul><p>Drag these components from the Palette onto the Viewer and assign their names. Put <span style="color:green;">MyCanvas</span> on top and set its dimensions to 300 pixels wide by 300 pixels high. Set the <strong style="color:green;">Text</strong> of ScoreLabel to "Score: ---". Set the <strong style="color:green;">Text</strong> of ResetButton to "Reset". Also add a <strong>Sound</strong> component and name it "Noise". You'll use <span style="color:green;">Noise</span> to make the phone vibrate when the mole is hit, similar to the way you made the kitty purr in <span style="color:green;">HelloPurr</span>.</p> <h4 class="ai-header">Timers and the Clock component</h4> <p>You need to arrange for the mole to jump periodically, and you'll do this with the aid of a <strong>Clock</strong> 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 <strong style="color:green;">TimerInterval</strong> 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 <strong style="color:green;">Enabled</strong> is checked.</p> <h4 class="ai-header">Adding an Image Sprite</h4> <p>To add the moving mole we'll use a <em>sprite</em>.</p> <p>Sprites are images that can move on the screen within a Canvas. Each sprite has a <strong style="color:green;">Speed</strong> and a <strong style="color:green;">Heading</strong>, and also an <strong style="color:green;">Interval</strong> that determines how often the sprite moves at its designated speed. Sprites can also detect when they are touched. In <span style="color:green;">MoleMash</span>, 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 <strong>ImageSprite</strong> component onto the Viewer. You'll find this component in the Animation category of the Palette. Place it within <span style="color:green;">MyCanvas</span> area. Set these properties for the Mole sprite:</p> <ul><li><strong style="color:green;">Picture</strong>: Use mole.png, which you downloaded to your computer at the beginning of this tutorial.</li> <li><strong style="color:green;">Enabled</strong>: checked</li> <li><strong style="color:green;">Interval</strong>: 500 (The interval doesn't matter here, because the mole's speed is zero: it's not moving by itself.)</li> <li><strong style="color:green;">Heading</strong>: 0 The heading doesn't matter here either, because the speed is 0.</li> <li><strong style="color:green;">Speed</strong>: 0.0</li> <li><strong style="color:green;">Visible</strong>: checked</li> <li><strong style="color:green;">Width</strong>: Automatic</li> <li><strong style="color:green;">Height</strong>: Automatic</li> </ul><p>You should see the <strong style="color:green;">x</strong> and <strong style="color:green;">y</strong> properties already filled in. They were determined by where you placed the mole when you dragged it onto <span style="color:green;">MyCanvas</span>. Go ahead and drag the mole some more. You should see <strong style="color:green;">x</strong> and <strong style="color:green;">y</strong> 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 <span style="color:green;">Mole</span> is indented under <span style="color:green;">MyCanvas</span> in the component structure list, indicating that the sprite is a sub-component of the canvas.</p> <p><img src="/sites/all/files/tutorials/moleMash/MoleMashDesigner.png" /></p> <h4 class="ai-header">Component Behavior and Event Handlers</h4> <p>Now you'll specify the component behavior. This introduces some new App Inventor ideas. The first is the idea of a <em>procedure</em>.</p> <p>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.</p> <h4 class="ai-header">Define Procedures</h4> <p>Define two procedures:</p> <ul><li><span class="callblock">MoveMole</span> moves the <span style="color:green;">Mole</span> sprite to a new random position on the canvas.</li> <li><span class="callblock">UpdateScore</span> shows the score, by changing the text of the <strong style="color:green;">ScoreLabel</strong></li> </ul><p>Start with MoveMole:</p> <ul><li>In the Blocks Editor, under Built-In, open the Definition drawer. Drag out a <span class="callblock">to procedure</span> block and change the label "procedure" to "MoveMole".<br /><pre class="box">Note: There are two similar blocks: <span class="callblock">procedure</span> and <span class="callblock">procedureWithResult</span>. Here you should use <span class="callblock">procedure</span>.</pre><p>The <span class="callblock">to MoveMole</span> 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 <span class="basicblock">random fraction</span> and multiplication and subtraction. You can find these in the Math drawer.</p></li> <li>Build the <span style="color:green;">MoveMole</span> procedure. The completed definition should look like this:<br /><img src="/sites/all/files/tutorials/moleMash/MoveMole.png" /><br /> Leave the arg socket for <span style="color:green;">MoveMole</span> empty because <span style="color:green;">MoveMole</span> does not take any arguments. Observe how the blocks connect together: the first statement uses the <span class="setblock">Mole.X set</span> block to set mole's horizontal position. The value plugged into the block's socket is the result of multiplying: <ol><li>The result of the <span class="basicblock">call random fraction</span> block, which a value between 0 and 1</li> <li>The result of subtracting the mole's width from the canvas width</li> </ol><p>The vertical position is handled similarly.</p></li> </ul><p>With <span style="color:green;">MoveMole</span> done, the next step is to define a variable called <span style="color:green;">score</span> to hold the score (number of hits) and give it initial value 0. Also define a procedure <span class="callblock">UpdateScore</span> that shows the score in <span style="color:green;">ScoreLabel</span>. The actual contents to be shown in <span style="color:green;">ScoreLabel</span> will be the text "Score: " joined to the value of <span style="color:green;">score</span>.</p> <ul><li>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 "text".</li> <li>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.</li> </ul><p>Here's how <span style="color:green;">score</span> and <span class="callblock">UpdateScore</span> should look:</p> <p><img src="/sites/all/files/tutorials/moleMash/UpdateScore.png" /></p> <h4 class="ai-header">Add a Timer</h4> <p>The next step is to make the mole keep moving. Here's where you'll use <span style="color:green;">MoleTimer</span>. Clock components have an event handler called <span class="basicblock">when ... Timer</span> that triggers repeatedly at a rate determined by the <strong style="color:green;">TimerInterval</strong>.</p> <p>Set up <span style="color:green;">MoleTimer</span> to call <span class="callblock">MoveMole</span> each time the timer fires, by building the event handler like this:</p> <p><img src="/sites/all/files/tutorials/moleMash/MoleMashTimerEventHandler.png" /></p> <pre class="ai-box">Notice how the mole starts jumping around on the phone as soon as you define the event handler. This is an example of how things in App Inventor start happening instantaneously, as soon as you define them.</pre><h4 class="ai-header">Add a Mole Touch Handler</h4> <p>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 <span style="color:green;">Mole</span> that:</p> <ol><li>Increments the score.</li> <li>Calls <span class="callblock">UpdateScore</span> to show the new score.</li> <li>Makes the phone vibrate for 1/10 second (100 milliseconds).</li> <li>Calls <span class="callblock">MoveMole</span> so that the mole moves right away, rather than waiting for the timer.</li> </ol><p>Here's what this looks like in blocks. Go ahead and assemble the <span class="basicblock">when Mole.Touched</span> blocks as shown.</p> <p><img src="/sites/all/files/tutorials/moleMash/MoleMashTouchEventHandler.png" /></p> <p>Here's a tip: You can use typeblocking: typing to quickly create blocks.</p> <ul><li>To create a value block containing 100, just type 100 and press return.</li> <li>To create a <span class="callblock">MoveMole</span> block, just type <span class="callblock">MoveMole</span> and select the block you want from the list</li> </ul><h4 class="ai-header">Reset the Score</h4> <p>One final detail is resetting the score. That's simply a matter of making the <span style="color:green;">ResetButton</span> change the score to 0 and calling <span class="callblock">UpdateScore</span>.</p> <h4 class="ai-header">Complete Program</h4> <p>Here's the complete <span style="color:green;">MoleMash</span> program:</p> <p><img src="/sites/all/files/tutorials/moleMash/MoleMashComplete.png" /></p> <h4 class="ai-header">Variations</h4> <p>Once you get the game working, you might want to explore some variations. For example:</p> <ul><li>Make the game vary the speed of the mole in response to how well the player is doing. To vary how quickly the mole moves, you'll need to change the <span style="color:green;">MoleTimer</span>'s <strong style="color:green;">Interval</strong> property.</li> <li>Keep track of when the player hits the mole and when the player misses the mole, and show a score with both hits and misses. To do this, you'll need do define touched handlers both for <span style="color:green;">Mole</span>, same as now, and for <span style="color:green;">MyCanvas</span>. One subtle issue, if the player touches the mole, does that also count as a touch for <span style="color:green;">MyCanvas</span>? The answer is yes. Both touch events will register.</li> </ul><h4 class="ai-header">Review</h4> <p>Here are some of the ideas covered in this project:</p> <ul><li>Sprites are touch-sensitive shapes that you can program to move around on a <strong>Canvas</strong>.</li> <li>The <strong>Clock</strong> component can be used as a timer to make events that happen at regular intervals.</li> <li>Procedures are defined using <span class="callblock">to</span> blocks.</li> <li>For each procedure you define, App Inventor automatically creates an associated call block and places it in the My Definitions drawer.</li> <li>Making a <span class="basicblock">random-fraction</span> block produces a number between 0 and 1.</li> <li>Text blocks specify literal text, similar to the way that number blocks specify literal numbers.</li> <li>Typeblocking is a way to create blocks quickly, by typing a block's name.</li> </ul><h4 class="ai-header">Scan the Sample App to your Phone</h4> <p>Scan the following barcode onto your phone to install and run the sample app. </p><p><img src="/sites/all/files/tutorials/moleMash/MoleMashBarcode.png" /></p> <h4 class="ai-header">Download Source Code</h4> <p>If you'd like to work with this sample in App Inventor, download the <a href="/sites/all/files/tutorials/moleMash/MoleMash.zip">source code</a> to your computer, then open App Inventor, go to the My Projects page, and choose <b>More Actions | Upload Source</b>.</p> <pre class="ai-box">Done with <span style="color:black;">MoleMash</span>? Return to the other tutorials <a href="/tutorials">here</a>.</pre></div></div></div><section class="field field-name-field-version field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Version:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-version/app-inventor-1" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">App Inventor 1</a> </li> </ul> </section> <section class="field field-name-field-tutorial-difficulty field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Difficulty:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-difficulty/basic" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Basic</a> </li> </ul> </section> <section class="field field-name-field-tutorial-type field-type-taxonomy-term-reference field-label-above view-mode-rss clearfix"> <h2 class="field-label">Tutorial Type:&nbsp;</h2> <ul class="field-items"> <li class="field-item even"> <a href="/tutorial-type/clock-timer" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Clock Timer</a> </li> <li class="field-item odd"> <a href="/tutorial-type/game" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Game</a> </li> <li class="field-item even"> <a href="/tutorial-type/sprites" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Sprites</a> </li> </ul> </section> Fri, 14 Jun 2013 15:43:59 +0000 aaron 306 at http://dev-explore.appinventor.mit.edu http://dev-explore.appinventor.mit.edu/content/molemash#comments