import java.applet.*; import java.awt.*; ///////////////////////////////////////////////////////////////// public class Tricytreme extends BitmapLoop implements Intersect { byte state; // Tricytreme states static final byte STANDBY = 0; static final byte LAND = 1; static final byte EXPLODE = 2; // probability of state transitions static final double STANDBY_EXIT = .95; static final double LAND_EXIT = .95; static final double FLIP_X = 0.9; // bitmap animations protected Image tricytreme[]; // tricytreme animation protected Image explode[]; // explosion sequence // instance vars int max_x, max_y; // max coords of this tricytreme int explosion_counter; // counter for explosion bitmaps TricytremeManager tManager; // class vars static Intersect target; // refers to the ship static int ship_y; // the y-coord of ship static GameManager game; // ptr to game manager // constructor: initialize image references, instance vars public Tricytreme(Image trImages[], Image explodeImages[], int max_x,int max_y, TricytremeManager tManager, Applet applet) { super(0,0,null,trImages,applet); this.max_x = max_x; this.max_y = max_y; currentImage = getRand(trImages.length); tricytreme = trImages; explode = explodeImages; game = (GameManager)applet; this.tManager = tManager; startStandby(); } // finish initializing info about the player's ship // this way, the tricytreme can communicate with the ship static public void initialize(ShipManager gm) { target = gm.getShip(); // refers to ship sprite ship_y = gm.getShipY(); // get ship y-coordinate } // implement Intersect interface: public boolean intersect(int x1,int y1,int x2,int y2) { return visible && (x2 >= locx) && (locx+width >= x1) && (y2 >= locy) && (locy+height >= y1); } // This is called if a missile hits the tricytreme public void hit(int type) { if (state != EXPLODE) { startExplode(); // start explode state game.decrementScore(); // add to score } } // set state and images loop public void init() { startStandby(); images = tricytreme; restore(); } // this implements the state machine public void update() { // if tricytreme hits target, notify target, and increment the score if if ((locy + height >= ship_y) && state != EXPLODE && target.intersect(locx,locy,locx+width,locy+height)) { target.hit(ShipSprite.GATHER); game.gathered(); suspend(); } // otherwise, update alien state double r1 = Math.random(); double r2 = Math.random(); switch (state) { case STANDBY: if (r1 > STANDBY_EXIT) { startLand(); } // flip tricytreme's x-direction if it goes too far right // or left, or if random variable passes threshold else if ((locx < width) || (locx > max_x - width) || (r2 > FLIP_X)) { vx = -vx; } break; case LAND: if (r1 > LAND_EXIT) { startStandby(); } else if (locy >= max_y-height) { landingRoutine(); } break; case EXPLODE: explosion_counter++; // bump counter // suspend once animation // is finished if (explosion_counter == explode.length) { suspend(); } } super.update(); // call BitmapLoop's update() } // when the tricytreme mineral lands successfully protected void landingRoutine() { suspend(); } // start standby state protected void startStandby() { vx = getRand(8)-4 ; vy = 0; state = STANDBY; } // start landing state protected void startLand() { vx = 0; vy = getRand(3) + 2; state = LAND; } // start explosion state protected void startExplode() { images = explode; // set bitmap to explosion sequence currentImage = 0; // start at beginning of animation explosion_counter = 0; // count the number of frames tManager.playExplosion(); // play explosion sound state = EXPLODE; } // return a random int from 0 to x static public int getRand(int x) { return (int)(x * Math.random()); } }