Explore MIT App Inventor - App Inventor 2 http://dev-explore.appinventor.mit.edu/tutorial-version/app-inventor-2 en Pizza Party with Fusion Tables for App Inventor 2 http://dev-explore.appinventor.mit.edu/ai2/pizzaparty <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; } /*--><!]]>*/ </style><div style="float:right;"><img src="http://explore.appinventor.mit.edu/sites/all/files/tutorials/pizzaParty/pizza_party_screenshot.png" style="border:none; padding-left:15;" /><br /><a href="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/pizzaParty/PizzaParty_MIT.aia"><img src="http://explore.appinventor.mit.edu/sites/all/files/tutorials/pizzaParty/downloadSourcebutton.png" style="border:none; padding-left:65;" /></a></div> <p>In this tutorial, you will create an app that lets people enter food orders for a pizza party. Orders are stored in a Fusion Table, providing one easy to access place for the data. By reading from the table, the app can easily display the orders that have been entered.</p> <p>A <a href="http://en.wikipedia.org/wiki/Google_Fusion_Tables">Fusion Table</a> is a Google service to support the gathering, managing, sharing, and visualizing of data. Data are stored in multiple tables on Google's <a href="http://en.wikipedia.org/wiki/Cloud_computing">cloud</a>. Individual tables can be merged (or fused) if they contain a common column, and they can be easily visualized on maps and in various kinds of charts and graphs. All of the data are stored in a public table that can be accessed via Google Drive, and allows different users<a href="#note">**</a> to add information to the tables. Coupled with a location sensor, an App Inventor app could post periodic updates of each user's location to a public fusion table. Users could post notes to mark noteworthy locations. For example, a team of botanists could use a Fusion Table app to create an annotated catalog of the trees or plants within a certain geographical area.</p> <p>This tutorial introduces:</p> <ul><li>Using the <b>FusionTables</b> component</li> <li>Using a <b>WebViewer</b> component</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="/ai2/tutorials">basic tutorials</a> before continuing.</p> <hr /><p><strong>IF YOU DOWNLOAD THE SOURCE CODE</strong> you will need to supply your own API KEY, your own Table ID, and your own TABLE URL in the global variables in the blocks editor. This source code will not work without these additions.</p> <h4 class="ai-header">Creating your own Fusion Table</h4> <p>Creating your own Fusion Tables is as easy as creating a Google document, if you are familiar with that process.</p> <p><img src="/sites/all/files/tutorials/pizzaParty/MoreEvenMoreFusion.jpg" style="float:right" /></p> <ol><li>On the web, login to your Gmail account or any other Google service (e.g., Drive, YouTube).</li> <li>Select the <strong>More &gt; Even more</strong> menu and scroll to the bottom of the page of Google services where you will find the Fusion Tables service under "Innovation", click on the Fusion Tables link.</li> <li>Click "Create New Table"</li> <li>You will be given three options for the new table: "From this computer", "Google Spreadsheets", or "Create an empty table". For the purposes of this tutorial, select <b>Create an empty table</b>.</li> <li>You will see that the new table automatically comes with four columns. Change the column names for your Pizza app by going to <strong>Edit &gt; Change Columns</strong>.You'll rename the four default columns to <em>Date</em> (type=Date), <em>Name</em> (type=Text), <em>Pizza</em> (type=Text), <em>Drink</em> (type=Text). Click save and then add a fifth column by going to the <strong>Edit &gt; Add Column</strong>. Name this fifth column <em>Comment</em> (type=Text). .</li> <li>Leave this window open so that you can come back and get the URL, which you'll need when you set up the properties of the WebViewer component in your app.</li> <li>Click on the <strong>Share</strong> button (top right) to modify the table's permissions. For this tutorial, you can specify a few friends who will use the app. Only people who are explicitly given permission will be able to enter pizza party preferences through your app.</li> </ol><pre class="ai-box"><img src="/sites/all/files/tutorials/pizzaParty/FusionTables_GoogleDrive.png" style="float:right;padding:15px;" />Another way to create a new table: go to Google Drive. Click the <strong>Create</strong> button, then go to <strong>More &gt; Fusion Table</strong>. The picture at right shows what the Create button's menu should look like. If you do not see Fusion Table in your menu, then you may need to contact your school's network administrator. (See Troubleshooting section at the bottom of this page.) </pre><p><strong><a name="note" id="note">NOTE</a> about Sharing Fusion Tables:</strong> To share a FusionTable with others, you have to share it with each person individually, or you can share with a Google Group (see footnote at the end of this tutorial), the same way you would share a private google doc. There is no way to share write privileges to a FusionTable with the public. Public access is restricted to read-only.</p> <h4 class="ai-header">Getting an API Key</h4> <p>In order to use the FusiontablesControl Component you need to acquire a Google Applications Programming Interface (API) key, an API Key. To get an API key, follow these instructions:</p> <ol><li>Go to your <a href="https://code.google.com/apis/console/">Google APIs Console</a> and login if necessary.</li> <li>Select the <strong>Services</strong> item from the menu on the upper left.</li> <li>In the list of services, find the <strong>Fusion Tables API</strong> service and click the toggle button that currently says "off".</li> <li>Read and agree to the terms of service. When you return to the APIs Console page you'll see that the on/off switch next to Fusion Tables API is now "On" and green.</li> <li>Go back up the menu on the upper left of the screen and select the <strong>API Access</strong> item.</li> <li>Your API Key will be in the rectangular box in the section called "Simple API Access". You will need set the "API Key" property of the Fusiontables Control component in any app that you make that uses Fusion Tables. (More info below.)</li> </ol><h4 class="ai-header">Building the App</h4> <p>Connect to the App Inventor web site and start a new project. Name the new project PizzaParty, set the screen's orientation to Portrait and uncheck the Screen's scrollable property. You may also wish to set the Screen's Title property to something other than 'Screen 1'.</p> <h4 class="ai-header">The User Interface</h4> <p>In addition to the FusiontablesControl component, the Pizza Party app makes use of several other types of components. It is assumed that you have learned how to use these in previous lessons. Use the component designer to create the interface for the Search Party. When completed, the designer should look like this:</p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/pizzaParty/designer.png" /></p> <p>The components are: </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> <td> Settings of Component </td> </tr><tr><td> <b>Label</b> </td> <td>Basic</td> <td style="color:green;">LabelName</td> <td>Shows the text "Your Name:"</td> <td></td> </tr><tr><td> <b>TextBox</b> </td> <td>Basic</td> <td style="color:green;">TextBoxUserName</td> <td>Gets input from user</td> <td>Set the width property to Fill Parent</td> </tr><tr><td> <b>HorizontalArrangement</b> </td> <td>Screen Arrangement</td> <td style="color:green;">HorizontalArrangement1</td> <td>Contains Name Label and Textbox</td> <td></td> </tr><tr><td> <b>ListPicker</b> </td> <td>Basic</td> <td style="color:green;">ListPickerPizza</td> <td>Accesses the list of available pizza types</td> <td> <p>Set the Width property to Fill Parent</p> <p>Set the Text property to "What type of pizza?"</p> <p>Set the ElementsFromString to "Cheese, Pepperoni, Anchovies, Hawaiian"</p> </td> </tr><tr><td> <b>ListPicker</b> </td> <td>Basic</td> <td style="color:green;">ListPickerDrink</td> <td>Accesses the list of available drinks.</td> <td> <p>Set the Width property to Fill Parent</p> <p>Set the Text property to "What type of drink?"</p> <p>Set the ElementsFromString to "Coke, Diet Coke, Sprite, Ginger Ale"</p> </td> </tr><tr><td> <b>Label</b> </td> <td>Basic</td> <td style="color:green;">LabelComment</td> <td>Shows the text "Comments:"</td> <td></td> </tr><tr><td> <b>TextBox</b> </td> <td>Basic</td> <td style="color:green;">TextBoxComments</td> <td>Takes user input</td> <td>Set the width property to Fill Parent</td> </tr><tr><td> <b>HorizontalArrangement</b> </td> <td>Screen Arrangement</td> <td style="color:green;">HorizontalArrangement2</td> <td>Contains Comments Label and Textbox</td> <td></td> </tr><tr><td> <b>Button</b> </td> <td>Basic</td> <td style="color:green;">ButtonSubmit</td> <td>Adds new data to the public fusion table</td> <td> <p>Set the Text to "Submit"</p> <p>Set the width property to Fill Parent</p> </td> </tr><tr><td> <b>WebViewer</b> </td> <td>Not ready for prime time</td> <td style="color:green;">WebViewer1</td> <td>Displays Fusion Table</td> <td>Set width and height properties to Fill Parent</td> </tr><tr><td> <b>FusiontablesControl</b> </td> <td>Not ready for prime time</td> <td style="color:green;">FusiontablesControl1</td> <td>Manages interactions with the app's Fusion Table</td> <td></td> </tr><tr><td> <b>Clock</b> </td> <td>Basic</td> <td style="color:green;">Clock1</td> <td>Used to provide a timestamp each time an order is placed.</td> <td></td> </tr><tr><td> <b>Notifier</b> </td> <td>Other stuff</td> <td style="color:green;">Notifier1</td> <td>Notifies the user of any errors</td> <td></td> </tr></table><h4 class="ai-header">Determining your Fusion Table URL and Table ID</h4> <p>In the blocks editor, you will set the WebViewer component's HomeURL property to point to the URL of your table. To find your Fusion Table's URL:</p> <ol><li>In your browser, navigate to the new Fusion Table you just created.</li> <li>Go to the menu and select <b>Tools &gt; Publish</b>.</li> <li>You'll see a notice saying: "This table is private and will not be visible". Click the blue link that says "Change Visibility".</li> <li>In the list of "Who Has Access", click the blue "Change..." link next to "Private - Only people listed below..."</li> <li>Choose"Public on the Web" or "Anyone with the link". Either of these settings will work for this tutorial. In the future, you should decide this setting based on the sensitivity of your data.</li> <li>Click the green Save button, then the blue Done button.</li> <li>Back on the Fusion Table page, go to the menu bar and select <strong>Tools &gt; Publish</strong>. Select the URL from the top text box (labeled "Send in an email or IM"), copy the URL and return to App Inventor. You will paste the URL into the definition block for the TABLE_URL (see below).</li> <li>The Table ID of the fusion table is contained within the URL after the plus sign. Look for "from+" and then copy all of the characters after the plus. This is the Table's ID. You can also find the Table ID by browsing to your table, then selecting <b>File&gt;About this table</b> in the menu.</li> </ol><h4 class="ai-header">Blocks Editor</h4> <p>Open the Blocks Editor so you can program the app's behavior. First, you will describe the app's variables. Variables whose names are ALL_CAPS are constants -- that is, variables whose values do not change while the program is running. It is good to get into the habit of using this naming convention. Define the following variables and give them the initial values shown in the table.</p> <table><tr style="background-color: #EFEFEF; font-weight: bold;"><td> Variable Name </td> <td> Initial Value </td> <td> Purpose </td> </tr><tr><td> <b>TABLE_URL</b> </td> <td>text</td> <td>Initialize this global variable to the "published" URL of your fusion table. See instructions above.</td> </tr><tr><td> <b>TABLE_ID</b> </td> <td>text</td> <td>Initialize this global variable to your table ID (e.g. a long string of characters unique to your fusion table). See instructions above.<font></font></td> </tr><tr></tr><tr><td> <b>API_KEY</b> </td> <td>text</td> <td>Initialize this global variable to your own API Key for Google Fusion Tables. See instructions above.</td> </tr><tr><td> <b>UserName</b> </td> <td>text</td> <td>Records the name of the user.</td> </tr><tr><td> <b>pizza</b> </td> <td>text</td> <td>Stores the pizza choice input by the user.</td> </tr><tr><td> <b>drink</b> </td> <td>text</td> <td>Stores the drink choice input by the user.</td> </tr><tr><td> <b>comment</b> </td> <td>text</td> <td>Stores the comment input by the user.</td> </tr></table><p><b>Initializing the App</b></p> <p>It is important to perform some initialization steps whenever the app is started. These are done in the <span class="eventblock">Screen1.Initialize</span> block. For this app we need to set the initial values for the FusionTable component's API Key property (set to global API_KEY) and the WebViewer component's HomeURL property (set to global TABLE_URL). We also tell the app to forget the user's login credentials. This will prompt the user to login to their Google account and give permission to the app to access the Fusion Table. This authentication step will happen only once when the app first tries to access the Fusion Table. Remember, Fusion Tables are only writeable by users who have been given permission by the table's owner. You specify this in the Sharing settings for the Fusion Table (easy to do from the Google Drive webpage.)</p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/pizzaParty/initialblocks.png" /></p> <p>Set up the <span class="callblock-ai2">resetForm</span> procedure as shown below. After recording an entry, this procedure resets the interface back to the original state.</p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/pizzaParty/resetForm.png" /></p> <p><b>List Picker Blocks</b></p> <p>In the designer, you set the choices for the pizza and drink types by filling in the "Selection" property with comma separated lists. These pre-programmed choices will be displayed on the user interface so the user can select their food and drink. Their selections are stored in the pizza and drink variables.</p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/pizzaParty/listpicker.png" /></p> <p><b>Submitting Data</b><br /></p><p></p> <p>Once the user has entered their name, food choices, and comments, they will click the <b>Submit</b> button. The app tests to make sure that the name, pizza, and drink fields have values in them, and prompts the user to try again if any of the required answers are missing. Notice that the <span class="textblock-ai2">text =</span> block is used (find it under Built-in palette, Text drawer). This block compares two strings of text to see if they are equal. If all required information is present, it calls the procedure <span class="callblock-ai2">InsertDataInTable</span> (see below). The blocks for the <span class="eventblock">ButtonSubmit.Click</span> are shown here:</p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/pizzaParty/submit.png" /></p> <p><b>Inserting Data into the Fusion Table</b></p> <p>The FusiontablesControl component is used to send the data to the Fusion Table. This action will create a new row in the Fusion Table, setting the values of the various columns involved. App Inventor makes this easy to do, but you have to be careful that the insert query is formatted correctly.</p> <p>This procedure involves two steps: (1) constructing the insert query and then (2) sending the query to Google's Fusion Table service. The query we want to send will take this format:</p> <p>INSERT INTO<br /><tableid> (<column1>, <column2>, ...) VALUES (<value1>, <value2>, ...)</value2></value1></column2></column1></tableid></p> <p>The words in CAPS are part of the query's syntax. The words in parentheses are values that we need to plug in. First there is a list of (column names) followed by VALUES followed by a list of (value names). The order of the column names and value names must be in the same order so that they match up. An example of what this might look like is shown below. Notice that the values must be enclosed in single quotes:</p> <p>INSERT INTO 191GHtZ_B2 (Name, Date) VALUES ('Sam', '10/10/2012')</p> <p>First, setup a new <span class="callblock-ai2">Procedure With Result</span> that takes a string and returns it surrounded by single quotes. The procedure <span class="callblock-ai2">quotify</span> is used in the InsertDataInTable procedure to place quotes around all of the values in the query. It also takes care of "escaping" any single quotes or apostrophes that are input by the user. You can send single apostrophes as part of a value in the query, so the "replace all" block adds an extra single quote. Two single quotes in a row are interpreted as one single quote.</p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/pizzaParty/quotify.png" /></p> <p>To construct the query we use App Inventor's join text block. Be sure to put spaces where needed, such as before and after the words INSERT INTO and VALUES:</p> <p><img src="/sites/all/files/ai2tutorials/pizzaParty/insertTable.png" /></p> <p>For this app, the column names must match the column names of the table we created earlier (with columns Date, Name, Pizza, Drink, Comment). Their respective values are taken from the procedure's global variables. Note: If you did not use these exact words for your table's columns, then be sure to use your table's column names when you build your query.</p> <p>Don't forget the <span class="callblock-ai2">FusiontablesControl.SendQuery</span> command at the very end of this procedure. It's small in size compared to rest of the procedure, but very important.</p> <p><b>Handling the Response from the Fusion Tables Service</b></p> <p>The <span class="eventblock">FusiontablesControl.GotResult</span> event will be fired when the app receives a response from Google's Fusion Tables Service. For an insert query the service will return the rowID of the new row that was inserted or an error message if something went wrong. In this simple example, we use the "contains" block ( (find it under Built-in palette, Text drawer) to check whether the result string has the rowID in it. If so, then we know that the rowID was received, and we then invoke the <span class="callblock-ai2">WebViewer.GoHome</span> procedure, which reloads the "HomeURL" as specified in the WebViewer's properties. Note that this set of blocks also calls the <span class="callblock-ai2">resetForm</span> procedure. After recording an entry, it resets the interface back to the original state.</p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/pizzaParty/gotresult.png" /></p> <p><b>You're done!</b> Package the app by going to <b>Package for Phone</b> on the Designer. You can now test the App for the purposes of the pizza party. Once you understand this tutorial, you'll be ready to make new Fusion Tables and modify the app to collect different types data from users. Remember, you have to give each user permission to access the Fusion Table. You do this through the Google Fusion Tables interface, not through App Inventor. Luckily, this means you don't have to change the app in order to add more users who can access the table.</p> <h4 class="ai-header">Challenges</h4> <p>This app has the Fusion Table hard-coded into the blocks. Find a way to let users specify their own fusion table ID so that they can host their own Pizza Party.</p> <h4 class="ai-header">Variations</h4> <p>Now that you have a simple app that uses fusion tables and a webviewer working, you might want to build some other apps with Fusion Tables. For example:</p> <ul><li>Include a <b>LocationSensor</b> so that the user's location can be added to the Fusion Table to create a map with notes</li> <li>Make the WebViewer display something other than the table of stored values; perhaps a map or a chart</li> </ul><h4 class="ai-header">Troubleshooting</h4> <p>If you are using a Google Apps for Education account, and you are not able to create a new fusion table (in the "Create" menu of Google Drive you won't even see an option for Fusion Tables), you will need to ask your system administrator to turn this option on for you. Or, you can switch to a standard gmail account. Fusion Tables are not automatically turned on for Google Apps for Education Accounts, your system administrator must make Fusion Tables available to the accounts in your domain.</p> <p>If you are receiving errors when trying to submit to the Fusion Table, especially if the error mentions Authentication, be sure that you have put the correct API Key into the API Key property field on the FusionTables component in the Design Window.</p> <p>To familiarize yourself with fusion tables, have a look around the <a href="http://support.google.com/fusiontables/bin/answer.py?hl=en&amp;answer=2571232">Fusion Tables Web Site</a>. Check out the example gallery to see what kinds of things are possible. Work through this <a href="http://earth.google.com/outreach/tutorial_fusion_sample.html">Fusion Table tutorial</a>, which shows how import some data, create a Fusion Table, and view the data on a map with your browser. You'll need to log in with your Google account.</p> <p><strong>To share a FusionTable with many people</strong>, rather than by entering email addresses individually, you can <strong>create a dedicated Google Group for your app and let all the app users know how to join the group</strong> (maybe through the web page for your app). From the moment you create your app, you share the Fusion Table once with your Google Group (using its email address), and <strong>make sure to give to the group editing rights</strong>. Every user who joins the group will inherit the editing rights automatically.</p> <pre class="ai-box"><span style="color:black;">Done with PizzaParty?</span> <a href="http://explore.appinventor.mit.edu/tutorials">Return to the other tutorials</a>.</pre><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/pizzaParty/PizzaParty_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>. Remember to add in your API KEY and Fusion Table information in the Designer and blocks.</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/data-storage" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Data Storage</a> </li> </ul> </section> Thu, 08 Aug 2013 15:19:00 +0000 joanie 381 at http://dev-explore.appinventor.mit.edu http://dev-explore.appinventor.mit.edu/ai2/pizzaparty#comments 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 PaintPot (Part 2) for App Inventor 2 http://dev-explore.appinventor.mit.edu/ai2/paintpot-part2 <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 tutorial has two parts: <a href="/ai2/paintpot-part1">Part 1</a> | <a href="/ai2/paintpot-part2">Part 2</a> </p> <p>Part 2 extends <a href="/ai2/paintpot-part1">Part 1</a> of the tutorial to create both large and small dots, as a demonstration of how to use <em>global variables</em>.</p> <h4 class="ai-header">Starting</h4> <p>Make sure you've completed the <a href="/ai2/setup">Set Up</a> process and you have your completed project from <a href="/ai2/paintpot-part1">PaintPot Part 1</a> loaded.</p> <p>Start where you left off at the end of Part 1, with the project open in App Inventor. Use the <strong>Save As</strong> button to make a copy of <span style="color:green;">PaintPot</span> so you can work on the new version without affecting the original version. Name the copy "PaintPotV2" (with no spaces). After saving a copy, you should see <span style="color:green;">PaintPotV2</span> in the Designer.</p> <h4 class="ai-header">Creating variables</h4> <p>The size of the dots drawn on the canvas is determined in the <span class="basicblock">when DrawingCanvas.Touched</span> event handler where <span class="callblock-ai2">call Drawing.DrawCircle</span> is called with <strong style="color:green;">r</strong>, the radius of the circle, equal to 5. To change the thickness, all we need to do is use different values for <strong style="color:green;">r</strong>. Use <strong style="color:green;">r</strong> = 2 for small dots and <strong style="color:green;">r</strong> = 8 for large dots.</p> <p>Start by creating names for these values:</p> <ol><li>Open the Blocks Editor if it isn't already open and connect the phone. Your phone should show the buttons and the canvas you built previously.</li> <li>In the Blocks Editor, in the Built-In column, open the Variables drawer. Drag out a <span class="variableblock">initialize global name to</span> block. Change the text that reads "name" to read "small". A yellow warning exclamation mark might appear on the block. If you mouse over this you'll see a warning message explaining that the block has an empty socket.</li> <li>You need to fill in the socket with a number block that specifies the value for "small" -- use 2 as the value. To create the number block, type the number 2. A menu will appear, showing you all the possible blocks that include "2" in their name. Click on the first one, which is the <span class="mathblock">number 2</span> itself, and a number block with the value 2 should appear. Plug that in to the <span class="variable block">initialize global small to</span> block. The yellow warning mark will disappear, because the empty socket has been filled. (The second value listed in the menu is the math block <span class="mathblock">atan2</span> which you won't use here.)</li> </ol><p>Here are the steps in the sequence:</p> <ol><li><img src="/sites/all/files/ai2tutorials/paintPot2/var1.png" /></li> <li><img src="/sites/all/files/ai2tutorials/paintPot2/var2.png" /></li> <li><img src="/sites/all/files/ai2tutorials/paintPot2/var3.png" /></li> <li><img src="/sites/all/files/ai2tutorials/paintPot2/var4.png" /></li> <li><img src="/sites/all/files/ai2tutorials/paintPot2/var5.png" /></li> </ol><p>You've now defined a global variable named <span class="variableblock">small</span> whose value is the number 2.<br /> Similar to <span class="setblock">small</span>, define a global variable <span class="variableblock">big</span>, whose value is 8.<br /> Finally, define a global variable <span class="variableblock">dotsize</span> and give it an initial value of 2.</p> <pre class="ai-box">You might wonder whether it would be better programming style to make the initial value of <span style="color:black;">dotsize</span> be the value of <span style="color:black;">small</span> rather than 2. That would be true, except for a subtle programming point: Doing that would be relying on the assumption that <span style="color:black;">small</span> will already have a value at the point in time when <span style="color:black;">dotsize</span> is assigned its value. In App Inventor, you can't make assumptions about the order in which different <span class="setblock" style="color:black;">def</span> blocks will be processed. In general, of course, you really <em>would</em> like to specify the order in which variables are assigned. You can do this by assigning all values when the application is initialized, using the Screen initialize event. The <a href="http://appinventor.mit.edu/explore/content/quizme.html">Quiz Me</a> tutorial gives an example of initialization.</pre><h4 class="ai-header">Using variables</h4> <p>Now go back to the touch event handler you set up in Part 1 and change the <span class="callblock-ai2">call to DrawCircle</span> block so that it uses the value of <span style="color:green;">dotsize</span> rather than always using 5.</p> <p>In the Blocks Editor, switch to the My Blocks column, and open the Variables drawer. Pull out a get block and click on the dropdown. You should see three new variables in the dropdown: small, big, and dotsize</p> <p>These blocks were automatically created and put in the dropdown of <span class="variableblock">get</span> and <span class="variableblock">set</span> variable blocks, similarly to the way that x and y were created in the dropdown when you defined the <span class="eventblock">when DrawingCanvas.Touched</span> event handler in the part 1 of this tutorial. "Global" means "global variable", in contrast to the event-handler arguments, which are considered "local variables". The difference is that the argument values are accessible only within the body of the event handler, while global variables are accessible throughout the entire program.</p> <ul><li>Go to the <span class="eventblock">when MyCanvas.Touched</span> event handler and replace the number 5 block in <span class="callblock-ai2">call DrawCircle</span> with the <span class="variableblock">get dotsize</span> block from the Variables drawer.</li> </ul><h4 class="ai-header">Changing the values of variables</h4> <p>Now set up a way to change dotsize to be small (2) or big (8). Do this with buttons.</p> <ol><li>In the Designer, drag a <strong>HorizontalArrangement</strong> component into the Viewer pane below the <span style="color:green;">DrawingCanvas</span> component. Name the component "BottomButtons".</li> <li>Drag the existing <span style="color:green;">ButtonWipe</span> into <span style="color:green;">BottomButtons</span>.</li> <li>Drag two more button components from the Palette into <span style="color:green;">BottomButtons</span>, placing them next to <span style="color:green;">ButtonWipe</span>.</li> <li>Name the buttons "ButtonBig" and "ButtonSmall", and set their <strong style="color:green;">Text</strong> to read "Big dots" and "Small dots", respectively.</li> <li>In the Blocks Editor under My Blocks, create a <span class="eventblock">when ... Clicked</span> event handler for <span style="color:green;">ButtonSmall</span> that changes <span style="color:green;">dotsize</span> to be the value of <span style="color:green;">small</span>. To change <span style="color:green;">dotsize</span> use the <span class="variableblock">set global dotsize to</span> block from the MyDefinitions drawer and plug in the <span class="variableblock">global small</span> block.</li> <li>Make a similar event handler for <span style="color:green;">ButtonBig</span>.</li> </ol><p>The two click event handlers should look like this:</p> <p><img src="/sites/all/files/ai2tutorials/paintPot2/PaintPotDotsClick.png" /></p> <p>You're done! You can draw in <span style="color:green;">PaintPot</span> and use the new buttons to draw either big dots or small dots. Notice that dragging your finger still produces a thin line. That's because the changes we just made don't affect how <span class="callblock-ai2">DrawLine</span> is called.</p> <p>Here's the finished program in the Designer:</p> <p><img src="/sites/all/files/ai2tutorials/paintPot2/PaintPotAllDesigner.png" /></p> <p>and in the Blocks Editor:</p> <p><img src="/sites/all/files/ai2tutorials/paintPot2/PaintPotAllBlocks.png" /></p> <pre class="ai-box">A bug for you to work on: The program you just built has a slight bug. If you start drawing before pressing any of the paint buttons, the paint color will be black; however, after you choose a color, there's no way to get back to black. Think about how you could fix that.</pre><h4 class="ai-header">Review</h4> <p>You create global variables by using <span class="variableblock">def</span> blocks from the Variables drawer.</p> <p>For each global variable you define, App Inventor automatically supplies a <span class="variableblock">global</span> block that gives the value of the variable, and a <span class="variableblock">set global ... to</span> block for changing the value of the variable. These blocks can be found in the Variables drawer.</p> <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/paintPot2/PaintPot2Barcode.png" /></p> <p>Or <a href="/sites/all/files/ai2tutorials/paintPot2/PaintPot2.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="/sites/all/files/ai2tutorials/paintPot2/PaintPot2.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;">PaintPot</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/drawing-canvas" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Drawing Canvas</a> </li> </ul> </section> Tue, 16 Jul 2013 14:33:50 +0000 joanie 364 at http://dev-explore.appinventor.mit.edu http://dev-explore.appinventor.mit.edu/ai2/paintpot-part2#comments PicCall for App Inventor 2 http://dev-explore.appinventor.mit.edu/ai2/piccall <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><span style="color:green;">PicCall</span> shows you how you can use App Inventor to make apps that do actual things, like calling friends.</p> <p>This tutorial assumes that you have completed the <a href="/ai2/setup">Set Up</a> process.</p> <h4 class="ai-header">Before starting</h4> <p>To run <span style="color:green;">PicCall</span>, your phone must be set up and activated for making phone calls. If it isn't you can still build <span style="color:green;">PicCall</span> for practice, but the phone won't actually make the calls.</p> <pre class="ai-warning">Warning: <span style="color:black;">PicCall</span> does not work on all Android phones in the current implementation of App Inventor: you'll get an error notice on some phones when you try to pick a phone number. Also, you won't see all your contacts — only those created from Gmail. These limitations will be removed in the future.</pre><p>In this tutorial, unlike <span style="color:green;">HelloPurr</span>, you'll give names to components, rather than just using the default names that App Inventor provides (like "Button1"). Using meaningful names is good programming practice: it helps you keep your programs straight in your own mind, and it helps others understand your programs.</p> <p>Your phone should also contain a few contacts with pictures. You can use the Contacts app to save pictures for your contacts. You can also click on Contacts in your Gmail account on your computer and add pictures there.</p> <p>Make sure your computer and your phone are set up to use App Inventor. Start a new project in the Designer window. Name it "PicCall" and change the screen <strong style="color:green;">Title</strong> to <span style="color:green;">PicCall</span>. Open the Blocks Editor, click <strong>Connect to Companion</strong>, and check that the phone has started the App Inventor app.</p> <h4 class="ai-header">Getting started</h4> <p>Start out just like in <span style="color:green;">HelloPurr</span> by placing a button on the screen. Make the button 150 pixels wide and 150 pixels high. Set button's <strong style="color:green;">Image</strong> to a picture. You may as well use the picture of the kitty if it's handy -- you'll be changing the picture soon. Set the <strong style="color:green;">Text</strong> of the button to "Press to Call", although you'll be changing that soon as well.</p> <p>Change the name of the Button component to "TopButton" (you'll make one called "BottomButton" later in the tutorial). To change a component's <strong style="color:green;">Name</strong>, click the <strong>Rename</strong> button in the Components panel and enter the new name.</p> <pre class="ai-box">In this tutorial, unlike <span style="color:black;">HelloPurr</span>, you'll give names to components, rather than just using the default names that App Inventor provides (like "Button1"). Using meaningful names is good programming practice: it helps you keep your programs straight in your own mind, and it helps others understand your programs.Don't confuse the <strong style="color:black;">Name</strong> of a component with the <strong style="color:black;">Text</strong> of a component. The <strong style="color:black;">Text</strong> is what appears on the screen. The <strong style="color:black;">Name</strong> is the name your program uses to refer to the component. You'll see the name in the Components structure list in the Designer and on the drawers in the Blocks editor.</pre><h4 class="ai-header">Making phone calls</h4> <p>In <span style="color:green;">HelloPurr</span>, you made the phone play a sound when the button was clicked. <span style="color:green;">PicCall</span> in almost the same, except that instead of playing a sound, the phone makes a call.</p> <p>App Inventor's <strong>PhoneCall</strong> component makes phone calls. You can find PhoneCall in the Social section of the Palette. Open that section and drag out a PhoneCall into the viewer. It will go into the Non-visible components area. Name it "TopCall". The PhoneCall's <strong style="color:green;">PhoneNumber</strong> property determines the number to call. Set that to some 10-digit phone number you'd like to call. Here's how the Designer should look:</p> <p><img src="/sites/all/files/ai2tutorials/picCall/PicCallDesigner.png" /></p> <p>Now switch to the Blocks Editor and pull out the <span class="eventblock">when TopButton.Click do</span> block. In the <span class="eventblock">do</span> slot, place a <span class="callblock">call TopCall.MakePhoneCall</span> block from the TopCall drawer, so that the event handler looks like this:</p> <p><img src="/sites/all/files/ai2tutorials/picCall/PicCallWhenClick.png" /></p> <p>Go ahead and test what you have so far on the phone: Press the button and make the call. You could package this up as an app right now. It would be a pretty limited app, always calling the same fixed number, some people might find that useful.</p> <h4 class="ai-header">Phone contact information</h4> <p>In addition to making phone calls, App Inventor apps can also get information from the phone's contact list. You do this with the <strong>PhoneNumberPicker</strong> component.</p> <p>Pull out a PhoneNumberPicker component from the Social section of the Palette, place it under <span style="color:green;">TopButton</span>. A PhoneNumberPicker is a kind of button: when you press it, it brings up your phone contacts list and lets you pick someone. Change the name of the PhoneNumberPicker to "TopPick", and change its <strong style="color:green;">Text</strong> to "Press to pick a number to call". Try it by pressing the picker on your phone: you should see your contacts come up, and you can pick one. Nothing will happen after you pick, because you haven't yet told the components to do anything. You'll do that next.</p> <h4 class="ai-header">Using the picker</h4> <p>Switch to the Blocks window and open the drawer for <span style="color:green;">TopPick</span>. Drag out the <span class="eventblock">when TopPick.AfterPicking do</span> block. This lets you define an event handler that says what to do after you've picked a number from your contacts.</p> <p>Now open the <span style="color:green;">TopCall</span> drawer and drag out <span class="setblock">set TopCall.PhoneNumber to</span> and fit it into the slot in the <span class="eventblock">when TopPick.AfterPicking do</span> block. Now drag out <span class="argblock">TopPick.PhoneNumber</span> from the <span style="color:green;">TopPick</span> drawer and plug it into the empty socket. Here's how your event handler should look:</p> <p><img src="/sites/all/files/ai2tutorials/picCall/PicCallAfterPicking.png" /></p> <p>Try it on the phone: Press the picker, choose a contact and a phone number. Then press the phone call button to make the call. Add a command to the event handler to set <span style="color:green;">TopButton</span>'s <strong style="color:green;">Text</strong> property to <span class="argblock">TopPick.PhoneNumber:</span></p> <p><img src="/sites/all/files/ai2tutorials/picCall/PicCallAfterPicking2.png" /></p> <h4 class="ai-header">Pictures</h4> <p>If you have a picture stored with your contacts, you can make the button show that along with the phone number, rather than always using the picture of the kitty. To do this, add an command to the event handler, to set the <strong style="color:green;">Image</strong> property of <span style="color:green;">TopButton</span> to be the the <strong style="color:green;">Picture</strong> property of <span style="color:green;">TopPick</span>:</p> <p><img src="/sites/all/files/ai2tutorials/picCall/PicCallAfterPicking3.png" /></p> <pre class="ai-box">PhoneNumberPicker has two properties that are easy to confuse: <strong style="color:black;">Picture</strong> and <strong style="color:black;">Image</strong>. <strong style="color:black;">Picture</strong> is the picture associated with the contact that's picked. <strong style="color:black;">Image</strong> is the image of the PhoneNumberPicker component as it appears in the Designer and on the phone.</pre><h4 class="ai-header">Enhancements</h4> <p>Here are some variations for you to try:</p> <ul><li>Add a second button, <span style="color:green;">BottomButton</span>, and a second PhoneNumberPicker, so that your app gives you the choice of two numbers.</li> <li>Add a label with instructions on how to use the app.</li> <li>Show the name of the person being called in addition to the phone number. Use an extra label to show the additional information.</li> </ul><h4 class="ai-header">Using PicCall</h4> <p>You can package <span style="color:green;">PicCall</span> and download it to the phone so you can use it when you're not connected to the computer. But there's a big limitation: Every time you restart <span style="color:green;">PicCall</span>, it starts fresh and does not remember what you picked last time. Later, we'll see how to use the <strong>TinyDB</strong> component to create apps that can remember information from one time to the next. Such information is called <em>persistent data</em>.</p> <h4 class="ai-header">Review</h4> <p>Here are the key ideas covered in this tutorial:</p> <ul><li>You can name components by means of the <strong>Rename</strong> button.</li> <li>App Inventor has components that can use information stored on the phone. The <strong>PhoneNumberPicker</strong> can get phone numbers and pictures for your contacts, and <strong>PhoneCall</strong> can make calls.</li> </ul><pre class="ai-box" style="background-image: url('/sites/all/files/ai2tutorials/picCall/android-warning-30x30.gif"><strong>Tip</strong>: The list that comes up when you run the phone number picker does not show the pictures associated with your contacts, on some Android systems. Even though the image isn't shown, the "Picture" property will still return a picture that will show up when you run the app, provided that the phone has a picture for that contact.</pre><p>Scan the following barcode onto your phone to install and run the sample app. </p><p><img src="/sites/all/files/ai2tutorials/picCall/PicCallBarcode.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/picCall/PicCall.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;">PicCall</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> Wed, 03 Jul 2013 14:50:54 +0000 aaron 358 at http://dev-explore.appinventor.mit.edu http://dev-explore.appinventor.mit.edu/ai2/piccall#comments PaintPot (Part 1) for App Inventor 2 http://dev-explore.appinventor.mit.edu/ai2/paintpot-part1 <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 tutorial has two parts: <a href="/ai2/paintpot-part1">Part 1</a> | <a href="/ai2/paintpot-part2">Part 2</a> </p> <p>This tutorial introduces the <strong>Canvas</strong> component for creating simple two-dimensional graphics. You'll build an app that lets you draw on the phone screen in different colors.</p> <pre class="ai-box"><strong>Historical note</strong>: PaintPot was one of the first programs developed to demonstrate the potential of personal computers, as far back as the 1970s.</pre><p><a href="http://cs.usfca.edu/~wolber/appinventor/bookSplits/ch2PaintPot.pdf">Download Book Chapter PDF</a></p> <h4>What you're building</h4> <p><img style="float:right;margin:5px;" src="/sites/all/files/ai2tutorials/paintPot1/PaintPotPart1PhoneImage.png" /></p> <p>With the <span style="font-style:italic;">PaintPot</span> app, you can:</p> <ul><li>Dip your finger into a virtual paint pot to draw in that color.</li> <li>Drag your finger along the screen to draw a line.</li> <li>Tap the screen to make dots.</li> <li>Use the button at the bottom to wipe the screen clean.</li> <li>Include an image as a drawing background.</li> </ul><p><span style="font-style:italic;"> <p>This tutorial assumes that you have completed the <a href="/ai2/hellopurr">HelloPurr</a> tutorial. This tutorial introduces the following App Inventor concepts:</p> <ul><li>The <strong>Canvas</strong> component for drawing.</li> <li>Controlling screen layout with <strong>Arrangement</strong> components.</li> <li>Event handlers that take arguments.</li> <li>Variables.</li> </ul><h4 class="ai-header">Before starting</h4> <p>Make sure your computer and your phone are set up to use App Inventor. Start a new project in the Designer window, and name it <span style="font-style:italic;">"PaintPot"</span>. Open the Blocks Editor, click <strong>Connect to Phone</strong>, and make sure the phone has started the App Inventor app.</p> <h4 class="ai-header">Screen title</h4> <p>To get started, go to the Properties panel on the right of the Designer and change the screen <strong>Title</strong> to "PaintPot". You should see this change on phone, with the new title showing in the title bar.</p> <p>There are three names in App Inventor, and it's easy to confuse them:</p> <ol><li>The name you choose for your project as you work on it (in this case, <span style="font-style:italic;">PaintPot</span>). This will also be the name of the application if you package it for the phone.</li> <li>The name "Screen1", which is the name of the <strong>Screen</strong> component. You'll see it listed in the Components panel in the Designer. You can't change the name of the first Screen component in the current version of App Inventor but you can create additional screens with names of anything you should choose.</li> <li>The <strong>Title</strong> property of the screen, which is what you'll see in the phone's title bar. Title is a property of the <strong>Screen</strong> component. The Title starts out being "Screen1", which is what you used in <span style="font-style:italic;">HelloPurr</span>. However, you can change it, as you're doing for <span style="font-style:italic;">PaintPot</span>. To reiterate, the name and the title of Screen1 are initially the same, but you can change the title if you want.</li> </ol><h4 class="ai-header">Set up the Components</h4> <p>You'll use these components to make <span style="font-style:italic;">PaintPot</span>:</p> <ul><li>Three <strong>Buttons</strong> for selecting <strong style="color:red">red</strong>, <strong style="color:blue">blue</strong>, or <strong style="color:green">green</strong> paint, and another button for wiping the drawing.</li> <li>A <strong>Canvas</strong>, the drawing surface. This canvas has a <strong>BackgroundImage</strong>, which is <a href="/sites/all/files/ai2tutorials/helloPurr/kitty.png">this kitty</a> from the <span style="font-style:italic;">HelloPurr</span> tutorial. You can also draw on a blank canvas. That's just a canvas without a background image.</li> <li>There's also a component you don't see: you use a <strong>HorizontalArrangement</strong> to make the three color buttons line up.</li> </ul><p>That makes five components in all. Let's get them and build the app.</p> <h4 class="ai-header">Color Buttons</h4> <ul><li>Drag a <strong>Button</strong> component onto the Viewer and change the button's <strong>Text</strong> attribute to "Red" and make its <strong>BackgroundColor</strong> red.</li> <li>Click on <span style="font-style:italic;">Button1</span> in the components list in the Viewer to highlight it (it might already be highlighted) and use the <strong>Rename...</strong> button to change its name from "Button1" to "ButtonRed".</li> <li>Similarly, make two more buttons for blue and green, named "ButtonBlue" and "ButtonGreen", placing them vertically under the red button.</li> </ul><p>Here's how this should look in the designer, with the button names appearing in the list of project components. In this project, you're changing the names of the components rather than leaving them as the default names as you did with <span style="font-style:italic;">HelloPurr</span>. Using meaningful names makes your projects more readable to yourself and others.</p> <p><img src="/sites/all/files/ai2tutorials/paintPot1/PaintPotThreeButtonsVertically.png" /></p> <p>You should also see the three buttons on the phone screen.</p> <h4 class="ai-header">Layout with Screen Arrangement</h4> <p>You should now have three buttons, one above the other. The next step is to make them line up horizontally. You do this using a <strong>HorizontalArrangement</strong> component.</p> <ol><li>From the Palette's Screen Arrangement category, drag out a <strong>HorizontalArrangement</strong> component and place it under the buttons. Change the name of this component from "HorizontalArrangement1" to "ThreeButtons".</li> <li>In the Properties panel, change the <strong>Width</strong> of <span style="font-style:italic;">ThreeButtons</span> to "Fill Parent..." so that it fills the entire width of the screen.</li> <li>Move the three buttons side by side into the <strong>HorizontalArrangement</strong> component. <strong>Hint</strong>: You'll see a blue vertical line that shows where the piece you're dragging will go.</li> </ol><p>If you look in the list of project components, you'll see the three buttons indented under the <span style="font-style:italic;">ThreeButtons</span> to show that they are now its subcomponents. Notice that all the components are indented under <span style="font-style:italic;">Screen1</span>.</p> <p><img src="/sites/all/files/ai2tutorials/paintPot1/PaintPotThreeButtonsHoriz.png" /></p> <p>You should also see your three buttons line up in a row on the phone screen, although things might not look exactly as on the Designer. For example, the Arrangement's outline shows in the Designer but not on the phone.</p> <p>In general, you use Screen Arrangement to create simple vertical or horizontal layouts. You can create more complex layouts by nesting Screen Arrangement components. There is also a <strong>TableArrangement</strong> component (not covered in this tutorial).</p> <h4 class="ai-header">Canvas and wipe button</h4> <p>The final two components are the canvas and the wipe button.</p> <ol><li>From the Palette's Basic category drag a <strong>Canvas</strong> component onto the Viewer. Change its name to "DrawingCanvas". Set its <strong>Width</strong> to "Fill Parent" and set its <strong>Height</strong> to 300 pixels.</li> <li>Add a Background Image to the <strong>Canvas</strong>. Click on the field containing "None..." next to <strong>BackgroundImage</strong> in the canvas's Properties panel. You can use the same kitty.png file, if you still have it on your desktop from an earlier tutorial. Or you can use another image.<br /><pre class="ai-box">You can use any image you like, but you'll get the best results if the size of the image (in pixels) is close to the size at which you'll be showing it on the phone. Also, large images will take a long time to load, and might exceed the memory capacity of the phone allocates for applications.</pre></li> <li>From the Palette, drag the final button onto the screen, placing it under the canvas. Change its <strong>id</strong> to "ButtonWipe" and change its <strong>Text</strong> attribute to "Wipe".</li> </ol><p>You've now completed the steps to set the appearance of your app. Here's how this should look in the Designer. Next, you'll define how the components behave.</p> <p><img src="/sites/all/files/ai2tutorials/paintPot1/PaintPotDesigner.png" /></p> <h4 class="ai-header">Add behaviors to the components</h4> <p>Click the Blocks button to switch to the Blocks Editor. First you will set up the buttons that change the paint color. Later you will add blocks to decide what happens when someone touches or drags the screen.</p> <h4 class="ai-header">Add button event handlers</h4> <p>In the Blocks Editor:</p> <ol><li>Open the drawer for <span style="font-style:italic;">ButtonRed</span> and drag out the <span class="basicblock">when ButtonRed.Click </span> block.</li> <li>Open the <span style="font-style:italic;">DrawingCanvas</span> drawer. Drag out the <span class="setblock">set DrawingCanvas.PaintColor to </span> block (remember that the set block of components is a <a href="/concepts/dropdowns">dropdown</a> so PaintColor is a selection in the dropdown) and place it in the <span class="basicblock">do</span> section of <span class="basicblock">when ButtonRed.Click </span>.<br /><img src="/sites/all/files/ai2tutorials/paintPot1/canvasdropdown.gif" /></li> <li>Open the Colors drawer and drag out the block for the color Red and put it into <span class="componentsetblock">set DrawingCanvas.PaintColor to </span>. (Clicking on a color block after it's been placed will display a table of colors that you can select from.)</li> <li>Repeat steps 2-4 for the blue and green buttons.</li> <li>The final button to set up is the Wipe button. Make a click event handler for <span style="font-style:italic;">ButtonWipe</span> by dragging <span class="eventblock">when ButtonWipe.Click </span> from the <span style="font-style:italic;">ButtonWipe</span> drawer. From the <span style="font-style:italic;">DrawingCanvas</span> drawer, drag <span class="callblock">call DrawingCanvas.Clear </span> and place it in the <span class="eventblock">do</span> area of the <span class="eventblock">when ButtonWipe.Click</span> block.</li> </ol><p>The blocks for the buttons should look like this:</p> <p><img src="/sites/all/files/ai2tutorials/paintPot1/buttonsclick.png" /></p> <h4 class="ai-header">Add Touch-event Handlers</h4> <p>Now for the next step: drawing on the <strong>Canvas</strong>. You'll arrange things so that when you touch the canvas, you get a dot at the spot where you touch. If you drag your finger slowly along the canvas, it draws a line.</p> <ul><li>In the Blocks Editor, open the drawer for the canvas and drag the <span class="eventblock">when DrawingCanvas.Touched</span> block to the workspace. As soon as you drag the block out, you may notice three argument names located at the top of the block <strong>x</strong>, <strong>y</strong>, and <strong>touchedSprite</strong>. These arguments are also known as local variables and can get accessed by using the <span class="getblock">get</span> or <span class="setblock">set</span> block found in the Variables drawer.</li> </ul><p>You've already seen button click events. Clicks are simple, because there's nothing to know about the click other than that it happened. Other event handlers such as <span class="eventblock">when ... Touched</span> need information about the event. In App Inventor, this information is expressed as the value of arguments associated with the event handler. For the <span class="eventblock">when ... Touched</span> event, the first two arguments stand for the x and y coordinates of where the touch happened. We'll save <strong>touchedSprite</strong> for a later tutorial.</p> <ul><li>For this touch event, make the canvas draw a small circle at the point with coordinates (x, y). Drag out a <span class="callblock">call DrawingCanvas.DrawCircle</span> command from the canvas drawer and place it in the <span class="eventblock">do</span> section of <span class="eventblock">when DrawingCanvas.Touched</span>.</li> </ul><p>On the right side of the <span class="callblock">call DrawingCanvas.DrawCircle</span> block are three sockets where you must specify values for the x and y coordinates where the circle should be drawn, and <strong>r</strong>, which is the radius of the circle. For <strong>x</strong> and <strong>y</strong>, you'll use values of the arguments that were supplied to the Touched handler:</p> <ol><li>Open the Variables drawer. Find the <span class="getblock">get</span> block.</li> <li>Drag out two <span class="getblock">get</span> blocks and plug them into the corresponding sockets in the <span class="eventblock">when DrawingCanvas.Touched</span> block. Click on the dropdown to select <strong>x</strong> and <strong>y</strong> in the corresponding block.</li> <li>You'll also need to specify the radius of the circle to draw. Five (pixels) is a good value for this app. Click in a blank area of the screen and type the number 5 followed by return to create a number block with a value of 5. Typing on the blank area of the screen is called <a href="/concepts/typeblocking">typeblocking</a> and is a useful shortcut to know. This can be done for any block, not just numbers. Plug the block for 5 into the radius slot.</li> </ol><p>Here's how the touch event handler should look:</p> <p><img src="/sites/all/files/ai2tutorials/paintPot1/PaintPotTouchHandler.png" /></p> <p>Try out what you have so far on the phone. Touch a color button. Now touch the canvas, and your finger should leave a spot at each place you touch. Touching the Wipe button should clear your drawing.</p> <h4 class="ai-header">Add Drag Events</h4> <p>Finally, add the drag event handler. Here's the difference between a touch and a drag:</p> <ul><li>A touch is when you place your finger on the canvas and lift it without moving it.</li> <li>A drag is when you place your finger on the canvas and move your finger while keeping it in contact.</li> </ul><p>When you drag your finger across the screen, it appears to draw a giant, curved line where you moved your finger. What you're actually doing is drawing hundreds of tiny straight lines: each time you move your finger, even a little bit, you extend the line from your finger's immediate last position to its new position.</p> <p>A drag event comes with 6 arguments. These are three pairs of x and y coordinates that show:</p> <ul><li>The position of your finger back where the drag started.</li> <li>The current position of your finger.</li> <li>The immediately previous position of your finger.</li> </ul><p>There's also a sprite, which we'll ignore for this tutorial.</p> <p>Now make dragging draw a line between the previous position and the current position by creating a drag handler:</p> <ol><li>From the <span style="font-style:italic;">DrawingCanvas</span> drawer, drag the <span class="eventblock">when DrawingCanvas.Dragged</span> block to the workspace.</li> <li>Also from the <span style="font-style:italic;">DrawingCanvas</span> drawer, drag the <span class="callblock-ai2">call DrawingCanvas.DrawLine</span> block into the <span class="eventblock">do</span> slot of the <span class="eventblock">when DrawingCanvas.Dragged</span> block.</li> <li>Drag a <span class="getblock">get</span> block to the open slots in <span class="eventblock">when DrawingCanvas.Dragged</span> and select the corresponding value: <strong>x1</strong> and <strong>y1</strong> should be <strong>prevX</strong> and <strong>prevY</strong>; <strong>x2</strong> and <strong>y2</strong> should be <strong>currentX</strong> and <strong>currentY</strong>.</li> </ol><p>Here's the result:</p> <p><img src="/sites/all/files/ai2tutorials/paintPot1/PaintPotDragHandler.png" /></p> <p>Test your work by trying it on the phone: drag your finger around on the screen to draw lines and curves. Touch the screen to make spots. Use the Wipe button to clear the screen.</p> <p>In <a href="/ai2/paintpot-part2">PaintPot Part 2</a>, you'll see how to use global variables to create dots of different sizes.</p> <h4 class="ai-header">Review</h4> <p>Here are some of the ideas covered in this tutorial:</p> <ul><li>You can use Screen Arrangement components to specify screen layouts other than just placing components one under the other.</li> <li>The <strong>Canvas</strong> component lets you draw on it. It can also sense touches and drags.</li> <li>Some event handlers are called with information about the event, such as the coordinates of where the screen was touched. This information is represented by arguments. When you select an event handler that has arguments, App Inventor creates <span class="argblock">value</span> blocks for these and places them in the My Definitions drawer.</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/paintPot1/PaintPotBarcode.png" /></p> <p>Or <a href="/sites/all/files/ai2tutorials/paintPot1/PaintPot.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="/sites/all/files/ai2tutorials/paintPot1/PaintPot.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> </span></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/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/drawing-canvas" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Drawing Canvas</a> </li> </ul> </section> Wed, 03 Jul 2013 14:47:23 +0000 joanie 357 at http://dev-explore.appinventor.mit.edu http://dev-explore.appinventor.mit.edu/ai2/paintpot-part1#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 Magic 8-ball for App Inventor 2 http://dev-explore.appinventor.mit.edu/ai2/magic-8-ball <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"><h3>Lesson One: Magic 8-Ball Predicts the Future</h3> <p><img src="/sites/all/files/ai2tutorials/magic8ball/8ball.jpg" style="float:left;width:75px;" /></p> <p>This introductory module will guide you through building a “Magic 8-Ball” app with App Inventor 2. When activated, your 8-ball will deliver one of its classic predictions, such as “It is decidedly so” or “Reply hazy, try again.”</p> <h3>Learning Goals</h3> <p>After completing this app, you will be able to:</p> <ul><li>Navigate the App Inventor environment: designer, blocks editor, emulator and/or physical phone</li> <li>Correctly use the following App Inventor components: accelerometer sensor, button, sound</li> <li>Correctly use the following App Inventor concepts: making and using a list, responding to an event</li> </ul><h3>Materials</h3> <ul><li>A selection of images and sounds are available at the <a href="/media-library">App Inventor Media Library</a>.</li> <li>Optional supporting hard copy materials for the original App Inventor version of this tutorial such as the <a href="/media-library">App Inventor Overview Handouts</a>, and the <a href="https://docs.google.com/viewer?a=v&amp;pid=sites&amp;srcid=ZGVmYXVsdGRvbWFpbnxhcHBpbnZlbnRvcmxlc3NvbnN8Z3g6MjJkNmViOGQ3MDNmZWYwZQ">PDF version</a> of this lesson.</li> </ul><h3>Outline</h3> <ol><li><a href="/content/setup">Set up</a> computers and phones or emulators. (Suggestion: do this ahead of time)</li> <li>Part One:<a href="#m8one">Click a Button, Hear a Sound</a> </li> <li>Part Two: <a href="#m8two">Click the Button, Get a Prediction + Hear a Sound</a> </li> <li>Part Three: <a href="#m8three">Shake the Phone, Get a Prediction + Hear a Sound</a> </li> <li><a href="#m8four">Suggestions for further exploration:</a> Text-to-Speech, Rotating image, Custom prediction lists</li> </ol><h3><a name="m8one" id="m8one">Part One: Click a Button, Hear a Sound</a></h3> <p>The final Magic 8-Ball App will deliver a prediction from a list that you have designed. To get started, first we'll make a button with a picture on it, and program it to play a sound when the button is clicked.</p> <p style="color:green;">DESIGN: App Inventor Designer</p> <ol><li>To open the App Inventor Designer window, go to <a href="http://newblocks.appinventor.mit.edu">http://newblocks.appinventor.mit.edu</a>. See setup instructions above if you are not sure how to sign in.</li> <li>If you have already made an app (such as Hello Purr), you will automatically be directed to the Designer with the last project you worked on showing. Click "My Projects" in the upper left corner of the screen, which will take you to your list of projects. Click "New" and name your project something like "Magic8Ball"(note: spaces are not allowed).<br /><img src="/sites/all/files/ai2tutorials/magic8ball/newproject.png" /></li> <li>Download one image and one sound file from below to be used in your app. Right click (control-click) on the link of the image or sound, then choose "Download" or "Save As". Save the media files to a convenient location that you will remember. <ul><li><a href="http://dl.dropbox.com/u/90819513/Cha_Ching_Sound.mp3">ChaChing Sound</a></li> <li><a href="http://dl.dropbox.com/u/90819513/Clinking_Teaspoon_Sound.mp3">Clinking Teaspoon Sound</a></li> <li><a href="http://dl.dropbox.com/u/90819513/Ta%20Da%20sound.mp3">Tada Sound</a></li> <li><a href="http://dl.dropbox.com/u/90819513/image_8_ball.jpeg">Magic 8 Ball Image</a></li> <li><a href="http://dl.dropbox.com/u/90819513/magic8ball3.jpeg">Blank 8 Ball Image</a></li> </ul></li> <li>On the left column of the Designer, open the Basic palette, and drag a Button component over to the Viewer(#1).</li> <li>Set the button image to an 8-Ball image:<br />Click on your newly added button to see its properties in the Properties pane on the right. Under "Image" click on the word "None..." and a small selection window will pop up (#2). Click the "Add" button and browse to where you saved the 8-Ball image. Select the file, then click “OK” to close the selection window. Click “OK” again on the properties pane to close the small popup window (#3).</li> <li>Go to the text field in the Properties pane and delete the display text of your button component (#4).<br /><img src="/sites/all/files/ai2tutorials/magic8ball/newbutton.png" /><br /><img src="/sites/all/files/ai2tutorials/magic8ball/buttonproperties.png" /></li> <li>From the Media palette, drag over a Sound component onto the Viewer pane (#1). Notice that since the sound will not be a visible part of the app, it appears at the bottom of the Viewer pane, as a “Non-visible component”.</li> <li>Set the sound component's source file:<br />Click on your newly added sound component to see its properties in the Properties pane on the right. Under "Source" click in the small box on the word "None..." and a small selection window will pop up (#2). Click the "Add" button and browse to where you saved the sound file. Select the sound file, then click “OK” to close the selection window. Click “OK” again on the properties pane to close the small popup window (#3). </li> <p><img src="/sites/all/files/ai2tutorials/magic8ball/soundproperties.png" /></p><li>You have now completed the work in the Designer for Part One of this app. It's time now to go over to the Blocks Editor to program the behavior of these components.</li> </ol><p style="color:green;">BUILD: Blocks Editor</p> <p>In the upper right corner of the Designer, click on the Blocks button.</p> <p>Now you are going to tell your app how to behave when the button is clicked. This is actually very simple in App Inventor, because the "code" for the program only consists of two blocks!</p> <p>Once the Blocks Editor is open, there are several options running along the left side of the screen. We refer to these as "Palettes" with “Drawers.” </p> <p>From the blocks palette located under Screen1, click on the Button1 drawer. Drag the <span class="eventblock">when Button1.Click</span> block into the work area (#1). From the blocks palette, click on the Sound1 drawer, drag the <span class="callblock">Sound1.Play</span> block into the work area and insert it into the <span class="eventblock">when Button1.Click</span> block (#2). They will click together like magnetic puzzle pieces.</p> <p><img src="/sites/all/files/ai2tutorials/magic8ball/blocks_drag.png" /></p> <p>Your blocks should now look like this:</p> <p><img src="/sites/all/files/ai2tutorials/magic8ball/button1.click.png" /></p> <p>That's it! You've written the program for Part One of Magic 8-Ball. Now it's time to test that it's working right.</p> <p style="color:green;">TEST: Phone/Emulator</p> <p>You have now built an app! To test that it works, you either have to launch an emulator, or connect to a phone. Go back to the <a href="/ai2/setup">Setup Instructions</a> if you do not have a phone or an emulator running.</p> <p><b>Emulator</b>: click on the picture, you will hear the sound play.<br /><b>Phone</b>: tap the picture, you will hear the sound play.</p> <pre class="ai-box">Note: If you don't hear the sound, first be sure you have the volume turned up on your device (or computer if using emulator). Also, make sure your device has an SD card. App Inventor stores media files to the SD card. In some devices, the Play component does not work correctly. You will need to use the Player component instead of the Sound component.</pre><h3><a name="#m8two" id="#m8two">Part Two</a>: Output a Prediction</h3> <p>Now that we've gotten the button to perform an action (play a sound), we want to extend that action to include giving the user a prediction. First we'll need two labels: Label1 will display the instructions, and Label2 will display the chosen prediction. We'll use blocks to program a "list picker" to choose from a list of predictions. Each time the button is clicked, the app will change the text of Label2 to display the chosen prediction.</p> <p style="color:green;">DESIGN: App Inventor</p> <p>Go back to the Designer window in your browser and add some new things to your app.</p> <ol><li>From the Screen Arrangement palette, drag over the Vertical Arrangement component (#1). At first it will just look like an empty box, but when you put things in it, App Inventor will know that you want to line them up vertically (one on top of the other).</li> <p><img src="/sites/all/files/ai2tutorials/magic8ball/viewer_addvertarr.png" /></p> <li>From the Basic palette, drag over a Label component (#2) and drop it inside of the vertical arrangement component. In the Properties pane, change the "Text" property of Label1 to “Ask the Magic 8-Ball a question”.(#3)</li> <p><img src="/sites/all/files/ai2tutorials/magic8ball/vert_addlabel.png" /></p> <li>From the Basic palette, drag over another Label component (Label2) into the Vertical Arrangement box so that it sits right below Label1. Change the "Text" property of the Label2 to “Touch the Magic 8-Ball to receive your answer.” Now drag the 8-Ball image so that it is also inside the Vertical Arrangement component on top of the two labels. This will cause them to line up with each other in a vertical line. (Note: this can be tricky mouse work, but get them in there just right and the vertical arrangement will resize itself to fit everything.)</li> </ol><p><img src="/sites/all/files/ai2tutorials/magic8ball/align.png" /></p> <p>Now it’s time to go back into the Blocks Editor to program the components you just added to your project.</p> <p style="color:green;">BUILD: Blocks Editor</p> <p>Now for the fun part! You're going to make a list of predictions and program the button to pick one item from the list and display it inside Label2. The button will also still play the sound that you programmed in Part One. Here's how to do it...</p> <ol><li>From the blocks palette, click on Label2 drawer to see all of its associated blocks. Drag over the green <span class="componentsetblock">set Label2.BackgroundColor</span> and insert it just above the <span class="callblock">Sound1.Play</span> block. Notice that the <span class="eventblock">when Button1.Click</span> block automatically gets bigger to accomodate the new block.</li> <li>Clicking on the word "BackgroundColor" will allow you to change the property that is being set. We want to change the Text so our block will look like <span class="componentsetblock">set Label2.Text</span>. This is called a <a href="/support/concepts/mutators">mutator</a> block.<br /><img src="/sites/all/files/ai2tutorials/magic8ball/Label2.Text.png" /></li> <li>From the Built-In palette, click on the Lists drawer. Drag over the <span class="listblock">pick random item</span> block and connect it to the open socket of the <span class="componentsetblock">set Label2.Text</span> block.<br /><img src="/sites/all/files/ai2tutorials/magic8ball/Listdrawer.png" /></li> <li>From the Built-In palette, click on Lists again, then drag out the <span class="listblock">make a list</span> block and plug it into the "list" socket on the right side of the <span class="listblock">pick random item</span> block.</li> <li>From the Built-In palette, click on the Text drawer, drag out a <span class="textblock">text</span> block and connect it to the item socket of the <span class="listblock">make a list</span> block. Click directly on the word “text” so that it gets highlighted. You can then type in new text there. Think about the sayings you want in your list of predictions for the Magic 8-Ball. Type the first prediction into this new text block.</li> <li>Notice after you plug in two text blocks, there are no more sockets to add more responses. To create more sockets, you need to click the blue plus button. <span class="listblock">make a list</span> is a <a href="/support/concepts/mutators">mutator</a> block and thus can be expanded or shrunk by clicking the blue plus sign.<br /><img src="/sites/all/files/UserGuide/blocks/lists/makealist.gif" /></li> <li> Plug each text block into the <span class="ai-blocks">pick random item</span> block. (Ideas for answers: <a href="http://en.wikipedia.org/wiki/Magic_8-Ball">http://en.wikipedia.org/wiki/Magic_8-Ball</a>)</li> </ol><p>Blocks should look something like this:</p> <p><img src="/sites/all/files/ai2tutorials/magic8ball/finalblocks.png" /></p> <p>You've got a Magic 8-Ball App! Now your app is fully functional and will predict the future with absolute certainty. Test out that this works, and then come back for some challenge tasks to make the app even more fun.</p> <p style="color:green;">TEST: Emulator or Phone</p> <p><b>Emulator</b>: Click on the picture of the 8-Ball, you should see one of your answers displayed in the Label2.Text field, followed by the sound.<br /><b>Phone</b>: Tap on the picture of the 8-Ball, you should see one of your answers displayed in the Label2.Text field, followed by the sound.</p> <h3><a name="#m8three" id="#m8three">Part Three</a>: Shake the Phone, Get a Prediction</h3> <p>Even though you have a working Magic 8-Ball app, there is a way to make it even more fun. You can use the accelerometer component to make the phone respond to shaking instead of responding to a button click. This will make the app much more like a real Magic 8-Ball toy. <em>Note: This part can only be done with an actual phone or tablet equipped with an accelerometer. If you are using an emulator, skip this part and go to Challenge 1 instead.</em></p> <p style="color;green;">DESIGN: App Inventor</p> <p>From the Sensors palette, drag over an <b>AccelerometerSensor</b> sensor component. Notice that it automatically drops down to the “Non-visible components” area of the Viewer window. This is the only new component you need, so go on over to the Blocks Editor to change your program.</p> <p style="color:green;">BUILD: Blocks Editor</p> <ol><li>From the blocks drawer, click on AccelerometerSensor, then drag out the block for <span class="eventblock">when AccelerometerSensor.Shaking</span>.</li> <li>Disconnect all of the blocks from inside the <span class="eventblock">Button1.Click</span> block and move them inside the <span class="eventblock">AccelerometerSensor.Shaking</span> block. <b>NOTE:</b> you can move whole sections of connected blocks by clicking on the uppermost or leftmost block and dragging it. The connected blocks will come with it.</li> <li>Delete the <span class="eventblock">Button1.Click</span> block to keep your work area tidy.</li> </ol><p>The blocks should look something like this:</p> <p><img src="/sites/all/files/ai2tutorials/magic8ball/shaking.png" /></p> <p style="color:green;">TEST: Phone/Emulator</p> <p><b>Phone</b>: When you shake the phone it should show an answer and play a sound.<br /><b>Emulator</b>: unfortunately, you can not simulate shaking the phone when using the emulator.</p> <p style="color:green;">Package the App to Your Phone!</p> <p>Your app would disappear if you were to disconnect your phone from the Blocks Editor. This is because the app is still stored on the App Inventor server and not on your phone. Follow <a href="/support/packaging-apps">these instructions</a> to package your app to your phone or to make an ".apk" file that can be installed on any android phone. Or, if you want to make your app even cooler, try the challenges below.</p> <h3>Challenge 1: Make the Magic 8-Ball Speak</h3> <p>Instead of (or in addition to) making the prediction appear as text, can you make the 8-Ball speak it aloud? Hint: the text-to-speech component is under the <b>Other Stuff</b> palette in the Designer. <em>Note: Most Android devices have the text-to-speech (TTS) capability, but if you have trouble getting the TTS component in App Inventor to work, you may need to find out how to install TTS and/or enable TTS on your device.</em></p> <h3><a name="#m8four" id="#m8four">Suggestions for Further Exploration</a></h3> <p> </p><ul><li>Make the image rotate when the phone is shaken or have several images that the app rotates through while the phone is shaken. You could use this technique to make it look like the triangle piece inside the 8-ball window is surfacing. You could also make different images for different predictions and display the correct image for each prediction.</li> <li>Make a similar app but for a different purpose. The phone could be used in place of dice or yahtzee letters. It could simulate a coin toss or a random number or color generator for investigating probability.</li> <li>Ask end users to add choices to the list of predictions (See <a href="/ai2/makequiz">Make Quiz</a> tutorial).</li> <li>"Crowd source" for prediction choices: allow people to send text messages and have the app add them to the list.</li> <li>Make the 8 Ball app a "server" so that anyone who sends a text to it will receive a text message prediction in return.</li> <li>Complete change the list to humorous choices (e.g. an app for teacher to use when a student has an excuse for not doing homework), or for useful purposes like randomly selecting a name from amongst people in the class.</li> </ul><pre class="ai-box">Done with Magic 8-Ball? Return to <a href="/teach">Curriculum (Teacher Resources)</a> or <a href="/ai2/tutorials">Tutorials</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/magic8ball/Magic8BallBarcode.png" /></p> <p>Or <a href="/sites/all/files/ai2tutorials/magic8ball/Magic8Ball.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="/sites/all/files/ai2tutorials/magic8ball/Magic8Ball.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/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/accelerometer" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Accelerometer</a> </li> </ul> </section> Tue, 02 Jul 2013 20:43:39 +0000 joanie 355 at http://dev-explore.appinventor.mit.edu http://dev-explore.appinventor.mit.edu/ai2/magic-8-ball#comments StockQuotes for App Inventor 2 http://dev-explore.appinventor.mit.edu/ai2/stockquotes <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; } /*--><!]]>*/ </style><h2 class="ai-header"><span style="color:green;">StockQuotes</span></h2> <h4 class="ai-header">What You're Building</h4> <p>Just like you can access web pages from your phone -- for example, to look up a stock price -- so can App Inventor. This app enables the user to enter a stock symbol, then looks up the price of the stock on Yahoo! Finance and displays the price on the phone.</p> <p>This tutorial assumes that 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 event handlers. If you are not familiar with the basics, try stepping through some of the <a href="http://explore.appinventor.mit.edu/content/tutorials">basic tutorials</a> before continuing.</p> <h4 class="ai-header">Introduction</h4> <p>This tutorial includes</p> <ol><li>Accepting text input from the user to specify the stock symbol.</li> <li>Using the Web component to ask Google Finance for the latest price for the stock.</li> <li>Displaying the result.</li> </ol><h4 class="ai-header">Getting Started</h4> <p>Connect to the App Inventor web site and start a new project. Name it StockQuotes, and also set the screen’s <b style="color:green;">Title</b> to “Stock Quotes”. Open the Blocks Editor and connect it to the phone.</p> <h4 class="ai-header">Set up the Components</h4> <p>Use the component designer to create the user interface. When you are done, it should look something like the picture below. Additional instructions are below the picture.</p> <p><img src="/sites/all/files/ai2tutorials/stockQuotes/components1.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>TextBox</b> </td> <td>Basic</td> <td style="color:green;">StockSymbolTextBox</td> <td>Where the user enters the stock symbol</td> </tr><tr><td> <b>Button</b> </td> <td>Basic</td> <td style="color:green;">GetQuoteButton</td> <td>To request the stock quote</td> </tr><tr><td> <b>Label</b> </td> <td>Basic</td> <td style="color:green;">ValueLabel</td> <td>To display the stock quote</td> </tr><tr><td> <b>Web</b> </td> <td>Other stuff</td> <td style="color:green;">Web1</td> <td>To request and receive the stock quote</td> </tr></table><p>Stick with the default properties except for the following changes:</p> <table><tr style="background-color: #EFEFEF; font-weight: bold;"><td>Component</td> <td>Action</td> </tr><tr><td><b>StockSymbolTextBox</b></td> <td>Set its <b style="color:green;">Hint</b> property to "Enter a stock symbol". Clear its <b style="color:green;">Text</b> property by deleting or backspacing over the contents.</td> </tr><tr><td><b>GetQuoteButton</b></td> <td>Set its <b style="color:green;">Text</b> property to "Get Stock Quote".</td> </tr><tr><td><b>ValueLabel</b></td> <td>Clear its <b style="color:green;">Text</b> property.</td> </tr></table><h4 class="ai-header">The Yahoo! Finance API</h4> <p>Many web services provide an <em>application programmer interface</em> (API) for developers to enable their programs to access the service. Some ways to discover APIs are through the website <a href="http://programmableweb.com">http://programmableweb.com</a> or just by doing a web search for the service name and “API”.</p> <p>The Yahoo! Finance API is documented in gory detail at <a href="http://www.gummy-stuff.org/Yahoo-data.htm">http://www.gummy-stuff.org/Yahoo-data.htm</a> . The highlights are that you can get the latest price for the stock with the symbol "GOOG", for example, with the URL <a href="http://finance.yahoo.com/d/quotes.csv?f=l1&amp;s=GOOG">http://finance.yahoo.com/d/quotes.csv?f=l1&amp;s=GOOG</a> . The section "f=l1" (lower-case letter L, followed by the number 1) says we would like the latest price, and the section “s=GOOG” says we would like information about the stock whose symbol is “GOOG”. The result is returned in comma-separated value (CSV) format, which you may be familiar with from spreadsheets. Since only one value will be returned for our query, the result will be a plain old number, such as “511.5”, without any commas. (Commas would be used if we requested multiple pieces of data from Yahoo!, such as the name of the company and the daily trade volume.)</p> <h4 class="ai-header">Add Behaviors to the Components</h4> <h5 class="ai-header">Requesting the Data</h5> <p>The blocks to make the web request are shown here and detailed below:</p> <p><img src="/sites/all/files/ai2tutorials/stockQuotes/request-data.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="eventblock">GetQuoteButton.Click</span></td> <td>GetQuoteButton</td> <td>Handle a click of the "Get Quote" button.</td> </tr><tr><td><span class="componentsetblock">set Web1.Url to</span></td> <td>Web1</td> <td>Specify the URL to request.</td> </tr><tr><td><span class="textblock-ai2">call make text</span></td> <td>Text</td> <td>Concatenate the parts of the URL.</td> </tr><tr><td><span class="textblock-ai2">text</span> (<a href="http://finance.yahoo.com/d/quotes.csv?f=l1&amp;s=">http://finance.yahoo.com/d/quotes.csv?f=l1&amp;s=</a>)</td> <td>Text</td> <td>Specify the first unchanging part of the URL.</td> </tr><tr><td><span class="componentsetblock">StockSymbolTextBox.Text</span></td> <td>StockSymbolTextBox</td> <td>Get the stock symbol from the text box.</td> </tr><tr><td><span class="eventblock">call Web1.Get</span></td> <td>Web1</td> <td>Make the web request.</td> </tr></table><p>The meaning is: When GetQuoteButton is clicked:</p> <ol><li>Build the Web component’s URL by concatenating “<a href="http://finance.yahoo.com/d/quotes.csv?f=l1&amp;s=">http://finance.yahoo.com/d/quotes.csv?f=l1&amp;s=</a>” (which you should copy and paste into the text block) and the symbol entered by the user (StockSymbolTextBox.Text).</li> <li>Request the page specified by the URL. (This is like pressing return after entering a URL in your web browser.)</li> </ol><h5 class="ai-header">Receiving the Data </h5><p>When the response to the web request arrives, the <span class="eventblock">Web.GotText</span> event is raised with four parameters (only some of which we’ll use in this app):</p> <ol><li><b>url</b>: the URL of the original request (which is useful if requests are made with many different URLs).</li> <li><b>responseCode</b>: <a href="http://en.wikipedia.org/wiki/List_of_HTTP_status_codes">the HTTP status code</a>, which indicates whether the web request succeeded or how it failed; for example, 200 means that the request succeeded, 404 that the page could not be found, etc.</li> <li><b>responseType</b>: <a href="http://en.wikipedia.org/wiki/Mime_type">the MIME type</a> of the response, such as “text/csv” in this app, “image/jpeg”, etc.</li> <li><b>responseContent</b>: the data being returned, such as “511.5”.</li> </ol><p>Here are a picture and table of the blocks you need to create:</p> <p><img src="/sites/all/files/ai2tutorials/stockQuotes/receive-data.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="eventblock">Web1.GotText</span></td> <td>Web1</td> <td>Specify what to do when the reply comes back from the web.</td> </tr><tr><td><span class="controlblock-ai2">ifelse</span></td> <td>Control</td> <td>Provide different behavior depending on whether the request succeeded.</td> </tr><tr><td><span class="variableblock">get responseCode</span></td> <td>Variables</td> <td>Gets the response code returned for the web request, which...</td> </tr><tr><td><span class="mathblock-ai2"> = </span>(equals) block</td> <td>Math</td> <td>...is checked for equality with...</td> </tr><tr><td><span class="eventblock">number</span> (200)</td> <td>Math</td> <td>...200, the code for valid web responses.</td> </tr><tr><td><span class="componentsetblock">set ValueLabel.Text to</span></td> <td>ValueLabel</td> <td>Display the result on the screen.</td> </tr><tr><td><span class="textblock-ai2">call make text</span></td> <td>Text</td> <td>Build the result by concatenating...</td> </tr><tr><td><span class="textblock-ai2">text</span> ("Current value: ")</td> <td>Text</td> <td>...the text “Current value: “ and...</td> </tr><tr><td><span class="variableblock">get responseContent</span></td> <td>Variables</td> <td>Gets the value returned from the web.</td> </tr><tr><td><span class="componentsetblock">set ValueLabel.Text to</span></td> <td>ValueLabel</td> <td>Display an error message.</td> </tr><tr><td><span class="textblock-ai2">text</span> ("Error getting stock quote")</td> <td>Text</td> <td>The error message</td> </tr></table><p>Here's a description of the block's behavior:</p> <ol><li>If the response code indicates that the web request succeeded (= 200), set the label to the concatenation of “Current value: “ and the returned data (e.g., 511.5).</li> <li>Otherwise, set the label to “Error getting stock quote”.</li> </ol><h4 class="ai-header">Review</h4> <p>Here are some ideas introduced in this tutorial:</p> <ol><li>Using an application programmer interface (API)</li> <li>Making a request with the Web component</li> <li>Checking whether a web request was successful</li> <li>Displaying information returned from the web</li> </ol><p>These ideas will be developed further in the second part of this tutorial, which is under development.</p> <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/stockQuotes/StockQuotesBarcode.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/stockQuotes/stockQuotes.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> <h4 class="ai-header">Credits</h4> <pre class="ai-box">This tutorial is based on <a href="http://appinventorblog.com/2011/06/02/app-inventor-has-a-new-component-the-web/">an app created by Prof. David Wolber</a> and relies on the Yahoo! Finance API. Done with <span style="color:black;">StockQuotes</span>? Return to the other tutorials <a href="http://explore.appinventor.mit.edu/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/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/external-api" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">External API</a> </li> </ul> </section> Tue, 02 Jul 2013 20:35:01 +0000 aaron 354 at http://dev-explore.appinventor.mit.edu http://dev-explore.appinventor.mit.edu/ai2/stockquotes#comments VideoWall for App Inventor 2 http://dev-explore.appinventor.mit.edu/ai2/videowall <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; } /*--><!]]>*/ </style><h4 class="ai-header">What you're building</h4> <p>The VideoWall app tutorial demonstrates how you can control the size of a video playing in an app by using the <strong>Video Player</strong> component's <b style="color:green;">Width</b>, <b style="color:green;">Height</b>, and <b style="color:green;">FullScreen</b> features. The VideoWall uses media assets (videos stored in the app itself), but you can use the app to display videos from the internet as well.</p> <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> <h4 class="ai-header">Getting Started</h4> <p>Connect to the App Inventor web site and start a new project. Name the new project VideoWall and set the screen's Orientation to Landscape.</p> <p>Download the following video files* for use later on:</p> <ul><li><a href="/sites/all/files/ai2tutorials/videoWall/bigbuckbunny.3gp">BigBuckBunny (bigbuckbunny.3gp)</a></li> <li><a href="/sites/all/files/ai2tutorials/videoWall/nasa.3gp">NASA (nasa.3gp)</a></li> <li><a href="/sites/all/files/ai2tutorials/videoWall/sintel.3gp">Sintel (sintel.3gp)</a></li> </ul><p>*Attributions for these videos are included at the end of this tutorial.</p> <h4 class="ai-header">Introduction</h4> <p>The finished VideoWall app will display a wall of three videos that can be expanded to their true size and then shrunk back down again. The app will also allow you to display the videos in fullscreen. This tutorial assumes you have followed earlier tutorials to learn how the following blocks work:</p> <ul><li><span class="variableblock">Variables</span></li> <li><span class="callblock-ai2">Procedures</span></li> <li><span class="eventblock">Button.Click blocks</span></li> <li><span class="controlblock-ai2">Control (if-else) blocks</span></li> </ul><p>This tutorial introduces the following:</p> <ul><li>Resizing the VideoPlayer</li> <li>Showing the VideoPlayer video in fullscreen mode</li> </ul><h4 class="ai-header">Set up the Components</h4> <p>Use the component designer to create the interface for the <span style="color:green;">VideoWall</span>. When completed, the designer should look similar to the snapshot below.</p> <p><img src="/sites/all/files/ai2tutorials/videoWall/setupcomponents.png" /></p> <p>First, you need to upload the video files. Click on the Add... button and select a video file downloaded earlier. Repeat this step to add the other two video files. Now create the interface by dragging and dropping the components from the Palette to 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>HorizontalArrangement</b> </td> <td>Screen Arrangement</td> <td style="color:green;">HorizontalArrangement1</td> <td>Holds all other components: makes the three vertical arrangements line up side by side</td> </tr><tr><td> <b>VerticalArrangement</b> </td> <td>Screen Arrangement</td> <td style="color:green;">VerticalArrangement1</td> <td>Holds the left-most VideoPlayer and controls</td> </tr><tr><td> <b>VerticalArrangement</b> </td> <td>Screen Arrangement</td> <td style="color:green;">VerticalArrangement2</td> <td>Holds the middle VideoPlayer and controls</td> </tr><tr><td> <b>VerticalArrangement</b> </td> <td>Screen Arrangement</td> <td style="color:green;">VerticalArrangement3</td> <td>Holds the right-most VideoPlayer and controls</td> </tr><tr><td> <b>VideoPlayer</b> </td> <td>Media</td> <td style="color:green;">VideoPlayer1</td> <td>Displays the BigBuckBunny video</td> </tr><tr><td> <b>VideoPlayer</b> </td> <td>Media</td> <td style="color:green;">VideoPlayer2</td> <td>Displays the NASA video</td> </tr><tr><td> <b>VideoPlayer</b> </td> <td>Media</td> <td style="color:green;">VideoPlayer3</td> <td>Displays the Sintel video</td> </tr><tr><td> <b>Button</b> </td> <td>Basic</td> <td style="color:green;">ResizeButton1</td> <td>Resizes VideoPlayer1</td> </tr><tr><td> <b>Button</b> </td> <td>Basic</td> <td style="color:green;">ResizeButton2</td> <td>Resizes VideoPlayer2</td> </tr><tr><td> <b>Button</b> </td> <td>Basic</td> <td style="color:green;">ResizeButton3</td> <td>Resizes VideoPlayer3</td> </tr><tr><td> <b>Button</b> </td> <td>Basic</td> <td style="color:green;">FullScreenButton1</td> <td>Shows the VideoPlayer1 video in fullscreen</td> </tr><tr><td> <b>Button</b> </td> <td>Basic</td> <td style="color:green;">FullScreenButton2</td> <td>Shows the VideoPlayer2 video in fullscreen</td> </tr><tr><td> <b>Button</b> </td> <td>Basic</td> <td style="color:green;">FullScreenButton3</td> <td>Shows the VideoPlayer3 video in fullscreen</td> </tr></table><p>Set the properties as described below:</p> <table><tr style="background-color: #EFEFEF; font-weight: bold;"><td>Component</td> <td>Action</td> </tr><tr><td style="color:green;">HorizontalArrangement1</td> <td>Set Width to Fill parent...</td> </tr><tr><td style="color:green;">VerticalArrangement1, VerticalArrangement2, <span style="color:black;">and</span> VerticalArrangement3</td> <td>Set Width to Fill parent...</td> </tr><tr><td style="color:green;">ResizeButton1, ResizeButton2, <span style="color:black;">and</span> ResizeButton3</td> <td>Set Text to "Grow" and set Width to Fill parent...</td> </tr><tr><td style="color:green;">FullScreenButton1, FullScreenButton2, <span style="color:black;">and</span> FullScreenButton3 </td> <td>Set Text to Show FullScreen and set Width to Fill parent...</td> </tr><tr><td style="color:green;">VideoPlayer1</td> <td>Set Source to bigbuckbunny.3gp , set Width to Fill parent... , and set Height to 36 pixels</td> </tr><tr><td style="color:green;">VideoPlayer2</td> <td>Set Source to nasa.3gp , set Width to Fill parent... , and set Height to 36 pixels</td> </tr><tr><td style="color:green;">VideoPlayer3</td> <td>Set Source to sintel.3gp , set Width to Fill parent... , and set Height to 36 pixels</td> </tr></table><h4 class="ai-header">Add Behaviors to the Components</h4> <p>The interface is complete, but the buttons don't resize the videos yet. Open the Blocks Editor to add the behavior to the buttons. First, you'll define three variable blocks to keep track of the size of the VideoPlayers:</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="variableblock">initialize global name to</span></td> <td>Variables</td> <td>Defines the vid1_zoomed variable (rename it)</td> </tr><tr><td><span class="variableblock">initialize global name to</span></td> <td>Variables</td> <td>Defines the vid2_zoomed variable (rename it)</td> </tr><tr><td><span class="variableblock">initialize global name to</span></td> <td>Variables</td> <td>Defines the vid3_zoomed variable (rename it)</td> </tr></table><p>The three variables should like this:</p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/videoWall/flagblocks.png" /></p> <p>Create the <span class="callblock">resizeVideoPlayer Procedure</span> block. There are three VideoPlayers in the app, but you'll use one Procedure block to resize all three. To accomplish this simplicity, you will use the Any Component blocks component <strong>Any VideoPlayer</strong> blocks. Create the <span class="callblock-ai2">resizeVideoPlayer Procedure</span> block using the following blocks:</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="callblock-ai2">Procedure</span></td> <td>Procedures</td> <td>Defines the resizeVideoPlayer procedure. Use the mutator ability of the procedure to add three arguments: x2, x3, x5.</td> </tr><tr><td><span class="controlblock-ai2">ifelse</span></td> <td>Control</td> <td>Defines the ifelse block that chooses whether the VideoPlayer is shrunk or expanded</td> </tr><tr><td><span class="logicblock-ai2">=</span> block</td> <td>Logic</td> <td>Defines the equals block for testing if the zoomed block is true</td> </tr><tr><td><span class="logicblock-ai2">true</span></td> <td>Logic</td> <td>Defines the block that zoomed is compared to</td> </tr><tr><td><span class="componentsetblock">VideoPlayer.Width</span> (x2)</td> <td>Any VideoPlayer</td> <td>Sets the VideoPlayer Width to a number</td> </tr><tr><td><span class="mathblock-ai2">Number (-1)</span> (x2)</td> <td>Math</td> <td>Width to set VideoPlayer to</td> </tr><tr><td><span class="componentsetblock">VideoPlayer.Height </span> (x2)</td> <td>Any VideoPlayer</td> <td>Sets the VideoPlayer Height to a number</td> </tr><tr><td><span class="mathblock-ai2">Number</span> (x2), values of 26 and 144</td> <td>Math</td> <td>Height to set VideoPlayer to</td> </tr><tr><td><span class="componentsetblock">Button.text</span></td> <td>Any Button</td> <td>Changes the button text</td> </tr><tr><td><span class="textblock-ai2">Text</span></td> <td>Text</td> <td>Text to set button to. Make one text block text's Shrink and the other's Grow.</td> </tr></table><p>The <span class="callblock-ai2">resizeVideoPlayer</span> block should look like the following:</p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/videoWall/resize_block.png" /></p> <p>The <span class="callblock-ai2">resizeVideoPlayer</span> block will be explained later after you create the blocks for responding to button clicks.</p> <h4 class="ai-header">Create the Click Blocks</h4> <p>The blocks you will create respond to clicks on the ResizeButton buttons. To build the three blocks, you will need the following blocks:</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="eventblock">ResizeButton1.Click</span></td> <td>ResizeButton1</td> <td>Defines the block for responding to clicks on ResizeButton1</td> </tr><tr><td><span class="eventblock">ResizeButton2.Click</span></td> <td>ResizeButton2</td> <td>Defines the block for responding to clicks on ResizeButton2</td> </tr><tr><td><span class="eventblock">ResizeButton3.Click</span></td> <td>ResizeButton3</td> <td>Defines the block for responding to clicks on ResizeButton3</td> </tr><tr><td><span class="callblock-ai2">ResizeVideoPlayer</span> (x3)</td> <td>Procedures</td> <td>Starts the resizeVideoPlayer block for resizing a VideoPlayer</td> </tr><tr><td><span class="logicblock-ai2">not</span> (x3)</td> <td>Logic</td> <td>Defines the block for switching the various zoomed block values</td> </tr><tr><td><span class="variableblock">set global vid1_zoomed</span></td> <td>Variables</td> <td>Sets the vid1_zoomed block to a different value</td> </tr><tr><td><span class="variableblock">set global vid2_zoomed</span></td> <td>Variables</td> <td>Sets the vid2_zoomed block to a different value</td> </tr><tr><td><span class="variableblock">set global vid3_zoomed</span></td> <td>Variables</td> <td>Sets the vid3_zoomed block to a different value</td> </tr><tr><td><span class="variableblock">global vid1_zoomed</span></td> <td>Variables</td> <td>Used to change the vid1_zoomed value.</td> </tr><tr><td><span class="variableblock">global vid2_zoomed</span></td> <td>Variables</td> <td>Used to change the vid2_zoomed value.</td> </tr><tr><td><span class="variableblock">global vid3_zoomed</span></td> <td>Variables</td> <td>Used to change the vid3_zoomed value.</td> </tr><tr><td><span class="componentsetblock">component ResizeButton1</span></td> <td>ResizeButton1</td> <td>Passed to the resizeVideoPlayer procedure</td> </tr><tr><td><span class="componentsetblock">component ResizeButton2</span></td> <td>ResizeButton2</td> <td>Passed to the resizeVideoPlayer procedure</td> </tr><tr><td><span class="componentsetblock">component ResizeButton3</span></td> <td>ResizeButton3</td> <td>Passed to the resizeVideoPlayer procedure</td> </tr><tr><td><span class="componentsetblock">component VideoPlayer1</span></td> <td>VideoPlayer1</td> <td>Passed to the resizeVideoPlayer procedure</td> </tr><tr><td><span class="componentsetblock">component VideoPlayer2</span></td> <td>VideoPlayer2</td> <td>Passed to the resizeVideoPlayer procedure</td> </tr><tr><td><span class="componentsetblock">component VideoPlayer3</span></td> <td>VideoPlayer3</td> <td>Passed to the resizeVideoPlayer procedure</td> </tr></table><p>The blocks should look like the following:</p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/videoWall/resize_blocks.png" /></p> <p>Most blocks in App Inventor require you to know exactly what component your app will manipulate when you design the app. For some apps, you will have several of the same type of component and you want to program the same behavior for all of the similar components (like the VideoPlayer blocks in this app). The blocks in the Any component section allow you to build some general manipulation on some type of component. When you built the <span class="callblock">resizeVideoPlayer procedure</span> block, you didn't know specifically which VideoPlayer would be used in the procedure. The <span class="callblock">resizeVideoPlayer</span> works on VideoPlayers; but not until the <span class="callblock">resizeVideoPlayer</span> block is used in the <span class="basicblock">ResizeButton1.Click</span> block (for example) is the specific VideoPlayer known.</p> <p><b>Note:</b> The <span style="color:green;">VideoWall</span> app could have been designed with a specific resizing procedure for each VideoPlayer. By using the Advanced blocks in a single resizing procedure, the app is much simpler.</p> <h4 class="ai-header">How the Blocks Work</h4> <p>Setting the Width and Height property for a VideoPlayer works exactly the same way as setting the Width and Height of a Button. For whatever positive number is set, the video playing will resize its appearance to fit that value. There are two values that are exceptions to the using positive values rule: -1 and -2. Setting VideoPlayer.Width or VideoPlayer.Height to -1 is like setting the Width or Height to <em>Fill parent</em> in the designer. Setting VideoPlayer.Width or VideoPlayer.Height to -2 is like setting the Width or Height to <em>Automatic</em> in the designer.</p> <pre class="ai-warning"><b>Warning:</b> You can set the VideoPlayer Width and Height to any positive number you want. The VideoPlayer will change its size to match the values you set; but on some devices, the VideoPlayer does not change its size correctly. The behavior on such devices is usually unpredictable.</pre><pre class="ai-testing"><b>Test this behavior.</b> Click on the Grow button below the BigBuckBunny video. The video's size should expand, and the text of the button should change to "Shrink". Click on the Shrink button below the BigBuckBunny video. The video's size should shrink back to its original size and the text should change back to "Grow".</pre><h4 class="ai-header">Create the blocks for showing fullscreen video</h4> <p>You will now add the blocks for showing the videos in fullscreen mode. Use the following blocks:</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="logicblock-ai2">true</span> (x3)</td> <td>Logic</td> <td>Value to set FullScreen as</td> </tr><tr><td><span class="eventblock">FullScreenButton1.Click</span></td> <td>FullScreenButton1</td> <td>Responds to clicks on FullScreenButton1</td> </tr><tr><td><span class="componentsetblock">set VideoPlayer1.FullScreen</span></td> <td>VideoPlayer1</td> <td>Used to show fullscreen video</td> </tr><tr><td><span class="eventblock">FullScreenButton2.Click</span></td> <td>FullScreenButton2</td> <td>Responds to clicks on FullScreenButton2</td> </tr><tr><td><span class="componentsetblock">set VideoPlayer2.FullScreen</span></td> <td>VideoPlayer2</td> <td>Used to show fullscreen video</td> </tr><tr><td><span class="eventblock">FullScreenButton3.Click</span></td> <td>FullScreenButton3</td> <td>Responds to clicks on FullScreenButton3</td> </tr><tr><td><span class="componentsetblock">set VideoPlayer3.FullScreen</span></td> <td>VideoPlayer3</td> <td>Used to show fullscreen video</td> </tr></table><p>The blocks should look like the following:</p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/videoWall/fullscreen_blocks.png" /></p> <h4 class="ai-header">How the Blocks Work</h4> <p>The <span class="componentsetblock">VideoPlayer.FullScreen</span> block takes a true/false value (also called a boolean) to tell it whether to go full screen or not. Setting a <span class="componentsetblock">VideoPlayer.FullScreen</span> block to true causes that VideoPlayer to be displayed in fullscreen mode. If there is another VideoPlayer in fullscreen mode, that VideoPlayer's .FullScreen value is set to false and it is replaced with the current VideoPlayer. If a <span class="componentsetblock">VideoPlayer.FullScreen</span> is true, setting a <span class="componentsetblock">VideoPlayer.FullScreen</span> block to false causes the fullscreen mode to be exited and the app's interface to display. Test this behavior. Start playing the BigBuckVideo, and click on the Show FullScreen button below the BigBuckBunny video. The app's interface should disappear and some media controls with the BigBuckBunny video should appear. Use the Back button on your device or the emulator to exit fullscreen. The app's interface should appear.</p> <h4 class="ai-header">Final Program</h4> <p>VideoWall Final Version</p> <p><img src="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/videoWall/blockseditor_full.png" /></p> <p>Package the final version of the app by choosing <b>Package For Phone | Barcode</b> 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>Now that you have finished the first <span style="color:green;">VideoWall</span> app, you might want to build some variations. For example:</p> <ul><li>Get more video files and add a second row to create a real VideoWall</li> <li>Use videos from an online server.</li> <li>Expand the resizeVideoPlayer procedure to resize VideoPlayers by small increments to create an animation effect. You could use multiple Clocks to start the resizeVideoPlayer procedure and animate multiple VideoPlayers at once.</li> </ul><p><b>If you distribute your app to others, make sure you respect any license requirements for the videos you use.</b></p> <p>Below are the attributions to the video files included in this demo app. The creators of the source videos that these clips are from do not endorse App Inventor.</p> <table><tr style="background-color: #EFEFEF; font-weight: bold;"><td>Video File</td> <td>Information</td> <td>Attribution</td> </tr><tr><td>bigbuckbunny.3gp</td> <td>A clip from the full length film</td> <td>(c) copyright 2008, Blender Foundation / <a href="http://www.bigbuckbunny.org">http://www.bigbuckbunny.org</a></td> </tr><tr><td>nasa.3gp</td> <td>A formatted version of the Mars' Whirling Dust Devil clip.</td> <td>Here is the <a>original video.</a></td> </tr><tr><td>sintel.3gp</td> <td>A clip from the full length film </td> <td>(c) copyright Blender Foundation | <a href="http://durian.blender.org">http://durian.blender.org</a></td> </tr></table><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/videoWall/VideoWallBarcode.png" /></p> <p>Or <a href="http://explore.appinventor.mit.edu/sites/all/files/ai2tutorials/videoWall/VideoWall.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="/sites/all/files/ai2tutorials/videoWall/VideoWall.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">MIT is grateful to <a href="http://explore.appinventor.mit.edu/people/vance-turnewitsch">Vance Turnewitsch</a> for developing this tutorial. Done with <span style="color:black;">VideoWall</span>? Return to the other App Inventor 2 tutorials <a href="http://explore.appinventor.mit.edu/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/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/video" typeof="skos:Concept" property="rdfs:label skos:prefLabel" datatype="">Video</a> </li> </ul> </section> Tue, 02 Jul 2013 20:18:30 +0000 aaron 353 at http://dev-explore.appinventor.mit.edu http://dev-explore.appinventor.mit.edu/ai2/videowall#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