G al ai2...an action sports game tutorial for App Inventor 2 The Goal ai2 app you code as part of this tutorial demonstrates techniques required to build an action game with App Inventor 2. Coding involves a Canvas, Image Sprites, ListPickers, Clocks, Sound and Player components and a few more objects. Sound and image files make the app colorful with simple graphics. All the app s code is pulled together on a single screen, Screen1, made possible through Vertical Layouts. The Canvas and Sprites are the primary tools used to build a Soccer goalie game (hmm, some people call this Football). The Goal ai2 player defends a goal as the opponent Android throws soccer balls at the pitch. Save as many balls as you can before the opponent makes four scores. The game can be easy or very hard; the developer gets to decide. Goal ai2 is a game and a test bed of development techniques the app in this tutorial has Developer Options. Your best friends coding action games are the App Inventor 2 Canvas and Sprite documentation http://ai2.appinventor.mit.edu/reference/components/animation.html and the appinventor.com book chapter 17 http://www.appinventor.org/bookchapters/chapter17.pdf (from the book App Inventor 2: Create your own Android Apps). Definately read these documents before continuing onward with this tutorial. These articles explain the basic concepts of game making (this tutorial does not).
Not a Soccer Game Please I don t want to make a Soccer game. Oh, OK, you don t have to develop a soccer goalie game. Build the kind of time waster app you want. Balls can be bullets, airplanes, birds, whatever it takes. Instead of soccer ball kicks, have some explosions. The physics and how you create the bullet, airplane or bird movement with App Inventor is the same as movement of the soccer ball (you might want to add flapping wings to the bird). Sound effects are only a recorder away. How to make an Animated Action Game First you need an idea. You probably would rather program a baseball game or tennis or?
Many of the game parts are created outside the App Inventor environment. A successful app requires great graphics and some sound. Produce the visual and sound effects yourself or find suitable free graphics/sounds or for which you are able to pay to use copyrighted material. The event handlers and methods of the Canvas and ImageSprite objects are key to developing this project. The AI2 Documentation Library (with a few edits) indicates the following: Canvasstuff: DrawText(texttext,numberx,numbery) Draws the specified text relative to the specified coordinates using the values of the FontSize and TextAlignment properties. Touched(numberx,numbery,booleantouchedSprite) When the user touches the canvas and then immediately lifts finger: provides the (x,y) position of the touch, relative to the upper left of the canvas. TouchedSprite is true if the same touch also touched a sprite, and false otherwise. ImageSprite Interval The interval in milliseconds at which the sprite's position is updated. For example, if the interval is 50 and the speed is 10, then the sprite will move 10 pixels every 50 milliseconds. Picture The picture that determines the sprite's appearance Rotates If true, the sprite image rotates to match the sprite's heading. If false, the sprite image does not rotate when the sprite changes heading. The sprite rotates around its center point. Speed The speed at which the sprite moves. The sprite moves this many pixels every interval. Visible True if the sprite is visible. Width X The horizontal coordinate of the left edge of the sprite, increasing as the sprite moves to the right. Y The vertical coordinate of the top of the sprite, increasing as the sprite moves down. CollidedWith(componentother) Handler for CollidedWith events, called when two sprites collide. Note that checking for collisions with a rotated ImageSprite currently checks against the sprite's unrotated position. Therefore, collision checking will be inaccurate for tall narrow or short wide sprites that are rotated. EdgeReached(numberedge)
Event handler called when the sprite reaches an edge of the screen. If Bounce is then called with that edge, the sprite will appear to bounce off of the edge it reached. Edge here is represented as an integer that indicates one of eight directions north(1), northeast(2), east(3), southeast(4), south ( 1), southwest( 2), west( 3), and northwest( 4). 1 4 2 3 3 2 4 1 Touched(numberx,numbery) When the user touches the sprite and then immediately lifts finger: provides the (x,y) position of the touch, relative to the upper left of the canvas Bounce(numberedge) Makes this sprite bounce, as if off a wall. For normal bouncing, the edge argument should be the one returned by EdgeReached. booleancollidingwith(componentother) Indicates whether a collision has been registered between this sprite and the passed sprite. MoveIntoBounds() Moves the sprite back in bounds if part of it extends out of bounds, having no effect otherwise. If the sprite is too wide to fit on the canvas, this aligns the left side of the sprite with the left side of the canvas. If the sprite is too tall to fit on the canvas, this aligns the top side of the sprite with the top side of the canvas. MoveTo(numberx,numbery) Moves the sprite so that its left top corner is at the specified x and y coordinates. PointInDirection(numberx,numbery) Turns the sprite to point towards the point with coordinates as (x, y). PointTowards(componenttarget) Turns the sprite to point towards a designated target sprite. The new heading will be parallel to the line joining the centerpoints of the two sprites. Design Concepts App Inventor is not Multi threaded App Inventor is an event driven compiler. AI2 creates single threaded apps. This means once a command is given with a block, the Android attempts to complete the instruction before starting the next action. The explanation is a simplification and essentially what happens. A developer must write code to avoid conflicts between instructions and to ensure intended actions happen, even if the coding instructions are in a Clock.Timer. The firing of a Clock
sometimes confuses Android and pre empts button touches. When a disruption happens, some of your block instructions might be skipped. Skipping happens because AI is event driven. When Timers are used to cue events, collisions between instructions may occur unless you are careful coding. Some redundant code in the example app helps prevent and ameliorate screen freezing or strange behaviour. There is no sure way to ensure all instructions are completed, especially when an action game app does LOTS of things. A double call Player1.Stop is coded to try to ensure a command from a button touch is carried out, even when the instant of implementation is in conflict with perhaps an instruction in a Clock component firing an action. A double coding technique does not always work. Multi threading capable compilers (executing various commands almost simultaneously and processing in the background) are more suitable for game creation. App Inventor will do a very good job as a single threaded app provided the developer codes to account for event driven programming and execution. How does one know what values to use for Canvas Coordinates? There is no trick, determining values is a matter of inspection and trial and error. Goal ai2 has a few built in tools to help determine what values might be appropriate. The prime tool is using the Canvas.Touched event handler to track. Use it to determine the x and y positions of areas you can touch on the screen. Here is a map of the 300 x 300 pixel game Canvas used in this app. The top of the Canvas is at y = 0; the left edge is at x = 0. The field mid field line is located at about y = 137. Each block represents 10 pixels Soccer field on top of the grid
I want the goalie only to be able to save a ball and earn points if a ball is touched on the screen if and only if the ball is touched within the area outlined in red. I needed to create a ring fence. I found the corners of the box by touching the screen and noting the x,y coordinates running the app in Developer Mode. I selected appropriate coordinates for the ring fence (Y greater or equal to 224 and X between 90 and 180). If..then and logic blocks then determine the behaviour of blocks touched within the ring fence (see the manageballs and manageballs2 procedures). Similarly the mid field marker s y coordinates (about y = 137) and the point at the top of the screen where the balls start to accelerate toward the player are determined (y= 20 in this example). Hard coded x and y values could be used for some points to specify sprite location, however many of the locations sprites are instructed to move to are coded within a certain Canvas pixel range and randomly selected. Allowing randomness provides game variety and interest. If everything is always the same, an app gets boring rapidly. A Single Screen The entire app is on Screen1. Virtual screens are created using Vertical layouts. The screens are shown or hidden by toggling their Visible property between true and false. Variability in Play Do the same thing long enough in a game and how boring. Keep the app exciting by providing ways to make the game interesting. The developer can change how the balls respond on the Canvas, how points are scored and ways to celebrate. The example app shows things that are easily varied. Altogether, varying sprite speed and start positions often result in significant changes in game play. A menu selects various ball configurations for the game (yes, more than one of the extra features can be simultaneously used during game play).
The selectable,built in routines within Goal ai2 change the location where the balls spawn, vary ball speed and switch the goal target criteria (what location or object a sprite points to). A toggleable button displays the status of these switches at any time during the game. One or more feature can be selected during a game. The options could be saved but that is left for you as homework. The balls can spawn (reappear) at the opponent s goal, at mid field or one ball at the opponent s goal and the other ball at midfield. Positioning the soccer ball starting points closer to the goal makes the app play difficult. A combination of fixed values, random values or a combination determine where the balls spawn. Select Two Balls (the default start for both balls at the opponent s goal), Ball Start Low/High (toggles between both balls spawning at the goal or mid field), or Balls High & Low (one ball spawns at the opponent s goal, the other at midfield). The balls are either directed to point to the center of the goal sprite (Sprite2) or to a range of x,y points randomly. The balls either move toward the goal or points near the goal. Use either PointInDirection(numberx,numbery)or PointTowards(componenttarget) in code depending on the effect you desire. The app toggles between the two options. SpriteTarget false points to a random point on a centerline in front of the goal, SpriteTarget true points toward the goal sprite, Sprite2. Erratic Balls varies both pointing targets and speed according to a Clock timer. Speed The speed the object moves is determined by the Speed and Interval properties together. The Speed property is the distance, in pixels, that the object will move each Interval. Set the Speed property to a value other than 0 to make a sprite move. Ball speed is programmed to change/vary. Higher number values for Sprite.Speed elicit faster ball movement. Select Slower Balls (the default) or Faster Balls. Always remember, the ball speed is actually a
function of Speed and Interval. In this app, Interval is kept constant although Speed is variable. Both properties can be varied in your version of the app. Drawing and Erasing Text from the Canvas Drawing text on the soccer playing field is easy. Use the DrawText block and appropriately position the text using the x and y coordinates. Making the text erase is awkward in App Inventor 2 ; the developer has to write over the existing text with the identical text displayed but in a color identical to the Canvas background image color. Determine the playing background color using an image manipulation program s color picker. Here the soccer field is shown on the Color Picker tool in GIMP. Use AI2 s make color block as indicated above on the left to create a custom color ( defaultcolor) to reproduce the background color shown on the Gimp image manipulation program display on the right Once the RGB color values are known, it is possible to code the erase routine with AI2 blocks. Layout Challenges You got a pretty good Canvas, now where are you going to put the game controls? App Inventor s layout tools are not wysiwyg unfortunately. A pleasing control layout is the result of lots of guessing, using Vertical and Horizontal layouts, Labels and Buttons as spacers, and viewing the layout on several size Android devices. What you see on the Designer screen is not exactly how the objects render on a device. Enhancements Goal ai2 uses home made sound files, a graphic image from Wikipedia modified to purpose and a sound file created by a university choir (that requires an acknowledgment in the app). The game you develop will be require pretty much the same type of externally developed files and images. Keep sound files short; the noise does not need to be high fidelity. Free tools like Audacity help to decrease the fidelity and more importantly file size of sound images. The programs allow you to edit the length and characteristics of the sound file. The example app uses very short sounds
(ball kick) for noises, in conjunction with the Sound component. Background music requires the Player component. Limit the size of images to the maximum screen size the images will display on. App Inventor can scrunch very large images into the 320 x 480 pixel screen of older phones using Automatic for the Width and Height; that is poor practice, wastes resources and often causes running issues. The lesson is make the images just the appropriate size outside of AI2 using an image editor like GIMP or Paint. Outside Tools: Image manipulation Paint (for Windows users) GIMP Sound manipulation Audacity Wave Pad Sound recording the Recorder component in AI2 records.3gp files a tape recorder Graphic Hints How to get circular balls The soccer ball starts as a 200 x 200 rectangular image on Wikipedia http://upload.wikimedia.org/wikipedia/commons/thumb/d/d3/soccerball.svg/200px Soccerball.sv g.png. The image is shrunk to 20 x 20 pixels. There is a problem. When displayed on the screen, the ball looks like We want the ball to look like The transformation from square to round is accomplished by making the white box around the ball image transparent using an image editing program. If you use GIMP, the following Menu jumps will get you started with transparency: Layer>Transparency or Colors>Color to Alpha. How to make a perspective playing field. The app perspective playing field is made from a free image of a soccer field from Wikipedia.
The original 2000 W x 3027 H pixel soccer field image is resized to Width 300 pixels (because the game screen will be 300 pixels wide. Why 300? Because I decided this size is a reasonable size. The game area fits on almost all Android phone screens leaving a margin. The margin is necessary to scroll thru a Canvas to a point lower on the screen). The resizing of the ball field image is done with Paint (Windows users). The image resizes to 300 x 454 when the width is set to 300 and the image tool is set to maintain proportions. The free GIMP image editing tool can make a perspective layout of the image. The flat image could be used in the game instead.. You will have to experiment with GIMP s perspective tool to arrive at the correct proportions you want. Resize, then make the perspective image fit into a 300 x 300 pixel box as shown below. The perspective image is the background for the Canvas. Find the perspective tool in GIMP with the following: Tools>Transform Tools>Perspective.
Sounds Developers can record many sounds yourselves, avoiding copyright and attribution issues. The soccer ball handling sound for this app is made by recording the kicking of a 1994 World Cup commemorative soccer ball. The crowd sound is a generic crowd at a sporting event on a continuous loop. The music is a free version of my country s national anthem recorded by the Roanoke College Choir ( http://roanoke.edu/media/choir/starspangledbanner.mp3 ), the whistles, rattles and horns are home recordings. The game intro music is from Dancing on Clouds by Eric Matyas, www.soundimage.org This longer piece is edited with Audacity for the introduction. The link to Eric s original file is http://soundimage.org/cool and mellow/ Dancing being edited with Audacity. Android devices need to load sounds at runtime because loading a file takes time. Sound1.Source is not set until after the program has started. To achieve the expected
performance during game play, the app should load the sounds when the program starts up. The soundsources block, placed in the Screen1.Initialize event handler, pre loads the sounds. Pre loading this way might allow you to use a single Player or Sound component and in any event will help ensure the sound you want plays almost immediately. You must set the Source immediately preceding a Player or Sound call to the sound you want played at the moment when you use several sound bites on the same Player or Sound Component. All the Sources are placed in a Procedure; you do not have to do that. A Procedure makes it easier to change files if you change your mind about what you want your app User to hear. All the file calls are in the same place. Goal ai2 was originally coded using single Player and Sound components. Timing issues were encountered. I resorted to using several components to ameliorate issues related to multiple sounds playing simultaneously coincident with a lot of game screen action. Some components are still used for more than a single sound. Images A source for flag images and icons is the Icon Archive. Many of the images from this source are free for personal use. Read the terms of use for individual images please. Play as whoever you want. If your favorite team/country is not here, the correct images are an Internet search away.
Many Bells and Whistles Goal ia2 has many options and toys. Code is provided to vary game play and some graphics are provided to make the app more appealing. Icons appear to reward ball saves and others to track the opponent s goals. You can add even more features because you are the developer. Realize the more toys, the larger the opportunity for delays in commands and collisions between commands. When you code additional features, what you code may not work the first time; often the issue is a problem of timing. Sometimes rearranging the order of blocks will fix some issues or moving some routines from mainline code into Clock.Timer event handlers. Avoid firing Clocks using similar TimerIntervals. Instead of three clocks firing at 1000, 1000 and 1000 ms intervals, fire them at 1000, 1121, 997 ms for example and you might avoid timing conflicts. Avoid placing all sprite movement routines into a single Timer; still use Timers but also use the various event handlers available. Elementary game rewards and notifications are provided. You get a soccer ball after thegolia successfully makes ten saves; the opponent's goals are tracked with colored balls, the country of the goalie is selectable and small rewards are provided for making saves. Where are the Blocks? The Variables The Boolean variables primarily define the game option configuration. Other variables contain initial, start up single values.
The Buttons Button2 is the START button. It s event handler contains the code to start and restart the app. The generous use of Procedures simplifies the code blocks. Button12 is the reset button. Button14 is the Quit button. Herein are contained the routines to save the high score to the TinyDB database using a Tag of highscore. The app close block is also here. Button15 is the crowd noise toggle. It turns the crowd noise on and off. Button16 is the game Pause button. Button17 is the game Help button. The help file is an html file stored in Media.
Button18 toggles the status of the various game play options so the player can see what options are in effect. The game options are selected using ListPicker1. Procedures ballspeed manages the speed of the soccer balls depending on options selected using the ListPicker1. Sprite3 s speed is intended to be a surprise when faster balls are selected.
agoal controls activities following the opponent Android scoring a goal. The blocks keep track of the number of goals scored and, depending on what is happening in the game, makes appropriate choices for the sounds played and images displayed. The TextToSpeech block (shown disabled and offset to the rest of the blocks) is a possible replacement for the horn noise..
ballstart controls the spawning location of the soccer balls after the balls pass the bottom edge of the playing field or if a goal is scored or a sprite touched. Celebrate is happy time. The procedure instructs the app on how to handle achieving a high score.
Development Options Development Options in the ListPicker hides several controls during game play. These controls are useful when modifying how you want game play to work. The Slider allows experimentation with very fast balls. The Canvas.Touched block shows the x and y position of any screen touch; it tells you where a point on the playing field is located by temporarily displying the x, y coordinates. The tool is useful when positioning sprites and developing ring fences. goaldisplay is a procedure to manage the graphic display of opponent goals that serve as a reminder to the player. The ball color progresses from gray to warmer colors until it becomes red when four scores are made.
initializeballs instructs the app where and how to restart the game balls and options.
manage and manage2 manages ball and game behavior following a soccer ball save (or attempted save). manage2 is essentially the same as manage except in one, the directions are for sprite1 and the other is for sprite3. These blocks could be coded as a single procedure managing both sprites, but then the logic is more difficult to discern from looking at the blocks. manageoptions keeps track of the game settings currently in use while playing. optionslist is a list of the Boolean variables use to monitor game settings.
redrawnotices/settarget/soundsources When a Draw block is used on a Canvas, the only way to erase the text is by writing over the text with the text color set to the color of the background image. The redrawnotices procedure does this.
The game has an option to make the soccer balls seek (point to) either the goal sprite (the thin and wide green sprite3) or an x,y point located somewhere randomly along the goal line. Game play is slightly different in each case. settarget manages the way the game plays. soundsources preloads the sound files in the game. Preloading means the files are instantly available for game play. This procedure is placed in the Screen1.Initialize event handler. pausegame and resetgame do what the names say. The pausegame procedure pauses game play, temporarily stops the clock and when pressed again, restarts play. The resetgame procedure sets most game values to their initial state. Screen1.Initialize sets initial game conditions. Two blocks are disabled. Hiding the Status Bar with the ShowStatusBar set to false is an interesting idea, however it hides the Android device s
battery level. If you are not concerned about shutting down unexpectedly during game play, enable the block. As a developer, since nb 144, developers have the option of showing or hiding the Title Bar. Currently, the Title Bar is hidden. The text of the collapsed text block should attached to the ListPicker1 block is as follows: Two Balls,Ball Start Low/High,Balls High & Low,Slower Balls,Faster Balls,Erratic Balls,Change Target,Developer Options,Help,Reset High Score
Special Colors To erase the displays written with the Canvas.DrawText block, you have to establish the colors for the background that is behind the text. How to do this is explained in the section Drawing and Erasing discussed earlier.
Sprite1 a Soccer Ball What to do when a soccer ball is touched and what happens when balls reach the left or right screen edges. There is similar code for Sprite3. Sprite3 another Soccer Ball
Sprite2 the Goal Here is where you instruct the game to respond when (if) the goalie goofs and an opponent s ball scores. The Clocks The app has three clocks. Clocks 1 and 3 run continuously. Clock2 is used at the game start, then turned off. Clock1 continuously updates the screen and is used to cue erratic performance of soccer balls. Clock2 controls the game splash screen. Clock3 runs the game clock while action is in play.
ListPicker1 This is the game options menu.
ListPicker2 This menu selects the team the Player want to represent during game play. Several game activities vary depending on the selections made.
The Designer Screen The Designer contains numerous Vertical and Horizontal layout used to provide several virtual screens and to provide a reasonable screen layout.
Media
Are you through yet? Maybe you are through. Have you considered : 1) adding obstacles (perhaps a yellow card issued after two successive goals within a very short time interval; 2) add another ball, more confusion, more fun? 3) rewards for different levels of saves; 4) partial points for saves made outside of the ringed fence at the goal; 5) a selection of anthems or background sounds; 6) storing game preferences in the TinyDB that are recalled at first run of the app. The TinyDB is already there. Perhaps save the settings as a csv to the database with a tag like gamesettings, then retrieve the values using a csv to list block; at runtime. 7) applying some of the techniques demonstrated in Goal ia2 in your own action game; you do not have to code soccer. 8) Sharing your improvements on the App Inventor Forum Goal ai2 is far from finished; you can add lots of toys. Look at the aia file, the file is still under 1Mb. Add what you will but stay aware the more activities triggered within an event handler (Button.Click, Clock.Timer and others), the more probable some of your intended coding might interfere with other code as the code is executed. AI2 is event driven. Before you create the apk File During development, use the development path to the embedded HTML document used as the Help file. file:///mnt/sdcard/appinventor/assets/soccerhelp.html Prior to compiling the app with the Build menu, use the production path. file:///android_asset/soccerhelp.html A Boolean switch is used to turn on the production path prior to the final compiling of the app. Change the variable that is the last block in the Screen1.Initialize event handler (the appdevelopment variable) from true to false prior to compiling the apk. The aia File The Goal ai2 aia file is a template and also the full app. The app s controls are provided in the template aia. You reproduce the blocks. The download link for Goalai2_template.aia and Goalai2.aia is located on the main blog tutorial page.
Important Facts The tutorial and the Goal ai2 app are copyrighted. Please do not slightly modify this tutorial and claim it as your own or post Goal ai2 on Google Play or on any Web page. Have fun with the app for personal use. Use the algorithms and ideas in your own app and enjoy coding. This tutorial, images within the tutorial and Goal ai2 are Copyright 2015 by SJG. Some of the sound files and images are copyright as indicated in the text and in the app About.