You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Game.java 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. package spacewar;
  2. import java.awt.Dimension;
  3. /**
  4. * The Game class is the root of the spacewar game. To start a spacewar
  5. * game, you can either call the main method, or instantiate this class
  6. * directly.
  7. *
  8. * Synchronization is done by the GameSynchronization aspect.
  9. */
  10. public class Game extends Thread {
  11. /**
  12. * To run the game from top level, simply say Java Game, as usual. Passing
  13. * an argument makes the game run in demo mode. Without an argument it runs
  14. * in the normal player mode.
  15. */
  16. public static void main(String[] args) {
  17. if ( args.length == 0 )
  18. new Game("1").run();
  19. new Game(args[0]).run();
  20. }
  21. private Timer timer;
  22. private EnergyPacketProducer ePP;
  23. private Registry registry;
  24. private Pilot pilot1, pilot2;
  25. private Dimension screenSize = new Dimension(500, 500);
  26. Registry getRegistry() { return registry; }
  27. Pilot getPilot1() { return pilot1; }
  28. Pilot getPilot2() { return pilot2; }
  29. int getWidth() { return screenSize.width; }
  30. int getHeight() { return screenSize.height; }
  31. /**
  32. * To run the game, simply instantiate this class. It runs in its own
  33. * thread. You can instantiate multiple games at once. For the time being
  34. * the only way to end the game is to exit from the Java VM.
  35. *
  36. * @param mode Controls whether the game runs in demo mode or not. True
  37. * means it is a demo, false means it runs in normal 2 player mode.
  38. */
  39. public Game(String mode) {
  40. timer = new Timer(this);
  41. ePP = new EnergyPacketProducer(this);
  42. registry = new Registry(this);
  43. }
  44. public void run() {
  45. timer.start();
  46. ePP.start();
  47. while(true) {
  48. try {
  49. newRobot(3);
  50. Thread.sleep(15000);
  51. }
  52. catch (InterruptedException e) {}
  53. }
  54. }
  55. /*
  56. * These are the menu commands.
  57. */
  58. void addRobot() {
  59. newRobot(3);
  60. }
  61. void resetShips() {
  62. Ship[] ships = registry.getShips();
  63. for (int i = 0; i < ships.length; i++) {
  64. Ship ship = ships[i];
  65. Pilot pilot = ship.getPilot();
  66. newShip(pilot);
  67. }
  68. }
  69. void quit() {
  70. System.exit(0);
  71. }
  72. void error(Object o) {
  73. System.err.println(o);
  74. }
  75. /*
  76. * These three methods are the ONLY ways to make a Player a Robot or a Ship.
  77. * The structural invariant is that there should be no calls to new of one
  78. * of these three classes outside these three methods.
  79. */
  80. Player newPlayer(int number) {
  81. Player player = new Player(this, number);
  82. newShip(player);
  83. return player;
  84. }
  85. Robot newRobot(int number) {
  86. Robot robot = new Robot(this, number);
  87. newShip(robot);
  88. robot.start();
  89. return robot;
  90. }
  91. Ship newShip(Pilot pilot) {
  92. //
  93. // If there is an old ship (we're doing a reset), then remove it from
  94. // the registry.
  95. //
  96. Ship oldShip = pilot.getShip();
  97. if (! (oldShip == null))
  98. oldShip.die();
  99. Ship newShip = new Ship(this,
  100. Math.random() * getWidth(),
  101. Math.random() * getHeight(),
  102. Math.random() * Math.PI * 2);
  103. pilot.setShip(newShip);
  104. newShip.setPilot(pilot);
  105. return newShip;
  106. }
  107. void clockTick() {
  108. registry.clockTick();
  109. handleCollisions();
  110. }
  111. // collision detection
  112. void handleCollisions() {
  113. SpaceObject[] objects = registry.getObjects();
  114. SpaceObject objI, objJ;
  115. for (int i = 0; i < objects.length; i++) {
  116. objI = objects[i];
  117. for (int j = i + 1; j < objects.length; j++) {
  118. objJ = objects[j];
  119. if (objI instanceof Bullet && objJ instanceof Bullet)
  120. continue;
  121. if (isCollision(objI, objJ)) {
  122. if (objI instanceof Ship && objJ instanceof Ship)
  123. Ship.bounce((Ship)(objI), (Ship)(objJ));
  124. else {
  125. objI.handleCollision(objJ);
  126. objJ.handleCollision(objI);
  127. }
  128. }
  129. }
  130. }
  131. }
  132. /*
  133. * Is the distance between the two centers less than the sum of the two
  134. * radii. This is a cheap and dirty (i.e. wrong) implementation of this.
  135. */
  136. static boolean isCollision(SpaceObject a, SpaceObject b) {
  137. return (Math.abs(a.getXPos() - b.getXPos()) +
  138. Math.abs(a.getYPos() - b.getYPos())) <
  139. (a.getSize()/2 + b.getSize()/2);
  140. }
  141. }