Creating the Game Loop

As all game programmers will tell you, most games, at their core, consist of a constant loop. The loop checks for user input and, based on that input and any other game actions, will then draw the new frame/frames to the screen. The loop in your sample application will not win any awards for complexity or ingenuity, but it will get your started on your own game-rendering loop.

Note If you want to implement your own animation loop outside the view/viewGroup hierarchy, look into building a loop with the SurfaceView object. You can find documentation for this object at

http://code.google.com/android/reference/android/view/Surf aceView.html.

Loading Audio and Images

Before you get into drawing the CustomView, you'll need to load a few resources on initialization that will be used later. Code Listing 3-9 shows the new constructor for CustomView including local class variable declarations.

Code Listing 3-9. Initializing the CustomView protected class CustomView extends View {

Context ctx;

Paint lPaint = new Paint(); int x_1=0,y_1=0; MediaPlayer player = null; Bitmap ball = null; boolean running = true;

CustomView(Context c) {

player = MediaPlayer.create(c, R.raw.bounce); BitmapDrawable d = (BitmapDrawable) getResources().getDrawable(R.drawable.theball); ball = d.getBitmap(); ctx = c;

In the constructor, you're loading the bounce media resource from its /res/raw location through the R.java constants file. Because you've done this before with several other resource types, you should be an old hand at it. You also need to load in an image that will be drawn as the "ball." You do this using the resources manager object, which is retrieved from the Context object. Although you haven't explicitly loaded an image in code from a resource location before, it should look like almost any other resource load.

Implementing the Loop, Implementing the Loop, Implementing the...

Without further ado, Code Listing 3-10 shows what the CustomView object's onDraw method looks like.

Code Listing 3-10. The Core of the Animation Loop public void onDraw(Canvas canvas) {

//Draw the white background Rect rct = new Rect(); rct.set(0, 0, canvas.getBitmapWidth(), canvas.getBitmapHeight()); Paint pnt = new Paint(); pnt.setStyle(Paint.Style.FILL); pnt.setColor(Color.WHITE); canvas.drawRect(rct, pnt);

//Increment the X and Y value for the sprites x_1+=2;

//Reset the loop when the balls drift offscreen.

drawSprint(canvas.getBitmapWidth() - x1, y1, canvas);

if(running)

invalidate();

Starting from the top, you'll first white out the background using a paint-style object and a call to canvas.drawRect. The paint object, in combination with the Rectangle object, will tell the canvas to draw a white box that covers the entire screen. Next, you'll increment the x and y values for your ball sprites. You'll then need to reset them if they've drifted past the bounds of the screen and, finally, draw them with your own drawSprite call. Code Listing 3-11 shows the contents of that function.

Code Listing 3-11. Drawing a Bitmap protected void drawSprint(int x, int y, Canvas canvas) {

canvas.drawBitmap(ball, x, y, lPaint);

This function, right now, is simply a straightforward call to the drawBitmap method. I've separated out this method only because drawing the sprite in another context might require more functionality than in this simple example. Finally, returning to the onDraw function, you'll call invalidate only if your running flag is true. Calling invalidate on a view is Android's preferred way of forcing a redraw. In this case, you'll invalidate yourself, which will call onDraw, and the whole process starts over once again. If you simply set the running flag to false on pause or exit and invalidate it again when resuming, the animation should stay in step with the focus of its parent activity.

Adding and Controlling Sound

Since the auditory illusion requires the ability to turn on and off the sound of the two objects bouncing off each other, you'll need to set up the audio to play as they hit and then build a mechanism for the user to turn that audio on and off.

To play the audio, add the code in Code Listing 3-12 to the previous onDraw function since it is also, in effect, the game control loop. When I say "game loop," I'm referring to the invalidate call at the end of onDraw, which will place a redraw in Android's UI event loop. Keep in mind that playSound is a boolean declared just inside the custom view.

Code Listing 3-12. Playing and Reloading Audio if(playSound &&

canvas.getBitmapWidth() - x1 -16 == x1 + 16) player.start();

player.stop(); player.release();

player = MediaPlayer.create(ctx, R.raw.bounce);

As you might have noticed, you're starting the audio playback when the sprites are 16 pixels away from each other. This is a little slush time to let the audio get started. I should note that it speaks more to my inability to edit audio files than it does to a lack of efficiency in audio load and playback times in Android. You also must be sure to play the audio only if the playSound boolean is true. This variable is a member of the Activity class in which the custom view is defined. Using this boolean, you'll get control over the custom view class from within the screen activity. To turn on and off the audio, you now simply implement the method in Code Listing 3-13 in the activity.

Code Listing 3-13. Reacting to Key Events public boolean onKeyDown(int key, KeyEvent kc) {

if(key == KeyEvent. KEYCODE_DPAD_CENTER) {

playSound = !playSound; return true;

return super.onKeyDown(key, kc);

This code should look similar to how you dismissed the prank application in Chapter 2.

0 0

Post a comment