// PacmanMIDlet.java (c) Kari Laitinen // http://www.naturalprogramming.com/ // 2010-10-15 File created. // 2011-04-28 Last modification. /* This midlet demonstrates: - animation - use of the GameCanvas class Notes: - at least in the Sun Wireless Toolkit emulator, the size of a GameCanvas seems to be the same as the size of a conventional Canvas */ import java.io.* ; import javax.microedition.midlet.*; import javax.microedition.lcdui.*; import javax.microedition.lcdui.game.Sprite ; import javax.microedition.lcdui.game.GameCanvas ; // For the time being, the Pacman described by the class below // can only move horizontally. class Pacman { int pacman_center_point_x, pacman_center_point_y ; int[] pacman_mouth_angles = { 90, 75, 60, 45, 30, 15, 0, 15, 30, 45, 60, 75 } ; int mouth_angle_index = 0 ; boolean moving_left_to_right = true ; Pacman( int given_center_point_x, int given_center_point_y ) { pacman_center_point_x = given_center_point_x ; pacman_center_point_y = given_center_point_y ; } public void turn() { moving_left_to_right = ! moving_left_to_right ; } public void turn_right() { moving_left_to_right = true ; } public void turn_left() { moving_left_to_right = false ; } public void move() { mouth_angle_index ++ ; if ( mouth_angle_index >= pacman_mouth_angles.length ) { mouth_angle_index = 0 ; } if ( moving_left_to_right == true ) { pacman_center_point_x += 1 ; } else { pacman_center_point_x -= 1 ; } } public void draw( Graphics graphics ) { graphics.setColor( 0, 0, 0 ) ; int pacman_mouth_angle = pacman_mouth_angles[ mouth_angle_index ] ; if ( moving_left_to_right == true ) { graphics.fillArc( pacman_center_point_x, pacman_center_point_y, 100, 80, pacman_mouth_angle / 2, 360 - pacman_mouth_angle ) ; } else { // The Pacman mouth must open to the left. graphics.fillArc( pacman_center_point_x, pacman_center_point_y, 100, 80, 180 + pacman_mouth_angle / 2, 360 - pacman_mouth_angle ) ; } } } class PacmanCanvas extends GameCanvas implements Runnable { Thread animation_thread ; boolean thread_must_be_run = false ; int canvas_width = getWidth() ; int canvas_height = getHeight() ; Pacman moving_pacman = new Pacman( 100, 100 ) ; Graphics graphics ; public PacmanCanvas() { super( false ) ; graphics = getGraphics() ; System.out.print( "\n " + canvas_width + " x " + canvas_height + "\n" ) ; } public synchronized void start_animation_thread() { if ( animation_thread == null ) { animation_thread = new Thread( this ) ; thread_must_be_run = true ; animation_thread.start() ; } } public void stop_animation_thread() { if ( animation_thread != null ) { thread_must_be_run = false ; animation_thread.interrupt() ; animation_thread = null ; } } public void run() { while ( thread_must_be_run == true ) { // Check user input and turn the pacman if necessary. int key_state = getKeyStates() ; if ( ( key_state & LEFT_PRESSED ) != 0 ) { moving_pacman.turn_left() ; } else if ( ( key_state & RIGHT_PRESSED) != 0 ) { moving_pacman.turn_right() ; } else if ( ( key_state & UP_PRESSED ) != 0 || ( key_state & DOWN_PRESSED ) != 0 ) { moving_pacman.turn() ; } // The background color is red graphics.setColor( 255, 0, 0 ) ; graphics.fillRect( 0, 0, canvas_width, canvas_height ) ; moving_pacman.move() ; moving_pacman.draw( graphics ) ; flushGraphics() ; // flushes the off-screen buffer to display. // The other version of flushGraphics() would not render the // entire buffer. That is probably used in applications in // which processing time need to be spared. try { Thread.sleep( 40 ) ; } catch ( InterruptedException caught_exception ) { // No actions to handle the exception. } } } } public class PacmanMIDlet extends MIDlet { Display midlet_display = Display.getDisplay( this ) ; PacmanCanvas pacman_canvas = new PacmanCanvas() ; protected void startApp() throws MIDletStateChangeException { midlet_display.setCurrent( pacman_canvas ) ; pacman_canvas.start_animation_thread() ; } protected void pauseApp() { pacman_canvas.stop_animation_thread() ; } protected void destroyApp( boolean unconditional_destruction_required ) { pacman_canvas.stop_animation_thread() ; } }