The method drawGameElements
(Fig. 6.15) draws the cannon, cannonball, blocker and target on the SurfaceView
using the Canvas
that the CannonThread
(Section 6.8.14) obtains from the SurfaceView
’s SurfaceHolder
.
359 // draws the game to the given Canvas
360 public void drawGameElements(Canvas canvas)
361 {
362 // clear the background
363 canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(),
364 backgroundPaint);
365
366 // display time remaining
367 canvas.drawText(getResources().getString(
368 R.string.time_remaining_format, timeLeft), 30, 50, textPaint);
369
370 // if a cannonball is currently on the screen, draw it
371 if (cannonballOnScreen)
372 canvas.drawCircle(cannonball.x, cannonball.y, cannonballRadius,
373 cannonballPaint);
374
375 // draw the cannon barrel
376 canvas.drawLine(0, screenHeight / 2, barrelEnd.x, barrelEnd.y,
377 cannonPaint);
378
379 // draw the cannon base
380 canvas.drawCircle(0, (int) screenHeight / 2,
381 (int ) cannonBaseRadius, cannonPaint);
382
383 // draw the blocker
384 canvas.drawLine(blocker.start.x, blocker.start.y, blocker.end.x,
385 blocker.end.y, blockerPaint);
386
387 Point currentPoint = new Point(); // start of current target section
388
389 // initialize currentPoint to the starting point of the target
390 currentPoint.x = target.start.x;
391 currentPoint.y = target.start.y;
392
393 // draw the target
394 for (int i = 0; i < TARGET_PIECES; i++)
395 {
396 // if this target piece is not hit, draw it
397 if (!hitStates[i])
398 {
399 // alternate coloring the pieces
400 if (i % 2 != 0)
401 targetPaint.setColor(Color.BLUE);
402 else
403 targetPaint.setColor(Color.YELLOW );
404
405 canvas.drawLine(currentPoint.x, currentPoint.y, target.end.x,
406 (int) (currentPoint.y + pieceLength), targetPaint);
407 }
408
409 // move currentPoint to the start of the next piece
410 currentPoint.y += pieceLength;
411 }
412 } // end method drawGameElements
413
First, we call Canvas
’s drawRect method (lines 363–364) to clear the Canvas
so that all the game elements can be displayed in their new positions. The method receives as arguments the rectangle’s upper-left x-y coordinates, the rectangle’s width and height, and the Paint
object that specifies the drawing characteristics—recall that backgroundPaint
sets the drawing color to white.
Next, we call Canvas
’s drawText method (lines 367–368) to display the time remaining in the game. We pass as arguments the String
to be displayed, the x- and y-coordinates at which to display it and the textPaint
(configured in lines 170–171) to describe how the text should be rendered (that is, the text’s font size, color and other attributes).
If the cannonball is on the screen, lines 372–373 use Canvas
’s drawCircle method to draw the cannonball in its current position. The first two arguments represent the coordinates of the circle’s center. The third argument is the circle’s radius. The last argument is the Paint
object specifying the circle’s drawing characteristics.
We use Canvas
’s drawLine method to display the cannon barrel (lines 376–377), the blocker (lines 384–385) and the target pieces (lines 405–406). This method receives five parameters—the first four represent the x-y coordinates of the line’s start and end, and the last is the Paint
object specifying the line’s characteristics, such as its thickness.
Lines 380–381 use Canvas
’s drawCircle
method to draw the cannon’s half-circle base by drawing a circle that’s centered at the left edge of the screen—because a circle is displayed based on its center point, half of this circle is drawn off the left side of the SurfaceView
.
Lines 390–411 draw the target sections. We iterate through the sections, drawing each in the correct color—blue for the odd-numbered pieces and yellow for the others. Only those sections that haven’t been hit are displayed.