// "sinatra.java" // Joe Rosen (05/15/98). // Java 1.02 Event Model, version 2. import java.applet.*; import java.awt.*; // begin: applet "sinatra" public class sinatra extends Applet implements Runnable { // constants // window width X height final int k_Window_Width = 300; final int k_Window_Height = 329; // palm-size plastic case, top/left origin final int k_Case_Origin_Top = 39; final int k_Case_Origin_Left = 10; // switch up, top/left origin final int k_Switch_Up_Origin_Top = 10; final int k_Switch_Up_Origin_Left = 150; // Sinatra head, top/left origin final int k_Sinatra_Origin_Top = 93; final int k_Sinatra_Origin_Left = 86; // variables // switch button rect Rectangle switch_btn_rect; // random switch button color (1=black; 2=red) Color switch_btn_Color; // ((int) ((Math.random() * 2) + 1)) // mouth rectangle (used as button to toggle mouth open/close) Rectangle mouth_btn_rect; // sinatra images (all in one file) Image sinatra_Image; // images offset, flip-flop between 2 heads/eyes/mouth in same image file int image_offset; // 0= head 1; 171= head 2 // flag mouth anim boolean mouth_anim_flg; // true= anim // flag eyes open boolean eyes_open_flg; // true= open // flag eyes position int eyes_position_flg; // 0= left; 1= center; 2= right // offscreen graphics context (composite buffer) Image offscrn_Image; Graphics offscrn_Graphics; // animation thread Thread animation_Thread; // MediaTracker MediaTracker the_MediaTracker; // counter bug in mouseMove() // i.e. mouseMove() is continually reported while cursor's inside applet even // if there's no mouse movement. int prv_x, prv_y; // match previous mouse pos against cur mouse pos // init public void init() { // load sinatra images (all in one file) sinatra_Image = getImage(getCodeBase(),"images/sinatra.jpg"); // init and load MediaTracker the_MediaTracker = new MediaTracker(this); the_MediaTracker.addImage(sinatra_Image,0); // images offset, flip-flop between 2 heads/eyes/mouths in same image file image_offset = 0; // 0= head 1; 171= head 2 // init, flag mouth anim mouth_anim_flg = false; // true= anim // init, flag eyes open eyes_open_flg = false; // true= open // init, flag eyes position eyes_position_flg = 1; // 0= left; 1= center; 2= right // switch button rect switch_btn_rect = new Rectangle(k_Switch_Up_Origin_Left,k_Switch_Up_Origin_Top,42,53); // random switch button color (1=black; 2=red) if ( ((int) ((Math.random() * 2) + 1)) == 1 ) switch_btn_Color = Color.black; else switch_btn_Color = Color.red; // mouth rectangle (used as button to toggle mouth open/close) mouth_btn_rect = new Rectangle(k_Sinatra_Origin_Left+51,k_Sinatra_Origin_Top+155,46,38); // create offscreen graphics context (composite buffer) offscrn_Image = createImage(k_Window_Width,k_Window_Height); offscrn_Graphics = offscrn_Image.getGraphics(); // counter bug in mouseMove() // i.e. mouseMove() is continually reported while cursor's inside applet even // if there's no mouse movement. prv_x = -1; prv_y = -1; // match previous mouse pos against cur mouse pos } // end "init" /* "start()" * called when the applet becomes visible on screen */ public void start() { // start animator thread animation_Thread = new Thread(this); animation_Thread.start(); } /* end "start" /* "run()" * called (repeatedly) by the Thread created in "start()" */ public void run() { // update animator thread while (Thread.currentThread() == animation_Thread) { // repaint (update) the screen repaint(); // begin: thread delay (125 milliseconds) try { Thread.sleep(125); } catch (InterruptedException e) { break; } // end: thread delay // images offset, flip-flop between 2 heads/eyes/mouths in same image file if (image_offset == 0) image_offset = 171; // 171= head 2 else image_offset = 0; // 0= head 1 } // end "while (Thread.currentThread() == animation_Thread)" } // end "run" /* "stop()" * called when the applet is no longer visible on screen */ public void stop() { // stop scrolling logo animator thread if (animation_Thread != null) animation_Thread.stop(); animation_Thread = null; } // end "stop" /* "destroy()" * called just before the browser exits */ public void destroy() { // don't rely on garbage collection to release offscreen buffer offscrn_Graphics.dispose(); } // end "destroy" /* "mouseDown()" * called when the mouse button is pressed down */ public boolean mouseDown(Event evt, int x, int y) { // System.out.println("mouseDown: " + x + "," + y); // mouse press switch btn (?) if ( switch_btn_rect.inside(x,y) ) { // toggle eyes open if (eyes_open_flg == false) eyes_open_flg = true; // true= open else eyes_open_flg = false; // force repaint (screen update) repaint(); } // end "eyes" // mouse press in mouth btn (?) else if ( mouth_btn_rect.inside(x,y) ) { // toggle mouth anim if (mouth_anim_flg == false) mouth_anim_flg = true; // true= anim else mouth_anim_flg = false; // force repaint (screen update) repaint(); } // end "mouth" return true; } // end "mouseDown" /* "mouseMove()" * called when the mouse moves */ public boolean mouseMove(Event evt, int x, int y) { //System.out.println("mouseMove: " + x + "," + y); // absolutely ensure that there's been mouse movement if (prv_x == x || prv_y == y) return true; // return immediately, there's been no real mouse movement // eye motion detector (0= left; 1= center; 2= right) if ( x < (.333 * k_Window_Width) ) eyes_position_flg = 0; else if ( (x >= (.333 * k_Window_Width)) && (x < (.663 * k_Window_Width)) ) eyes_position_flg = 1; else if ( x >= (.666 * k_Window_Width) ) eyes_position_flg = 2; // force repaint (screen update) only if eyes are open if (eyes_open_flg) repaint(); // save coords (for match previous mouse pos against cur mouse pos in next pass) prv_x = x; prv_y = y; return true; } // end "mouseMove" /* "update()" * update the screen */ public void update(Graphics g) { // call "paint()" (intercepting "update" avoids background erase) paint(g); } /* end method "update" */ /* "paint()" * paint the screen */ public void paint(Graphics g) { // "more info" scroll crop Graphics clip_g; // fill buffer with white paint offscrn_Graphics.setColor(Color.white); offscrn_Graphics.fillRect(0,0,k_Window_Width,k_Window_Height); // if images loaded draw if ( the_MediaTracker.checkAll(true) == true ) { // draw the palm-size plastic case draw_palm_case(offscrn_Graphics); // begin: head // create clip rect clip_g = offscrn_Graphics.create(); // set clip rect clip_g.clipRect(k_Sinatra_Origin_Left,k_Sinatra_Origin_Top,171,216); // draw template image clip_g.drawImage( sinatra_Image, k_Sinatra_Origin_Left-image_offset,k_Sinatra_Origin_Top,this ); // dispose clip rect clip_g.dispose(); // end: head // begin: mouth (open?) if (mouth_anim_flg == true) { // create clip rect clip_g = offscrn_Graphics.create(); // set clip rect clip_g.clipRect(k_Sinatra_Origin_Left+51,k_Sinatra_Origin_Top+155,46,38); clip_g.drawImage( sinatra_Image, k_Sinatra_Origin_Left-image_offset,(k_Sinatra_Origin_Top+155)-270,this ); // dispose clip rect clip_g.dispose(); } // end: mouth // begin: eyes (open ?) if (eyes_open_flg == true) { // create clip rect clip_g = offscrn_Graphics.create(); // set clip rect clip_g.clipRect(k_Sinatra_Origin_Left+36,k_Sinatra_Origin_Top+108,75,18); if (eyes_position_flg == 0) clip_g.drawImage( sinatra_Image, k_Sinatra_Origin_Left-image_offset,(k_Sinatra_Origin_Top+108)-216,this); else if (eyes_position_flg == 1) clip_g.drawImage( sinatra_Image, k_Sinatra_Origin_Left-image_offset,(k_Sinatra_Origin_Top+108)-234,this); else if (eyes_position_flg == 2) clip_g.drawImage( sinatra_Image, k_Sinatra_Origin_Left-image_offset,(k_Sinatra_Origin_Top+108)-252,this); // dispose clip rect clip_g.dispose(); } // end: eyes } // else, image has yet to load else { // font Font txt_Font = new Font("Helvetica", Font.PLAIN, 9); // set text string font offscrn_Graphics.setFont(txt_Font); // set text string color offscrn_Graphics.setColor(Color.black); // write/draw text message offscrn_Graphics.drawString("Loading Images...",25,25); } // blast buffer to screen g.drawImage(offscrn_Image,0,0,this); } /* end method "paint" */ /* "draw_palm_case()" * draw the palm-size plastic case */ public void draw_palm_case(Graphics g) { // build palm-size plastic case // main frame g.setColor(Color.black); //g.setColor(Color.red); g.drawRect(k_Case_Origin_Left+44,k_Case_Origin_Top+44,235,235); g.drawLine( k_Case_Origin_Left,k_Case_Origin_Top, k_Case_Origin_Left,k_Case_Origin_Top+235 ); g.drawLine( k_Case_Origin_Left,k_Case_Origin_Top, k_Case_Origin_Left+235,k_Case_Origin_Top ); g.drawLine( k_Case_Origin_Left+235,k_Case_Origin_Top, k_Case_Origin_Left+279,k_Case_Origin_Top+44 ); g.drawLine( k_Case_Origin_Left,k_Case_Origin_Top, k_Case_Origin_Left+44,k_Case_Origin_Top+44 ); g.drawLine( k_Case_Origin_Left,k_Case_Origin_Top+235, k_Case_Origin_Left+44,k_Case_Origin_Top+279 ); // inner frame //g.setColor(Color.green); g.drawRect(k_Case_Origin_Left+45,k_Case_Origin_Top+45,233,233); g.drawLine( k_Case_Origin_Left+1,k_Case_Origin_Top+1, k_Case_Origin_Left+1,k_Case_Origin_Top+235 ); g.drawLine( k_Case_Origin_Left+1,k_Case_Origin_Top+1, k_Case_Origin_Left+235,k_Case_Origin_Top+1 ); // g.drawLine( k_Case_Origin_Left+235,k_Case_Origin_Top, // k_Case_Origin_Left+279,k_Case_Origin_Top+44); g.drawLine( k_Case_Origin_Left+235,k_Case_Origin_Top+1, k_Case_Origin_Left+277,k_Case_Origin_Top+43 ); g.drawLine( k_Case_Origin_Left+236,k_Case_Origin_Top, k_Case_Origin_Left+279,k_Case_Origin_Top+43); // g.drawLine( k_Case_Origin_Left,k_Case_Origin_Top+235, // k_Case_Origin_Left+44,k_Case_Origin_Top+279); g.drawLine( k_Case_Origin_Left+1,k_Case_Origin_Top+235, k_Case_Origin_Left+43,k_Case_Origin_Top+277 ); g.drawLine( k_Case_Origin_Left,k_Case_Origin_Top+236, k_Case_Origin_Left+43,k_Case_Origin_Top+279 ); // g.drawLine( k_Case_Origin_Left,k_Case_Origin_Top, // k_Case_Origin_Left+44,k_Case_Origin_Top+44 ); g.drawLine( k_Case_Origin_Left+1,k_Case_Origin_Top+2, k_Case_Origin_Left+43,k_Case_Origin_Top+44 ); g.drawLine( k_Case_Origin_Left+2,k_Case_Origin_Top+1, k_Case_Origin_Left+44,k_Case_Origin_Top+43 ); // draw switch // up if (eyes_open_flg == false) { g.setColor(Color.gray); g.fillRect(k_Switch_Up_Origin_Left+12,k_Switch_Up_Origin_Top+20,18,33); g.setColor(Color.black); g.drawRect(k_Switch_Up_Origin_Left+12,k_Switch_Up_Origin_Top+20,18,33); g.setColor(switch_btn_Color); g.fillRect(k_Switch_Up_Origin_Left,k_Switch_Up_Origin_Top,42,21); g.setColor(Color.black); g.drawRect(k_Switch_Up_Origin_Left,k_Switch_Up_Origin_Top,42,21); } // down else { g.setColor(Color.gray); g.fillRect(k_Switch_Up_Origin_Left+12,k_Switch_Up_Origin_Top+39,18,14); g.setColor(Color.black); g.drawRect(k_Switch_Up_Origin_Left+12,k_Switch_Up_Origin_Top+39,18,14); g.setColor(switch_btn_Color); g.fillRect(k_Switch_Up_Origin_Left,k_Switch_Up_Origin_Top+19,42,21); g.setColor(Color.black); g.drawRect(k_Switch_Up_Origin_Left,k_Switch_Up_Origin_Top+19,42,21); } } /* end method "draw_palm_case" */ } // end: applet "sinatra"