MOBILE

Handling Mobile User Input (part 3) - Building the UFO 2 Example

9/3/2012 3:00:42 AM
You’re now going to take the example to another level entirely by adding a means of controlling the UFO with keys on a mobile phone, as well as adding some tumbling asteroids as obstacles for the UFO to dodge. I’d stop short of officially calling the UFO 2 example a game, but it’s about as close as you can get!

The UFO 2 example program involves the following major additions with respect to the original version of the program:

  • User input for controlling the flying saucer

  • Three frame-animated asteroid sprites that float around the screen

  • Collision detection between the flying saucer and the asteroid sprites

You are already well equipped to tackle all these additions, so let’s get to it.

Writing the Program Code

The MIDlet class for the UFO 2 example doesn’t change at all from the previous version, so let’s jump straight into the modified UFOCanvas class. The first change is the addition of three asteroid sprites, which are stored in a Sprite array:

private Sprite[] roidSprite = new Sprite[3];

You initialize these asteroid sprites in the start() method of the MIDlet by using the following code:

Image img = Image.createImage("/Roid.png");
roidSprite[0] = new Sprite(img, 42, 35);
roidSprite[1] = new Sprite(img, 42, 35);
roidSprite[2] = new Sprite(img, 42, 35);

As you can see, the asteroid image (Roid.png) is created only once, and then used as the sprite image for all three asteroid sprites. In addition to creating the three asteroid sprites, the start() method also initializes the position of the flying saucer sprite differently than the original version did:

ufoSprite.setPosition((getWidth() - ufoSprite.getWidth()) / 2,
  (getHeight() - ufoSprite.getHeight()) / 2);

Although it looks a bit messy, this code is simply centering the flying saucer sprite on the screen so that it isn’t initially colliding with the asteroids, which are all three initially located in the upper-left corner of the screen at the default position (0,0).

The update() method is where most of the interesting new code lies in the UFO 2 MIDlet. All the key handling takes place in a single block of code, which looks like this:

Nothing too tricky here! The code simply checks the four directional keys and alters the UFO speed accordingly. Notice that the speed is still capped at a magnitude of 8 regardless of how much you pound on the keys. After altering the speed, the flying saucer is updated with another couple of lines of code:

ufoSprite.move(ufoXSpeed, ufoYSpeed);
checkBounds(ufoSprite);

The familiar sprite move() method is called to move the saucer, whereas the new checkBounds() method is called to perform any screen wrapping. The code in the checkBounds() method isn’t new, but isolating it in a reusable method is. This is important because you need to be able to check the bounds of the UFO and asteroids sprites, and it wouldn’t make much sense to duplicate the code unnecessarily.

The updating of the asteroid sprites takes place in a loop that takes care of several different tasks. Here’s how the loop starts:

for (int i = 0; i < 3; i++) {

The first task within the loop is to move the asteroids and check their bounds in case they need to be wrapped around the screen:

  roidSprite[i].move(i + 1, 1 - i);
  checkBounds(roidSprite[i]);

The only tricky code here is the amount by which the asteroids are moved. To help give the asteroids their own unique speeds, the index of each asteroid is used as the basis for determining how fast it moves and in what direction. A similar approach is used to vary the animation frame directions of the asteroids, as this code reveals:

  if (i == 1)
    roidSprite[i].prevFrame();
  else
    roidSprite[i].nextFrame();

The idea behind this code is for the second asteroid to spin in an opposite direction as the first and third asteroids. You can accomplish this easily by moving the animation frames of the second sprite in the opposite direction as the others.

The remaining code in the asteroid update loop has to do with detecting a collision between the flying saucer and any of the asteroids:

If a collision has indeed occurred, the AlertType object is used to play a standard error sound, which is determined by each individual phone. A collision in this program triggers a reset of the sprite positions, as is evident in the code. If this were a full-blown game, this is where you would decrement the number of lives and check to see whether the game is over. In this case, you just reposition the sprites and let the animation keep on trucking.

There is only a minor change to the draw() method in this version of the UFO example MIDlet. I’m referring to the code that draws the asteroids, which looks like this:

for (int i = 0; i < 3; i++)
  roidSprite[i].paint(g);

That wraps up the new chunks of code in the UFO 2 example. Listing 1 contains the complete code for the new UFOCanvas class, which helps add some context to the code you just learned about.

Listing 1. The UFOCanvas Class Serves as a Customized Canvas for the UFO 2 MIDlet

You’ve already learned the ins and outs of this code, so I’ll spare you more discussion. Let’s see how it actually runs instead!

Testing the Finished Product

Testing the UFO 2 example MIDlet is considerably more interesting and entertaining than previous examples because you now get to use keys to control an animated graphical object (flying saucer). Figure 1 shows the UFO 2 MIDlet in all its glory as I carefully steer it around those pesky asteroids in the J2ME emulator.

Figure 1. The UFO 2 example MIDlet allows you to control a flying saucer and dodge asteroids by using mobile phone keys.


It’s not too hard to see the beginnings of an Asteroids-type game in this example. Take some time to play around with it and pay particularly close attention to how it handles collision detection. It’s very apparent how using image data collision detection results in a great deal of accuracy, which translates into a flying saucer you can deftly guide between asteroids even when there is little room to spare.

Other  
  •  My ipad : Presentations with Keynote - Playing Your Presentation, Using the VGA Adapter
  •  My ipad : Presentations with Keynote - Organizing Slides
  •  Three-resistance Xperia Go
  •  Galaxy Tab 2's 7-Inch Tiny Version
  •  Samsung Galaxy Note II
  •  Philips W632 ICS Smartphone
  •  One-week Experience With LG Optimus L7
  •  Nexus 7 – Benchmark Score
  •  Lumia 800 And 710 Are Updated To 7.5
  •  Gold-Plated Lamborghini TL700 : Simplicity Is Stylish
  •  Google Nexus 7 Tablet Review
  •  jQuery 1.3 : Selectors - DOM traversal methods, Accessing DOM elements
  •  jQuery 1.3 : Selectors - Custom selectors
  •  jQuery 1.3 : Selectors - Attribute selectors
  •  jQuery 1.3 : Selectors - The Document Object Model, CSS selectors
  •  Tablets Comparison (Part 3) - Cloud Storage - Google Drive, iCloud, Skydrive
  •  Tablets Comparison (Part 2) - Tablets – OS - Android 4.1 Jelly Bean, Apple iOS 6, Windows 8 RT
  •  Tablets Comparison (Part 1) - Google Nexus 7, Apple iPad, Microsoft surface
  •  Smartphones of The Month - August 2012
  •  Cook Gives No Grist To Rumour Mill
  •  
    Top 10
    A Look At Truecrypt The Open Source Security Tool
    Price Of Piracy
    Acer Aspire 5600U 23" Touchscreen All-in-One PC
    Zalman FX100-Cube Fanless Cooler
    Devolo dLAN LiveCam Starter Kit
    Has Apple Lost It? (Part 2)
    Has Apple Lost It? (Part 1)
    Sony Computer Entertainment (Part 3)
    Sony Computer Entertainment (Part 2)
    Sony Computer Entertainment (Part 1)
    Most View
    Audioquest Dragonfly – USB DAC/Headphone AMP
    Choosing The Right Parts For Your Build (Part 4) - Picking the right PSU
    All About Battery Life (Part 3)
    Finding Software Bargains
    Upgrading to SQL Server 2008
    Audeze LCD-2 Headphones At Music Direct (Part 2)
    Troubleshooting Guide - Internet Connection Problems
    Microsoft Dynamics AX 2009 : Building Lookups - Creating a lookup dynamically
    Windows 7 : Configuring Network Connectivity - Configuring DirectAccess
    Active Directory Domain Services 2008 : Filter Group Policy Object Scope by Using Security Groups, Disable User Settings in a Group Policy Object, Disable Computer Settings in a Group Policy Object
    BlackBerry Bold 9700 and 9650 Series : Searching for Lost Stuff
    Company Profiles: Twitter
    How To Choose An External Drive (Part 2)
    SQL Server 2005 : Advanced OLAP - Translations
    Canon EOS M With Wonderful Touchscreen Interface (Part 2)
    SQL Server 2008 : Demystifying Data Types - Computed Columns
    Ultrabook Supertest (Part 4) - Dell Inspiron 14z
    The SQL Server 2008 Configuration Manager
    Scan 3XS Sniper FT03 Nanu - Compact Gaming Systems
    Why Apple Wins? (Part 2)