Professional Documents
Culture Documents
Takeaway: In the first installment of his five-part app developer series, William J.
Francis creates a drawing surface and a framework for controlling and updating the
contents of an Android game.
In Google Play, 23 of the top 25 grossing applications for Android phones and tablets are
games (at the time of this writing). So it only makes sense that if you are in or are
thinking about getting into the mobile space that you might consider trying your hand
at writing entertainment software.
Even for an experienced software engineer, coding a game can be a little daunting. Its
not that writing games is more difficult than developing other types of applications, its
just different. Game programming has its own techniques, paradigms, and vocabulary
youll hear game developers talking about sprites, frame-rates, world-coordinates, and
pixel-perfect collision detection.
Last year, when along with my son I wrote my first game, I found myself combing the
Internet and forums for simple tutorials that covered the basics. There is an
overwhelming amount of information out there, but game programming is often specific
to a platform and/or tool. I decided to write a series for TechRepublic readers that
introduces the key concepts of coding games on the Android platform, and results in a
nearly complete game that demonstrates the techniques discussed.
This is the first post in this five-part series. The source code in each installment will
build upon that of the previous post. You will be able to follow along with each tutorial
or download the project and import it directly into Eclipse. As with learning anything
new, we must walk before we can fly. Therefore, while the code at the end of part one of
this tutorial will execute, it wont be terribly entertaining. Never fear, it will get there. In
the meantime, below is a sneak peek of the completed game.
Figure A
This is a screen shot of our finished game. The goal is to adjust the saucers momentum in
order to avoid getting smashed to bits by the asteroid. While simplistic, the project
incorporates all the essential aspects of a video game: a canvas, sprites, animation, collision
detection, and user input.
If you havent done any Android programming, that is okay too. There are lots of tools
available for writing mobile games, and in a later post, I will discuss some of the
alternatives. My main reasons for choosing Androids canvas and the standard SDK are
two-fold. First, the techniques are not so complicated as to scare away a novice. (While
OPENGL is more performant, just getting something to appear on the screen is often
enough to crush a budding game developers soul.) Second, all of the tools are free and
can be downloaded and set up under Mac OS, Linux, and Microsoft Windows. I am a big
fan of Corona SDK and Unity, but both cost money to get started and only run under
certain operating systems.
If this is your first time reading TechRepublics Android App Builder blog, we have a
newbies guide to Android development. Youll also want to take a look at Googles
official documentation for installing and setting up your development environment.
</application>
</manifest>
3. Define the layout for our application. In the /res/layout folder, locate main.xml. For
the most part, if youve done any Android programming, you should recognize the
layout components. I created a standard linear layout using common Android UI widgets
with one exception. Note that the very last element in the layout is defined as a
GameBoard; this is our own custom view and the heart of drawing our game to the
screen. For now, you should make sure if you didnt use the same package name that I
did (com.authorwjf.drawing) that you point it to your package.
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|center"
android:text="Reset" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/the_label" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Last Collision XY (?,?)"
android:id="@+id/the_other_label" />
<com.authorwjf.drawing.GameBoard
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin= "20dip"
android:id="@+id/the_canvas"/>
</LinearLayout>
4. Move to our /src directory and create a new .drawing package. In my case, the
package is com.authorwjf.drawing. Within this package add a new class file and call it
GameBoard.java; this new class file will handle all the drawing to our canvas. In its first
incarnation, GameBoard.java simply paints a black background and populates a star
field with random pulsing stars.
GameBoard.java
package com.authorwjf.drawing;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.View;
public class GameBoard extends View{
private Paint p;
private List<Point> starField = null;
private int starAlpha = 80;
private int starFade = 2;
private static final int NUM_OF_STARS = 25;
synchronized public void resetStarField() {
starField = null;
}
5. Modify the /src/Main.java file. The Main class file is charged with updating the
coordinates of any user objects that will get drawn to the screen by the GameBoard
class, handling user input, and the frame rate. By periodically posting an invalidate to
the canvas, Main.java forces the canvas to redraw its contents to reflect any updates in
the action. Think of Main.java as the brains behind our game.
Main.java
package com.authorwjf.gamedevtut;
import com.authorwjf.drawing.GameBoard;
import com.authorwjf.gamedevtut.R;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
((GameBoard)findViewById(R.id.the_canvas)).resetStarField();
((Button)findViewById(R.id.the_button)).setEnabled(true);
//It's a good idea to remove any existing callbacks to keep
//them from inadvertently stacking up.
frame.removeCallbacks(frameUpdate);
frame.postDelayed(frameUpdate, FRAME_RATE);
}
@Override
synchronized public void onClick(View v) {
initGfx();
}
private Runnable frameUpdate = new Runnable() {
@Override
synchronized public void run() {
frame.removeCallbacks(frameUpdate);
//make any updates to on screen objects here
//then invoke the on draw by invalidating the canvas
((GameBoard)findViewById(R.id. the_canvas)).invalidate();
frame.postDelayed(frameUpdate, FRAME_RATE);
}
};
}