/*******************************************
* Breakout Clone
* @version v1.0
* @author Maan Ashgar
* email: al_amed@yahoo.com
* **********************************************/
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
public class PongClone
extends MIDlet
implements CommandListener
{
// the main screen commands
private Command about = new Command("About",Command.HELP,1);
private Command exit = new Command("Exit",Command.EXIT,1);
private Command new_game = new Command("new game",Command.SCREEN,99);
// TODO: add a pause command , give the player the abillity to pause
Display display;
Form main_form;
GameClass game_class;
/** debuging method*/
static void debug(String s)
{
System.out.println(s);
}
protected void startApp()
throws MIDletStateChangeException
{
main_form = new Form("Pong Clone");
display = Display.getDisplay( this );
display.setCurrent(main_form);
//adding commands to the form
main_form.addCommand(about);
main_form.addCommand(exit);
main_form.addCommand(new_game);
main_form.setCommandListener(this);
}
public void commandAction(Command c, Displayable s)
{
if( c == about )//what to do on about command
{
Alert about_alert = new Alert( "About" , "This game is by Maan Ashgar" , null , AlertType.INFO );
display.setCurrent(about_alert,main_form);
}
if( c == exit )//what to do on exit command
{
try
{
game_class.exit();
destroyApp(false);
notifyDestroyed();
}
catch (Exception e)
{
}
}
if( c == new_game )//what to do on new game command
{
//start a new game
game_class = new GameClass();
game_class.addCommand(exit);
display.setCurrent(game_class);
}
}
//////////////////////destory & pause //////////////////////
protected void destroyApp( boolean unconditional )
throws MIDletStateChangeException
{
/*TODO : change all objects to null, stop all threads*/
display = null ;
main_form = null ;
game_class.inPlay = false ;
game_class = null ;
System.gc();
}
protected void pauseApp()
{
}
}
/**
* the game class, where the thread handling and the background painting
* and the user input checking is made
*/
class GameClass
extends javax.microedition.lcdui.game.GameCanvas
implements Runnable
{
//new game indecator
private boolean new_game;
private Ball ball;
private Puck puck;
Bricks brick;
//width of the screen
int width = getWidth();
//height of the screen
int height = getHeight();
//the ball image
String ball_image_string = "/xd.png";
//the puck image
String puck_image_string = "/puck.png";
//puck image width
int puck_image_width ;
//puck image width
int puck_image_height ;
// the LayerManager
LayerManager lm = new LayerManager();
//the on/off variable to the game loop
boolean inPlay;
//the ball direction
int x_dir = 5 ;
int y_dir = 5 ;
//game over flag
boolean end_game;
public GameClass()
{
super(false);
// create the sprites and start the game thread
try
{
// create the ball sprite
Image temp_image = Image.createImage( ball_image_string );
ball = new Ball( temp_image );
//create the puck sprite
temp_image = Image.createImage( puck_image_string );
puck = new Puck( temp_image );
//get the height and width of the puck image
puck_image_width = temp_image.getWidth();
puck_image_height = temp_image.getHeight();
//create the brick sprite
temp_image = Image.createImage("/bricks.png");
brick = new Bricks(temp_image);
//set the puck and the ball start location in the screen
puck.setPosition( width/2 - puck_image_width/2 , height - 30 );
ball.setPosition( width/3 , height/3 * 2 );
}
catch(Exception e)
{
}
//add the ball and puck to the layer manager
lm.append(brick);
lm.append(ball);
lm.append(puck);
//set the game loop on
inPlay = true;
//start the game thread
new Thread(this).start();
}
public void paint(Graphics g)
{
//draw the white background
g.setColor(0xffffff);
g.fillRect(0,0,width,height);
//draw the sprites
lm.paint(g,0,0);
//in case the game end , draw this
if(end_game == true)
{
g.setColor(0x000000);
g.fillRect(0,(height/2)-20,width,40);
g.setColor(0xffffff);
g.drawString("Oops! Game over",width/2,height/2, Graphics.BASELINE|Graphics.HCENTER );
}
flushGraphics();
}
public void run()
{
while(inPlay)
{
checkKeys();
ballMove();
this.paint(getGraphics());
try
{
Thread.sleep(100);
}
catch(Exception e)
{
}
}
}
/**
* this method will check for user input and move the puck
* accordingly
*/
public void checkKeys()
{
int x = puck.getX();
int key = getKeyStates();
//Left?
if( (key & LEFT_PRESSED) != 0)
{
if ( x - 7 >= 0 )
puck.move(-7,0);
else if ( x - 7 < 0 )
puck.move( (-1 * x) ,0);
}
//Right?
if( (key & RIGHT_PRESSED) != 0)
{
if( x + puck_image_width+ 7 < width )
puck.move( 7 , 0 );
else if( x + puck_image_width + 7 >= width )
puck.move( 0 , 0 );
}
}
/**
* this method will set the inPlay to false on exit to stop the loop
*/
public void exit()
{
inPlay = false;
}
/**
* this method will be responsbale for moving the ball
*/
public void ballMove()
{
// if the ball hit the puck
if (ball.collidesWith(puck,false))
{
//TODO: more advance puck/ball hit calculations
if(ball.getX() > (puck.getX()+18) && ball.getX() <= (puck.getX()+37))
{
y_dir *= -1 ;
}
else if (ball.getX()> (puck.getX()+37))
{
y_dir = (y_dir * -1) - 2 ;
}
else if (ball.getX() <= (puck.getX()+18))
{
y_dir = (y_dir * -1) + 2 ;
}
}
if (ball.collidesWith(brick,false) && brick.isVisible())
{
brick.setVisible(false);
}
//if the ball hit one of the walls
if ((ball.getX()+15) >= width || ball.getX() <= 0 )
x_dir *= -1 ;
//if the ball hit the roof
if (ball.getY() <= 0 )
y_dir *= -1 ;
//End game hit, if the ball hit the floor
if ((ball.getY()+15) >= height)
{
end_game = true ;
inPlay = false ;
}
ball.move(x_dir,y_dir) ;
}
}
class Ball extends javax.microedition.lcdui.game.Sprite
{
public Ball(Image image) throws Exception
{
super(image);
}
}
class Puck extends javax.microedition.lcdui.game.Sprite
{
public Puck(Image image) throws Exception
{
super(image);
}
}
class Bricks extends javax.microedition.lcdui.game.TiledLayer
{
Image brick_image ;
public Bricks(Image brick_image) throws Exception
{
super(4,3,brick_image,51,21);
int[] map = {
1,2,3,0,
2,0,2,0,
3,2,1,0
};
for (int i=0; i < map.length; i++) {
int column = i % 4;
int row = (i - column) / 3;
setCell(column,row,map[i]);
}
}
}