Defining Game Characteristics
A D V E R T I S E M E N T
A game where all you have to do is to move the central character left and
right is not very fun. Let's make some modifications to the game skeleton in
Listing 1 to define this game a little better. To start with, specify a boundary
for your game. It is essential to do this, because it helps to make your game
consistently sized across different devices. To do this, start by defining some
constants that are shown in the code here:
// the game boundary
public static final int GAME_WIDTH = 160;
public static final int GAME_HEIGHT = 160;
// the shifted x,y origin of the game
public final int GAME_ORIGIN_X = (getWidth() - GAME_WIDTH)/2;
public final int GAME_ORIGIN_Y = (getHeight() - GAME_HEIGHT)/2;
// the height of sections below and above the couple
public final int SECTION_HEIGHT = 64;
// the base on which the couple will move
public final int BASE = GAME_ORIGIN_Y + GAME_HEIGHT - SECTION_HEIGHT;
// the max height the couples can jump
public final int MAX_HEIGHT = 32;
(Note that I have introduced a game characteristic that indicates that this
couple may soon be jumping on the screen, with the help of the MAX_HEIGHT
constant.) On the screen, these constants help define the boundary of the game
and its sole element (the couple), as shown in Figure 2.
Figure 2. Defining the game boundaries using the game constants
Of course, now you need to modify the rest of the code to use these
constants. Add a new method to Listing 1 called buildGameScreen(Graphics
g), as shown in code here:
private void buildGameScreen(Graphics g) {
// set the drawing color to black
g.setColor(0x000000);
// draw the surrounding rectangle
g.drawRect(GAME_ORIGIN_X, GAME_ORIGIN_Y, GAME_WIDTH, GAME_HEIGHT);
// draw the base line
g.drawLine(GAME_ORIGIN_X, BASE, GAME_ORIGIN_X + GAME_WIDTH, BASE);
// draw the maximum line to where the couple can jump to
g.drawLine(GAME_ORIGIN_X, BASE - MAX_HEIGHT,
GAME_ORIGIN_X + GAME_WIDTH, BASE - MAX_HEIGHT);
}
Also add a call to this method in the updateGameScreen() method,
before the couple image is drawn. The game boundaries have been defined and the
only thing left to do is to make the starting position for the couple image as
the BASE and not CENTER_Y. Change this in the
start() method by setting coupleY = BASE;.
The couple image can move left and right with the left and right game keys,
but now we ensure that it does not move past the game boundary. This was a
problem in Listing 1, too, but in that case, the image simply vanished off the
screen, as the boundary was the edge of the screen. It will look very odd if the
image went past the boundaries now. Therefore, modify the left and right press
actions in the calculateCoupleX() method to restrict movement
beyond the boundaries. This modified method is listed here:
private void calculateCoupleX(int keyState) {
// determines which way to move and changes the
// x coordinate accordingly
if((keyState & LEFT_PRESSED) != 0) {
coupleX =
Math.max(
GAME_ORIGIN_X + coupleImg.getWidth()/2,
coupleX - dx);
}
else if((keyState & RIGHT_PRESSED) != 0) {
coupleX =
Math.min(
GAME_ORIGIN_X + GAME_WIDTH - coupleImg.getWidth()/2,
coupleX + dx);;
}
}
This method now uses Math.max() and Math.min()
methods to restrict the couple image within the game boundaries. Notice that it
also incorporates the width the of the image in these calculations.
I spoke earlier about making the couple image jump around on the screen.
Let's see how this can be achieved by adding a method to move the image along
the Y axis, independently of the user playing the game.
Add three new instance variables to Listing 1, called up,
jumpHeight, and random, as shown here:
// a flag to indicate which direction the couple are moving
private Boolean up = true;
// indicates the random jump height, calculated for every jump
private int jumpHeight = MAX_HEIGHT;
// random number generator
public Random random = new Random();
As you can see, jumpHeight is initialized to MAX_HEIGHT.
This jumpHeight variable will be calculated for each jump that the
couple make and it will be set to a random value each time. This is shown in the
calculateCoupleY() method shown here:
private void calculateCoupleY(int keyState) {
// check if the couple were on the way up
if(up) {
// if yes, see if they have reached the current jump height
if((coupleY > (BASE - jumpHeight + coupleImg.getHeight()))) {
// if not, continue moving them up
coupleY -= dy;
} else if(coupleY == (BASE - jumpHeight + coupleImg.getHeight())) {
// if yes, start moving them down
coupleY += dy;
// and change the flag
up = false;
}
} else {
// the couple are on their way down, have they reached base?
if(coupleY < BASE) {
// no, so keep moving them down
coupleY += dy;
} else if(coupleY == BASE) {
// have reached base, so calculate a new
// jump height which is not more than MAX_HEIGHT
int hyper = random.nextInt(MAX_HEIGHT + 1);
// but make sure that this it is atleast greater than the image height
if(hyper > coupleImg.getHeight()) jumpHeight = hyper;
// move the image up
coupleY -= dy;
// and reset the flag
up = true;
}
}
}
Note that since this method doesn't depend on the user pressing the up or
down game keys, it has no use for the keyState information. But
this value is passed to it nonetheless, in order to maintain conformity with the
calculateCoupleX() method. This method starts moving the couple
image by changing the coupleY variable in the upwards direction
until it reaches the current jump height (which is the MAX_HEIGHT
at starting). Once it reaches this jump height, it starts moving it in the
opposite direction until it reaches BASE. At this point, a new jump
height value, between the MAX_HEIGHT and couple image heights, is
randomly calculated and the couple start jumping again.
The overall effect is of a randomly jumping couple who can be moved left and
right by the user playing the game. A snapshot is shown in Figure 3.
Figure 3. Game snapshot
|