// Defines the SpaceShip SpaceObject. package SpaceWar; import java.awt.*; import java.awt.geom.*; class SpaceShip extends SpaceObject implements ControlledObject { ////////////////////////////////////////////////////////////////////// // // Parameters. protected static double engineThrust = 0.3; protected static int numberOfMines = 5; protected static double rotateRate = Math.PI / 32; protected static double shipMass = 5.0; protected static double shipRadius = 8.; ////////////////////////////////////////////////////////////////////// // // Instance variables. protected SpaceMissile myMissile; protected SpaceMine[] myMines = new SpaceMine[numberOfMines]; ////////////////////////////////////////////////////////////////////// // // Static members. // Register class. protected static void register() { SpaceObjectRegistry.put("ship", new SpaceShip()); } ////////////////////////////////////////////////////////////////////// // // Constructors. public SpaceShip() { setRadius(shipRadius); setMass(shipMass); } public SpaceShip(Color body, Color trim) { this(); setBodyColor(body); setTrimColor(trim); } ////////////////////////////////////////////////////////////////////// // // Control methods. public void detonateMissile() { synchronized(universe) { if (amOutOfControl()) { return; } if (myMissile != null) { myMissile.startExploding(null); myMissile = null; } } } public void toggleEngine() { synchronized(universe) { if (amOutOfControl()) { return; } if (thrust == 0.) { thrust = engineThrust; } else { thrust = 0.; } } } public void rotateClockwise() { synchronized(universe) { angularVelocity = -rotateRate; } } public void rotateCounterClockwise() { synchronized(universe) { angularVelocity = rotateRate; } } public void rotateStop() { synchronized(universe) { angularVelocity = 0.; } } public void launchMissile() { Point2D.Double p; double r; if (amOutOfControl()) { return; } if ((myMissile != null) && (!myMissile.amOutOfControl())) { return; } myMissile = (SpaceMissile)SpaceObjectRegistry.clone("missile"); copyToLaunch(myMissile); r = radius + myMissile.getRadius() + 1; p = myMissile.getPosition(); p.setLocation(p.getX() + r * Math.cos(angle), p.getY() + r * Math.sin(angle)); universe.addSpaceObject(myMissile); } public void launchMine() { int i; SpaceMine mine; Point2D.Double p; double r; if (amOutOfControl()) { return; } for (i = 0; i < numberOfMines; i++) { if ((myMines[i] == null) || myMines[i].amDead()) { break; } } if (i >= numberOfMines) { return; } mine = (SpaceMine)SpaceObjectRegistry.clone("mine"); myMines[i] = mine; copyToLaunch(mine); r = radius + mine.getRadius() + 1; p = mine.getPosition(); p.setLocation(p.getX() + r * Math.cos(angle + Math.PI), p.getY() + r * Math.sin(angle + Math.PI)); universe.addSpaceObject(mine); } public void restartGame() { universe.restartGame(1); } public void randomizeGame() { universe.restartGame(2); } ////////////////////////////////////////////////////////////////////// // // Overridden methods. public SpaceObject cloneMe() { SpaceShip ship; ship = new SpaceShip(); copyTo(ship); return (ship); } public void startExploding(SpaceObject otherObject) { if ((otherObject != null) && otherObject.amEatenObject() && !otherObject.amExploding()) { return; } super.startExploding(otherObject); } // Missiles are "eaten" by "eating" objects, including ships. public boolean amEatingObject() { return (true); } public void paintTrim(SpaceGraphics g) { double engineAngle = angle + Math.PI; // Draw engine. g.setColor(trimColor); g.drawLine(displayPosition, radius / 2, engineAngle, radius, engineAngle); } }