Minggu, 21 Juni 2009

Senin, Juni 21, 2009

ChickenWarrior : An epic game development in JavaME using Gnu/Linux and NetBeans Mobility Pack

Today, I am releasing the beta version of my new game, ChickenWarrior. This game is in J2ME, intented for the Mobile Phone users. I have tested this game in Motorolla MotoRokr, Sony Ericsson K700i and Sony Ericsson K300i and it works fairly well Cool

The theme of this game is a chicken desperate to save it's eggs falling from the sky at night. Ten eggs will fall from the Sky and the chicken will have to save it .

The NetBeans IDE 6.0 with Mobility pack was used to create this game. The Game Designing part of Mobility pack helps us to easily create the Sprite objects , TiledLayer objects and other game objects which is very complex to code otherwise.

For game play, we can use the left and right keys to move the chicken left and right. The up key will terminate the game if we wish to terminate the game in the middle.


Source Code :
1) ChickenWarrior.java

/**
* @author Maxin B. John
*
*/

package com;

import java.io.IOException;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.media.*;

/**
* @author maxin.john
*/
public class ChickenWarrior extends MIDlet implements CommandListener {

private boolean midletPaused = false;
private Player player ;
private Display d;
////GEN-BEGIN:|fields|0|
private Command exitCommand;
private Command playCommand;
private Form form;
private StringItem stringItem;
//
//GEN-END:|fields|0|

/**
* The HelloMIDlet constructor.
*/
public ChickenWarrior() {

}

////GEN-BEGIN:|methods|0|
//
//GEN-END:|methods|0|

////GEN-BEGIN:|0-initialize|0|0-preInitialize
/**
* Initilizes the application.
* It is called only once when the MIDlet is started. The method is called before the startMIDlet method.
*/
private void initialize() {//GEN-END:|0-initialize|0|0-preInitialize
// write pre-initialize user code here
//GEN-LINE:|0-initialize|1|0-postInitialize
// write post-initialize user code here
}//GEN-BEGIN:|0-initialize|2|
//
//GEN-END:|0-initialize|2|

////GEN-BEGIN:|3-startMIDlet|0|3-preAction
/**
* Performs an action assigned to the Mobile Device - MIDlet Started point.
*/
public void startMIDlet() {

switchDisplayable(null, getForm());
// show();
}

void show() {

System.out.println("Midlet running \n");
MyGameCanvas dgn = new MyGameCanvas();
dgn.mid= this;
new Thread(dgn).start();
d = Display.getDisplay(this);
d.setCurrent(dgn);

}

////GEN-BEGIN:|4-resumeMIDlet|0|4-preAction
/**
* Performs an action assigned to the Mobile Device - MIDlet Resumed point.
*/
public void resumeMIDlet() {

}

////GEN-BEGIN:|5-switchDisplayable|0|5-preSwitch
/**
* Switches a current displayable in a display. The display instance is taken from getDisplay method. This method is used by all actions in the design for switching displayable.
* @param alert the Alert which is temporarily set to the display; if null, then nextDisplayable is set immediately
* @param nextDisplayable the Displayable to be set
*/
public void switchDisplayable(Alert alert, Displayable nextDisplayable) {//GEN-END:|5-switchDisplayable|0|5-preSwitch
// write pre-switch user code here
Display display = getDisplay();//GEN-BEGIN:|5-switchDisplayable|1|5-postSwitch
if (alert == null) {
display.setCurrent(nextDisplayable);
} else {
display.setCurrent(alert, nextDisplayable);
}//GEN-END:|5-switchDisplayable|1|5-postSwitch
// write post-switch user code here
}

////GEN-BEGIN:|7-commandAction|0|7-preCommandAction
/**
* Called by a system to indicated that a command has been invoked on a particular displayable.
* @param command the Command that was invoked
* @param displayable the Displayable where the command was invoked
*/
public void commandAction(Command command, Displayable displayable) {//GEN-END:|7-commandAction|0|7-preCommandAction
// write pre-action user code here
if (displayable == form) {//GEN-BEGIN:|7-commandAction|1|19-preAction
if (command == exitCommand) {//GEN-END:|7-commandAction|1|19-preAction
// write pre-action user code here
exitMIDlet();//GEN-LINE:|7-commandAction|2|19-postAction
// write post-action user code here
}//GEN-BEGIN:|7-commandAction|3|7-postCommandAction
if (command == playCommand) {//GEN-END:|7-commandAction|1|19-preAction
// write pre-action user code here
show();//GEN-LINE:|7-commandAction|2|19-postAction
// write post-action user code here
}//GE
}//GEN-END:|7-commandAction|3|7-postCommandAction
// write post-action user code here
}//GEN-BEGIN:|7-commandAction|4|
//
//GEN-END:|7-commandAction|4|

////GEN-BEGIN:|18-getter|0|18-preInit
/**
* Returns an initiliazed instance of exitCommand component.
* @return the initialized component instance
*/
public Command getExitCommand() {
if (exitCommand == null) {//GEN-END:|18-getter|0|18-preInit
// write pre-init user code here
exitCommand = new Command("Exit", Command.EXIT, 0);//GEN-LINE:|18-getter|1|18-postInit
// write post-init user code here
}//GEN-BEGIN:|18-getter|2|
return exitCommand;
}


public Command getPlayCommand() {
if (playCommand == null) {//GEN-END:|18-getter|0|18-preInit
// write pre-init user code here
playCommand = new Command("Play", Command.OK, 0);//GEN-LINE:|18-getter|1|18-postInit
// write post-init user code here
}//GEN-BEGIN:|18-getter|2|
return playCommand;
}

//
//GEN-END:|18-getter|2|

////GEN-BEGIN:|14-getter|0|14-preInit
/**
* Returns an initiliazed instance of form component.
* @return the initialized component instance
*/
public Form getForm() {
if (form == null) {//GEN-END:|14-getter|0|14-preInit
// write pre-init user code here
form = new Form(" Save the Eggs! ", new Item[] { getStringItem() });//GEN-BEGIN:|14-getter|1|14-postInit
form.addCommand(getExitCommand());
form.addCommand(getPlayCommand());
form.setCommandListener(this);//GEN-END:|14-getter|1|14-postInit
// write post-init user code here
}//GEN-BEGIN:|14-getter|2|
return form;
}
//
//GEN-END:|14-getter|2|

////GEN-BEGIN:|16-getter|0|16-preInit
/**
* Returns an initiliazed instance of stringItem component.
* @return the initialized component instance
*/
public StringItem getStringItem() {
if (stringItem == null) {//GEN-END:|16-getter|0|16-preInit
// write pre-init user code here
stringItem = new StringItem("A Chicken Desperate to save it's eggs..", "");//GEN-LINE:|16-getter|1|16-postInit
// write post-init user code here
}//GEN-BEGIN:|16-getter|2|
return stringItem;
}

/**
* Returns a display instance.
* @return the display instance.
*/
public Display getDisplay () {
return Display.getDisplay(this);
}

/**
* Exits MIDlet.
*/
public void exitMIDlet() {
switchDisplayable (null, null);
destroyApp(true);
notifyDestroyed();
}

/**
* Called when MIDlet is started.
* Checks whether the MIDlet have been already started and initialize/starts or resumes the MIDlet.
*/
public void startApp() {
if (midletPaused) {
resumeMIDlet ();
} else {
initialize ();
// startMIDlet ();
try{
player = Manager.createPlayer(getClass().getResourceAsStream("/Arcade.mid"), "audio/midi");
player.setLoopCount(-1);
player.start();
}catch(MediaException me)
{
}catch(java.io.IOException e)
{

}
System.out.println("Before start midlet\n");
startMIDlet ();
}
midletPaused = false;
}

/**
* Called when MIDlet is paused.
*/
public void pauseApp() {
midletPaused = true;
try{
player.stop();
}catch (MediaException me){
}

}

/**
* Called to signal the MIDlet to terminate.
* @param unconditional if true, then the MIDlet has to be unconditionally terminated and all resources has to be released.
*/
public void destroyApp(boolean unconditional) {
try{
player.stop();
}catch (MediaException me){
}
}
}



############################################################

2) MyGameCanvas.java

/**
* @author Maxin B. John
*
*/

package com;

import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.LayerManager;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.midlet.*;

/**
*
* @author Maxin B. John
*
*/
public class MyGameCanvas extends GameCanvas implements Runnable{
private static final int SPEED = 5;
private LayerManager lm;
//private byte lastDirection = -1;
private SpriteAnimationTask spriteEggAnimator;
private SpriteAnimationTask spriteChickenAnimator;
private EggFall EggRandomMovement;
private boolean interrupted;
private Timer timer;
private MyGameDesign gameDesign;
private int eggNumber;
private Sprite Egg;
private Sprite Chicken;
public MIDlet mid;
public int canvasHeight;
public int canvasWidth;


public MyGameCanvas(){
super(true);
this.eggNumber=0;
this.setFullScreenMode(true);
this.init();
}

public void stop() {
this.interrupted = true;
}
private void init() {
try{
System.out.println("In init \n");
this.timer = new Timer();
this.gameDesign= new MyGameDesign();
this.Egg = gameDesign.getEgg();
this.Chicken = gameDesign.getMyChicken();
this.Egg.defineReferencePixel(8, 8);
this.Chicken.defineReferencePixel(8, 8);
this.canvasHeight= this.getHeight();
this.canvasWidth = this.getWidth();
this.spriteEggAnimator = new SpriteAnimationTask(this.Egg, false);
this.spriteChickenAnimator = new SpriteAnimationTask(this.Chicken, false);
this.timer.scheduleAtFixedRate(this.spriteEggAnimator, 0, gameDesign.Eggseq001Delay);
this.timer.scheduleAtFixedRate(this.spriteChickenAnimator, 0, gameDesign.MyChickenseq001Delay);
this.lm = new LayerManager();
gameDesign.updateLayerManagerForMySky(lm);
this.EggRandomMovement = new EggFall(this, Egg);

this.EggRandomMovement.setSequences(
gameDesign.MyChickenseq001, Sprite.TRANS_NONE,
gameDesign.MyChickenseq001, Sprite.TRANS_NONE,
gameDesign.MyChickenseq001, Sprite.TRANS_NONE,
gameDesign.MyChickenseq001, Sprite.TRANS_NONE
);

(new Thread(EggRandomMovement)).start();
}catch (IOException io){}
}

public boolean setEggNo(){
this.eggNumber+=1;
return true;
}

public int getEggNo(){
return this.eggNumber;
}

/**
* Check if sprite collides with the Chicken object
*
* @param sprite the sprite checked for collision with other layers
* @return true is sprite does collide, false otherwise
*/
public boolean spriteCollides(Sprite sprite) {
return sprite.collidesWith(this.Chicken, true);
}

public void run(){
System.out.println("Inside the run \n");
Graphics g = getGraphics();
while (!this.interrupted) {
//check for user input
int keyState = getKeyStates();
if ((keyState & LEFT_PRESSED) != 0) {
this.Chicken.setFrameSequence(gameDesign.MyChickenseq001);
this.Chicken.setTransform(Sprite.TRANS_MIRROR);
this.spriteChickenAnimator.backward();
this.Chicken.move(-SPEED, 0);
System.out.println("Left key pressed \n");

}
if ((keyState & RIGHT_PRESSED) != 0) {
this.Chicken.setFrameSequence(gameDesign.MyChickenseq001);
this.Chicken.setTransform(Sprite.TRANS_MIRROR);
this.Chicken.move(SPEED, 0);
System.out.println("Right key pressed \n");


}
if ((keyState & UP_PRESSED) != 0) {
this.Chicken.setFrameSequence(gameDesign.MyChickenseq001);
this.Chicken.setTransform(Sprite.TRANS_MIRROR);
System.gc();
try{
this.mid.notifyDestroyed();
}catch(Exception ex){

}
}

this.Chicken.setFrameSequence(gameDesign.MyChickenseq001);
this.spriteChickenAnimator.setMoving(true);
this.lm.paint(g, 0, 0);
flushGraphics(0, 0, this.getWidth(), this.getHeight());
try {
Thread.sleep(200);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}

/**
* Animates a sprite.
*/
private class SpriteAnimationTask extends TimerTask {

private boolean moving = false;
private boolean forward = true;
private Sprite sprite;

public SpriteAnimationTask(Sprite sprite, boolean forward) {
this.sprite = sprite;
this.forward = forward;
}

public void run() {
if (!this.moving) {
return;
}

if (this.forward) {
this.sprite.nextFrame();
} else {
this.sprite.prevFrame();
}
}

public void forward() {
this.forward = true;
this.moving = true;
}

public void backward() {
this.forward = false;
this.moving = true;
}

public void setMoving(boolean isMoving) {
this.moving = isMoving;
}
}
}


##############################################################

3) EggFall.java


package com;

/**
* @author Maxin B. John
*/

import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import java.util.Random;

public class EggFall implements Runnable,CommandListener{

private static final int SPEED = 3;
private MyGameCanvas canvas;
private Sprite sprite;

private byte previousDirection = GameCanvas.DOWN;
private byte direction = GameCanvas.DOWN;
private boolean interrupted;
private int[] downSeq;
private int downTrans;
private int[] upSeq;
private int upTrans;
private int[] leftSeq;
private int leftTrans;
private int[] rightSeq;
private int rightTrans;
private int finalScore=0;
private Command exitCommand;
private Form form;
private StringItem stringItem;
private Display dsp;


public EggFall(MyGameCanvas canvas, Sprite sprite) {
this.canvas = canvas;
this.sprite = sprite;
}

/////////////////////////////////////////////////////////
public void commandAction(Command command, Displayable displayable){

if (command == exitCommand) {
exitMIDlet();
System.out.println("Exit Command \n");
}

}

public Command getExitCommand() {

if (exitCommand == null) {
exitCommand = new Command("Exit", Command.EXIT, 0);
}
return exitCommand;
}


public void exitMIDlet() {
this.canvas.mid.notifyDestroyed();

}




/////////////////////////////////////////////////////////
public void setSequences(int[] downSeq, int downTrans, int[] upSeq, int upTrans, int[] leftSeq, int leftTrans, int[] rightSeq, int rightTrans) {
this.downSeq = downSeq;
this.downTrans = downTrans;
this.upSeq = upSeq;
this.upTrans = upTrans;
this.leftSeq = leftSeq;
this.leftTrans = leftTrans;
this.rightSeq = rightSeq;
this.rightTrans = rightTrans;
}

public void stop() {
this.interrupted = true;
}

public int getRandomNumber(){
int intervalMin = 10;
int intervalMax = 100;
int halfInterval = (intervalMin - intervalMax) / 2;
int integerDisc = Integer.MAX_VALUE / halfInterval;
Random r = new Random(System.currentTimeMillis());
int randomNumber = r.nextInt();
randomNumber = randomNumber / integerDisc;
randomNumber = randomNumber + halfInterval;
randomNumber = randomNumber <0 ? -1*randomNumber: randomNumber;

return randomNumber;
}

public void run() {
while (!this.interrupted) {
if (this.direction == GameCanvas.DOWN) {
if (this.previousDirection != this.direction) {
this.sprite.setFrameSequence(this.downSeq);
this.sprite.setTransform(this.downTrans);
this.previousDirection = this.direction;
}
this.sprite.move(0, SPEED);
if(this.sprite.getY()> this.canvas.canvasHeight && this.sprite.isVisible()){
System.out.println("This egg got broken .. you loose one egg\n");
this.sprite.setVisible(false);
if (this.canvas.getEggNo() >= 10){
System.out.println("Game over You scored ..\n"+ this.finalScore);
this.canvas.stop();
this.stop();
this.canvas.setFullScreenMode(false);
this.canvas.setCommandListener(this);
this.canvas.addCommand(this.getExitCommand());

}
else{
this.canvas.setEggNo();
this.sprite.setPosition(this.getRandomNumber(), 0);
this.sprite.setVisible(true);
System.out.println(this.canvas.getEggNo());
}
}

if (this.canvas.spriteCollides(this.sprite)) {
this.sprite.setVisible(false);
this.finalScore += 1;
System.out.println("You secured your egg!scored"+this.finalScore+"\n");

if (this.canvas.getEggNo() >= 10){
System.out.println("Game over \n"+ this.finalScore);
this.canvas.stop();
this.stop();
this.canvas.setFullScreenMode(false);
this.canvas.setCommandListener(this);
this.canvas.addCommand(this.getExitCommand());
}
else{
this.canvas.setEggNo();
this.sprite.setPosition(this.getRandomNumber(), 0);
this.sprite.setVisible(true);
System.out.println(this.canvas.getEggNo());
}
continue;
}
}
try {
Thread.sleep(200);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}


########################################################

4) MyGameDesign.java

/**
* Maxin B. John
*/

package com;

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
import java.io.IOException;
import java.util.Random;

/**
* @author maxin.john
*/
public class MyGameDesign {

//
private Image eggs;
private Sprite MyEgg;
public int MyEggseq001Delay = 200;
public int[] MyEggseq001 = {68, 68, 68, 67, 67};
private TiledLayer MyLayer;
private Sprite Chicken;
public int Chickenseq001Delay = 100;
public int[] Chickenseq001 = {84, 85, 86, 87, 84};
private Image chickens;
private TiledLayer ChicLayer;
private Sprite Egg;
public int Eggseq001Delay = 200;
public int[] Eggseq001 = {69, 69, 69, 69, 69};
private Sprite MyChicken;
public int MyChickenseq001Delay = 200;
public int[] MyChickenseq001 = {0, 0, 5, 16, 21};
//

/* public int canvasHeight=100;
public int canvasWidth;*/
//
//






public void updateLayerManagerForMySky(LayerManager lm) throws java.io.IOException {
// write pre-update user code here
int intervalMin = 10;
int intervalMax = 100;
int halfInterval = (intervalMin - intervalMax) / 2;
int integerDisc = Integer.MAX_VALUE / halfInterval;
Random r = new Random(System.currentTimeMillis());
int randomNumber = r.nextInt();
randomNumber = randomNumber / integerDisc;
randomNumber = randomNumber + halfInterval;
randomNumber = randomNumber <0 ? -1*randomNumber: randomNumber;
getEgg().setPosition(randomNumber, 0);
getMyChicken().setPosition(10,100);
getMyChicken().setVisible(true);
getEgg().setVisible(true);
lm.append(getEgg());
lm.append(getMyChicken());
getChicLayer().setPosition(0, 0);
getChicLayer().setVisible(true);
lm.append(getChicLayer());

// write post-update user code here
}



public Image getChickens() throws java.io.IOException {
if (chickens == null) {
// write pre-init user code here
chickens = Image.createImage("/chickens.png");
}
// write post-init user code here
return this.chickens;
}


public TiledLayer getChicLayer() throws java.io.IOException {
if (ChicLayer == null) {
// write pre-init user code here
ChicLayer = new TiledLayer(20, 20, getChickens(), 16, 16);
int[][] tiles = {
{ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51 },
{ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51 },
{ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52 },
{ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52 },
{ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51 },
{ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51 },
{ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51 },
{ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51 },
{ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51 },
{ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51 },
{ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51 },
{ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51 },
{ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51 },
{ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51 },
{ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51 },
{ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51 },
{ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52 },
{ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52 },
{ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52 },
{ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52 }
};
// write mid-init user code here
for (int row = 0; row < 20; row++) {
for (int col = 0; col < 20; col++) {
ChicLayer.setCell(col, row, tiles[row][col]);
}
}
}
// write post-init user code here
return ChicLayer;
}


public Sprite getEgg() throws java.io.IOException {
if (Egg == null) {
// write pre-init user code here
Egg = new Sprite(getChickens(), 16, 16);
Egg.setFrameSequence(Eggseq001);
// write post-init user code here
}
return Egg;
}


public Sprite getMyChicken() throws java.io.IOException {
if (MyChicken == null) {
// write pre-init user code here
MyChicken = new Sprite(getChickens(), 16, 16);
MyChicken.setFrameSequence(MyChickenseq001);
// write post-init user code here
}
return MyChicken;
}
}

Tidak ada komentar:

Posting Komentar