Learning Java by Building Android  Games
上QQ阅读APP看书,第一时间看更新

Creating a new project

Create a new project in the same way as we did for Sub Hunter but call it Canvas Demo. If you have the Sub Hunter project open now you can select File | New Project and create a project using the following options.

As we did before, be sure the Empty Activity option is selected on the Add an Activity to Mobile screen before clicking Next. Also, be sure to uncheck Generate Layout File and Backwards Compatibility (AppCompat). Don't worry about naming the Activity this is just a mini app to play around with we will not be returning to it.

Note

The complete code for this mini-app can be found in the download bundle in the Chapter 5/Canvas Demo folder.

Coding the Canvas demo app

To get started, add the highlighted code, after the class declaration but before the onCreate method. This is what the code will look like after this step.

public class MainActivity extends Activity {

    // Here are all the objects(instances)
 // of classes that we need to do some drawing
 ImageView myImageView;
 Bitmap myBlankBitmap;
 Canvas myCanvas;
 Paint myPaint;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
}

Notice that each of the four new classes is underlined in red. This is because we need to add the appropriate import statements. You could copy them from the first page of this chapter but much quicker would be to place the mouse pointer on each error in turn then hold the ALT key and tap the Enter key. If prompted, from the pop-up options, select Import class.

Once you have done this for each of ImageView, Bitmap, Canvas, and Paint, all the errors will be gone, and the relevant import statements will have been added to the top of the code.

Now that we have declared instances of the required classes we can initialize them. Add the following code to the onCreate method after the call to super.onCreate… as shown in this next code.

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);

   // Initialize all the objects ready for drawing
   // We will do this inside the onCreate method
   int widthInPixels = 800;
   int heightInPixels = 600;

   // Create a new Bitmap
   myBlankBitmap = Bitmap.createBitmap(widthInPixels,
         heightInPixels,
         Bitmap.Config.ARGB_8888);

   // Initialize the Canvas and associate it
   // with the Bitmap to draw on
   myCanvas = new Canvas(myBlankBitmap);

   // Initialize the ImageView and the Paint
   myImageView = new ImageView(this);
   myPaint = new Paint();
}

This code is the same as we saw when we were discussing Canvas in theory. Even though we are not going any deeper about classes now it might be worth exploring the Bitmap class initialization.

Exploring the Bitmap initialization

Bitmaps, more typically in games are used to represent game objects like the player, backgrounds, bombs, etc. Here we are simply using it to draw upon. In later projects, we will use all sorts of bitmaps to represent everything from spaceships to enemies.

The method that needs explaining is the createBitmap method. The parameters from left to right are:

  • The width (in pixels),
  • The Height (in pixels)
  • The bitmap configuration

Bitmaps can be configured in a number of different ways. The ARGB_8888 configuration means that each pixel is represented by 4 bytes of memory.

Note

There are a number of bitmap formats that Android can use. This one is perfect for a good range of color and will ensure that the bitmaps we use and the color we request will be drawn as intended. There are higher and lower configurations but ARGB_8888 is perfect for the entirety of this book.

Now we can do the actual drawing.

Drawing on the screen

Add this next highlighted code after the initialization of myPaint and inside the closing curly brace of the onCreate method.

   myPaint = new Paint();

   // Draw on the Bitmap
   // Wipe the Bitmap with a blue color
   myCanvas.drawColor(Color.argb(255, 0, 0, 255));

   // Re-size the text
   myPaint.setTextSize(100);
   // Change the paint to white
   myPaint.setColor(Color.argb(255, 255, 255, 255));
   // Draw some text
   myCanvas.drawText("Hello World!",100, 100, myPaint);

   // Change the paint to yellow
   myPaint.setColor(Color.argb(255, 212, 207, 62));
   // Draw a circle
   myCanvas.drawCircle(400, 250, 100, myPaint);
}

The previous code uses myCanvas.drawColor to fill the screen with color.

The myPaint.setTextSize defines the size of the text that will be drawn next. The myPaint.setColor method determines what color any future drawing will be. The myCanvas.drawText actually draws the text to the screen.

Analyze the arguments passed into drawText and we can see that the text will say "Hello World!" and it will be drawn 100 pixels from the left and 100 pixels from the top of our Bitmap (myBitmap).

Next, we use setColor again to change the color that will be used for drawing. Finally, we use the drawCircle method to draw a circle that is at 400 pixels from the left and 100 pixels from the top. The circle will have a radius of 100 pixels.

I reserved explaining the Color.argb method until now.

Explaining Color.argb

The Color class, unsurprisingly helps us manipulate and represent colors. The argb method used previously returns a color constructed using the alpha (opacity/transparency), red, green, blue model. This model uses values ranging from zero(no color) to 255(full color) for each element. It is important to note although on reflection it might seem obvious, the colors mixed are intensities of light and are quite different to what happens when we mix paint for example.

Tip

To devise an argb value and explore this model further take a look at this handy website. https://www.rapidtables.com/web/color/RGB_Color.html. The site helps you pick the RGB values you can then experiment with the alpha values.

The value used to clear the drawing surface was 255, 0, 0, 255. These values mean full opacity (solid color), no red, no green and full blue. This makes a blue color.

The next call to the argb method is in the first call to setColor where we are setting the required color for the text. The values 255, 255, 255, 255 means full opacity, full red, full green, full blue. When you combine light with these values you get white.

The final call to argb is in the final call to setColor when we are setting the color to draw the circle. 255, 21, 207, 62 makes a sun-yellow color.

The last step before we can run the code is to add the call to the setContentView method which places passes our ImageView (myImageView) as the view to be set as the content for this app. Here are the final lines of code highlighted after the code we have already added but before the closing curly brace of onCreate.

// Associate the drawn upon Bitmap with the ImageView
myImageView.setImageBitmap(myBlankBitmap);
// Tell Android to set our drawing
// as the view for this app
// via the ImageView
setContentView(myImageView);

Finally, we tell the Activity class to use myImageView by calling setContentView.

This is what the Canvas demo looks like with the emulator rotated to portrait. We can see an 800 by 800-pixel drawing. In all our games, we will see how we can utilize the entire screen.

Explaining Color.argb

In this example, we just draw to a Bitmap but in the Sub Hunter game, we want to draw to the entire screen, so a discussion of the Android coordinate system will be useful.