- Learning Java by Building Android Games
- John Horton
- 848字
- 2021-07-23 19:02:26
Using for loops to draw the Sub' Hunter grid
By the end of the book we will have used every type of loop but the first one we get to utilize is the for
loop. Can you imagine having to write a line of code to draw each and every line of the grid in Sub' Hunter?
We will delete the existing drawLine…
code in the draw
method and replace it with two for
loops that will draw the entire grid!
Here I show you the entire draw
method just to be sure you can clearly recognize what to delete and what to add. Add the highlighted code shown next.
void draw() { gameView.setImageBitmap(blankBitmap); // Wipe the screen with a white color canvas.drawColor(Color.argb(255, 255, 255, 255)); // Change the paint color to black paint.setColor(Color.argb(255, 0, 0, 0)); // Draw the vertical lines of the grid for(int i = 0; i < gridWidth; i++){ canvas.drawLine(blockSize * i, 0, blockSize * i, numberVerticalPixels, paint); } // Draw the horizontal lines of the grid for(int i = 0; i < gridHeight; i++){ canvas.drawLine(0, blockSize * i, numberHorizontalPixels, blockSize * i, paint); } // Re-size the text appropriate for the // score and distance text paint.setTextSize(blockSize * 2); paint.setColor(Color.argb(255, 0, 0, 255)); canvas.drawText( "Shots Taken: " + shotsTaken + " Distance: " + distanceFromSub, blockSize, blockSize * 1.75f, paint); Log.d("Debugging", "In draw"); printDebuggingText(); }
To explain the code let's focus on the second for
loop. This one:
// Draw the horizontal lines of the grid for(int i = 0; i < gridHeight; i++){ canvas.drawLine(0, blockSize * i, numberHorizontalPixels, blockSize * i, paint); }
This is the code that will draw all the horizontal lines.
Let's break down the second for
loop to understand what is going on. Look at the first line of the second for
loop again.
for(int i = 0; i < gridHeight; i++){
The code declares a new variable named i
and initializes it to 0
.
Then the loop condition is set to i < gridHeight
. This means that all the time that i
is lower than the value that we previously calculated for gridHeight
the code will keep looping.
The third part of the for
loop declaration is i++.
This simply increments i
by 1 each pass through the loop.
If we assume that gridHeight
is 24 as it is on the Google Pixel emulator, then the code in the for
loop's body will execute 24 times going up from 0 through 23. Let's look at the loop body again.
canvas.drawLine(0, blockSize * i, numberHorizontalPixels, blockSize * i, paint);
First, remember that this is all just one line of code. It is the limitations of printing in a book which has spread it over three lines.
The code starts off just the same as when we drew two lines in the previous chapter with canvas.drawLine(
. What makes the code work its magic is the arguments we pass in as coordinates for the line positions.
The starting coordinates are 0, blockSize * i
. This has the effect in the first part of the loop of drawing a line from the top left corner 0,0. Remember that i
starts at 0 so whatever blockSize
is the answer is still 0.
The next two arguments determine where the line will be drawn to. The arguments are numberHorizontalPixels, blockSize * i
. This has the effect of drawing the line to the far right of the screen also at the very top.
For the next pass through the loop, i
is incremented to 1 and the arguments in drawLine
produce different results.
The first two arguments, 0, blockSize * i
end up starting the line on the far left again but this time (because i
is 1) the starting coordinate is blockSize
pixels down the screen. Remember that blockSize
was determined by dividing the screen width in pixels by gridWidth
. The blockSize
variable holds is exactly the number of pixels we need between each line. Therefore, blockSize * i
is exactly the right pixel position on the screen for the line.
The coordinates to draw the line to are determined by numberHorizontalPixels, blockSize * i
. This is exactly opposite the starting coordinate on the far right of the screen.
As i
is incremented each pass through the loop the line moves the exactly correct number of pixels down each time. The process ends when i
is no longer lower than gridHeight
. If it didn't we would end up drawing lines that are not on the screen.
The final argument is paint
and this is just as we had it previously.
The other for
loop (the first one) works in exactly the same way except that the loop condition is i < gridWidth
(instead of gridHeight
) and the lines are drawn vertically from 0
to numberVerticalPixels
(instead of horizontally from 0
to numberHorizontalPixels
).
Study both loops to make sure you understand the details. You can now run the code and see the Sub' Hunter grid in all its glory.
In the previous image, the newly drawn gridlines are overlaid by the debugging text.