package net.frog_parrot.jump;
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
/**
* This class represents the player.
*
* @author Carol Hamer
*/
public class Cowboy extends Sprite {
//---------------------------------------------------------
// Dimension fields
/**
* The width of the cowboy's bounding rectangle.
*/
static final int WIDTH = 32;
/**
* The height of the cowboy's bounding rectangle.
*/
static final int HEIGHT = 48;
/**
* This is the order that the frames should be displayed
* for the animation.
*/
static final int[] FRAME_SEQUENCE = { 3, 2, 1, 2 };
//---------------------------------------------------------
// Instance fields
/**
* The X coordinate of the cowboy where the cowboy starts
* the game.
*/
private int myInitialX;
/**
* The Y coordinate of the cowboy when not jumping.
*/
private int myInitialY;
/**
* The jump index that indicates that no jump is
* currently in progress.
*/
private int myNoJumpInt = -6;
/**
* Where the cowboy is in the jump sequence.
*/
private int myIsJumping = myNoJumpInt;
/**
* If the cowboy is currently jumping, this keeps track
* of how many points have been scored so far during
* the jump. This helps the calculation of bonus points since
* the points being scored depend on how many tumbleweeds
* are jumped in a single jump.
*/
private int myScoreThisJump = 0;
//---------------------------------------------------------
// Initialization
/**
* Constructor initializes the image and animation.
*/
public Cowboy(int initialX, int initialY) throws Exception {
super(Image.createImage("/images/cowboy.png"), WIDTH, HEIGHT);
myInitialX = initialX;
myInitialY = initialY;
// You define the reference pixel to be in the middle
// of the cowboy image so that when the cowboy turns
// from right to left (and vice versa) he does not
// appear to move to a different location.
defineReferencePixel(WIDTH/2, 0);
setRefPixelPosition(myInitialX, myInitialY);
setFrameSequence(FRAME_SEQUENCE);
}
//---------------------------------------------------------
// Game methods
/**
* If the cowboy has landed on a tumbleweed, you decrease
* the score.
*/
int checkCollision(Tumbleweed tumbleweed) {
int retVal = 0;
if(collidesWith(tumbleweed, true)) {
retVal = 1;
// Once the cowboy has collided with the tumbleweed,
// that tumbleweed is done for now, so you call reset,
// which makes it invisible and ready to be reused.
tumbleweed.reset();
}
return(retVal);
}
/**
* Set the cowboy back to its initial position.
*/
void reset() {
myIsJumping = myNoJumpInt;
setRefPixelPosition(myInitialX, myInitialY);
setFrameSequence(FRAME_SEQUENCE);
myScoreThisJump = 0;
// At first the cowboy faces right:
setTransform(TRANS_NONE);
}
//---------------------------------------------------------
// Graphics
/**
* Alter the cowboy image appropriately for this frame.
*/
void advance(int tickCount, boolean left) {
if(left) {
// Use the mirror image of the cowboy graphic when
// the cowboy is going toward the left.
setTransform(TRANS_MIRROR);
move(-1, 0);
} else {
// Use the (normal, untransformed) image of the cowboy
// graphic when the cowboy is going toward the right.
setTransform(TRANS_NONE);
move(1, 0);
}
// This section advances the animation:
// Every third time through the loop, the cowboy
// image is changed to the next image in the walking
// animation sequence:
if(tickCount % 3 == 0) { // Slow the animation down a little.
if(myIsJumping == myNoJumpInt) {
// If he's not jumping, set the image to the next
// frame in the walking animation:
nextFrame();
} else {
// If he's jumping, advance the jump:
// The jump continues for several passes through
// the main game loop, and myIsJumping keeps track
// of where you are in the jump:
myIsJumping++;
if(myIsJumping < 0) {
// myIsJumping starts negative, and while it's
// still negative, the cowboy is going up.
// Here you use a shift to make the cowboy go up a
// lot in the beginning of the jump and ascend
// more and more slowly as he reaches his highest
// position:
setRefPixelPosition(getRefPixelX(),
getRefPixelY() - (2<<(-myIsJumping)));
} else {
// Once myIsJumping is negative, the cowboy starts
// going back down until he reaches the end of the
// jump sequence:
if(myIsJumping != -myNoJumpInt - 1) {
setRefPixelPosition(getRefPixelX(),
getRefPixelY() + (2<<myIsJumping));
} else {
// Once the jump is done, you reset the cowboy to
// his nonjumping position:
myIsJumping = myNoJumpInt;
setRefPixelPosition(getRefPixelX(), myInitialY);
// You set the image back to being the walking
// animation sequence rather than the jumping image:
setFrameSequence(FRAME_SEQUENCE);
// myScoreThisJump keeps track of how many points
// were scored during the current jump (to keep
// track of the bonus points earned for jumping
// multiple tumbleweeds). Once the current jump is done,
// you set it back to zero.
myScoreThisJump = 0;
}
}
}
}
}
/**
* Makes the cowboy jump.
*/
void jump() {
if(myIsJumping == myNoJumpInt) {
myIsJumping++;
// Switch the cowboy to use the jumping image
// rather than the walking animation images:
setFrameSequence(null);
setFrame(0);
}
}
/**
* This is called whenever the cowboy clears a tumbleweed
* so that more points are scored when more tumbleweeds
* are cleared in a single jump.
*/
int increaseScoreThisJump() {
if(myScoreThisJump == 0) {
myScoreThisJump++;
} else {
myScoreThisJump *= 2;
}
return(myScoreThisJump);
}
}
Listing 6. Tumbleweed.java
package net.frog_parrot.jump;
import java.util.Random;
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
/**
* This class represents the tumbleweeds that the player
* must jump over.
*
* @author Carol Hamer
*/
public class Tumbleweed extends Sprite {
//---------------------------------------------------------
// Dimension fields
/**
* The width of the tumbleweed's bounding square.
*/
static final int WIDTH = 16;
//---------------------------------------------------------
// Instance fields
/**
* Random number generator to randomly decide when to appear.
*/
private Random myRandom = new Random();
/**
* Whether this tumbleweed has been jumped over.
* This is used to calculate the score.
*/
private boolean myJumpedOver;
/**
* Whether this tumbleweed enters from the left.
*/
private boolean myLeft;
/**
* The Y coordinate of the tumbleweed.
*/
private int myY;
//---------------------------------------------------------
// Initialization
/**
* Constructor initializes the image and animation.
* @param left Whether this tumbleweed enters from the left.
*/
public Tumbleweed(boolean left) throws Exception {
super(Image.createImage("/images/tumbleweed.png"), WIDTH, WIDTH);
myY = JumpManager.DISP_HEIGHT - WIDTH - 2;
myLeft = left;
if(!myLeft) {
setTransform(TRANS_MIRROR);
}
myJumpedOver = false;
setVisible(false);
}
//---------------------------------------------------------
// Graphics
/**
* Move the tumbleweed back to its initial (inactive) state.
*/
void reset() {
setVisible(false);
myJumpedOver = false;
}
/**
* Alter the tumbleweed image appropriately for this frame.
* @param left Whether the player is moving left
* @return How much the score should change by after this
* advance.
*/
int advance(Cowboy cowboy, int tickCount, boolean left,
int currentLeftBound, int currentRightBound) {
int retVal = 0;
// If the tumbleweed goes outside of the display
// region, set it to invisible since it is
// no longer in use.
if((getRefPixelX() + WIDTH <= currentLeftBound) ||
(getRefPixelX() - WIDTH >= currentRightBound)) {
setVisible(false);
}
// If the tumbleweed is no longer in use (i.e., invisible)
// it is given a 1 in 100 chance (per game loop)
// of coming back into play:
if(!isVisible()) {
int rand = getRandomInt(100);
if(rand == 3) {
// When the tumbleweed comes back into play,
// you reset the values to what they should
// be in the active state:
myJumpedOver = false;
setVisible(true);
// Set the tumbleweed's position to the point
// where it just barely appears on the screen
// so that it can start approaching the cowboy:
if(myLeft) {
setRefPixelPosition(currentRightBound, myY);
move(-1, 0);
} else {
setRefPixelPosition(currentLeftBound, myY);
move(1, 0);
}
}
} else {
// When the tumbleweed is active, you advance the
// rolling animation to the next frame and then
// move the tumbleweed in the right direction across
// the screen.
if(tickCount % 2 == 0) {
// Slow the animation down a little. nextFrame();
}
if(myLeft) {
move(-3, 0);
// If the cowboy just passed the tumbleweed
// (without colliding with it), you increase the
// cowboy's score and set myJumpedOver to true
// so that no further points will be awarded
// for this tumbleweed until it goes off the screen
// and then is later reactivated:
if((! myJumpedOver) && (getRefPixelX() < cowboy.getRefPixelX())) {
myJumpedOver = true;
retVal = cowboy.increaseScoreThisJump();
}
} else {
move(3, 0);
if((! myJumpedOver) && (getRefPixelX() >
cowboy.getRefPixelX() + Cowboy.WIDTH)) {
myJumpedOver = true;
retVal = cowboy.increaseScoreThisJump();
}
}
}
return(retVal);
}
/**
* Gets a random int between
* zero and the param upper.
*/
public int getRandomInt(int upper) {
int retVal = myRandom.nextInt() % upper;
if(retVal < 0) {
retVal += upper;
}
return(retVal);
}
}