// WalkingMarioMIDlet.java (c) Kari Laitinen // http://www.naturalprogramming.com/ // 2011-04-07 File created. // 2011-04-28 Last modification. /* This midlet demonstrates: - animation - use of the Sprite class, a Sprite object contains an image that is split into many frames that can be displayed as a defined sequence of frames Acknowledgments: The development of this program has been aided by Joonas Hannula, Miika Kontio, and Erja Manninen. */ import java.io.* ; import javax.microedition.midlet.*; import javax.microedition.lcdui.*; import javax.microedition.lcdui.game.Sprite ; class Mario { int speed_in_pixels = 2 ; Image mario_frames ; Sprite mario_sprite ; int[] frames_to_walk_down = { 15,16,17,16 } ; int[] frames_to_walk_right = { 9,10,11,10 } ; int[] frames_to_walk_up = { 3,4,5,4 } ; int[] frames_to_walk_left = { 21,22,23,22 } ; static final int MOVING_DOWN = 0 ; static final int MOVING_RIGHT = 1 ; static final int MOVING_UP = 2 ; static final int MOVING_LEFT = 3 ; int mario_state = MOVING_RIGHT ; public Mario( int initial_mario_position_x, int initial_mario_position_y ) { try { mario_frames = Image.createImage( "/mario_frames.png" ) ; int picture_width = mario_frames.getWidth() ; int picture_height = mario_frames.getHeight() ; // NOTE: The used picture must be such that the following // divisions produce 'correct' results, i.e., picture width // must be equally divisible by 6, and picture height equally // divisible by 4 int sprite_frame_width = picture_width / 6 ; int sprite_frame_height = picture_height / 4 ; mario_sprite = new Sprite( mario_frames, sprite_frame_width, sprite_frame_height ) ; mario_sprite.setPosition( initial_mario_position_x, initial_mario_position_y ) ; mario_sprite.setFrameSequence ( frames_to_walk_right ) ; } catch ( IOException io_exception ) { System.out.print( "\n Could not create an Image object .... " ) ; } catch ( Exception exception ) { System.out.print( "\n Could not create an Image or Sprite " ) ; } } public int get_position_x() { return mario_sprite.getX() ; } public void turn_180_degrees() { if ( mario_state == MOVING_RIGHT ) { mario_sprite.setFrameSequence( frames_to_walk_left ) ; mario_state = MOVING_LEFT ; } else if ( mario_state == MOVING_LEFT ) { mario_sprite.setFrameSequence( frames_to_walk_right ) ; mario_state = MOVING_RIGHT ; } else if ( mario_state == MOVING_UP ) { mario_sprite.setFrameSequence( frames_to_walk_down ) ; mario_state = MOVING_DOWN ; } else if ( mario_state == MOVING_DOWN ) { mario_sprite.setFrameSequence( frames_to_walk_up ) ; mario_state = MOVING_UP ; } } public void update() { if ( mario_state == MOVING_RIGHT ) { mario_sprite.move( speed_in_pixels, 0 ) ; } else if ( mario_state == MOVING_LEFT ) { mario_sprite.move( - speed_in_pixels, 0 ) ; } else if ( mario_state == MOVING_UP ) { mario_sprite.move( 0, - speed_in_pixels ) ; } else if ( mario_state == MOVING_DOWN ) { mario_sprite.move( 0, speed_in_pixels ) ; } mario_sprite.nextFrame() ; } public void draw( Graphics graphics ) { mario_sprite.paint( graphics ) ; } } class WalkingMarioCanvas extends Canvas implements Runnable { Thread animation_thread ; boolean thread_must_be_run = false ; int canvas_width = getWidth() ; int canvas_height = getHeight() ; Mario walking_mario = new Mario( 0, 40 ) ; int interval_between_frames = 100 ; public WalkingMarioCanvas() { } 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 ) { // First we'll call the update() method that // moves the Mario figure and takes the next frame // into use. walking_mario.update() ; // Then we'll check whether a collision (with a wall) // has occurred. if ( walking_mario.get_position_x() > canvas_width || walking_mario.get_position_x() < 0 ) { walking_mario.turn_180_degrees() ; } // Finally we'll ask the execution environment to // dedraw. repaint() ; try { Thread.sleep( interval_between_frames ) ; } catch ( InterruptedException caught_exception ) { // No actions to handle the exception. } } } protected void paint( Graphics graphics ) { // The background color is darkish green, the same color // as is the background of frames graphics.setColor( 0, 115, 0 ) ; graphics.fillRect( 0, 0, canvas_width, canvas_height ) ; walking_mario.draw( graphics ) ; } } public class WalkingMarioMIDlet extends MIDlet implements CommandListener { Display midlet_display = Display.getDisplay( this ) ; WalkingMarioCanvas walking_mario_canvas = new WalkingMarioCanvas() ; Command exit_command = new Command( "Exit", Command.EXIT, 1 ) ; public WalkingMarioMIDlet() { walking_mario_canvas.addCommand( exit_command ) ; walking_mario_canvas.setCommandListener( this ) ; } protected void startApp() throws MIDletStateChangeException { midlet_display.setCurrent( walking_mario_canvas ) ; walking_mario_canvas.start_animation_thread() ; } protected void pauseApp() { walking_mario_canvas.stop_animation_thread() ; } protected void destroyApp( boolean unconditional_destruction_required ) { walking_mario_canvas.stop_animation_thread() ; } public void commandAction( Command given_command, Displayable display_content ) { if ( given_command == exit_command ) { destroyApp( false ) ; notifyDestroyed() ; } } }