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.

236 lines
6.9 KiB

  1. package controller;
  2. import java.awt.Color;
  3. import java.awt.event.KeyEvent;
  4. import playground.*;
  5. import gameobjects.*;
  6. import java.util.*;
  7. import org.apache.logging.log4j.Logger;
  8. import org.apache.logging.log4j.LogManager;
  9. /**
  10. * Controller using key events for up, down, left, right and space (shooting) to control the ego
  11. * object behavior.
  12. */
  13. public class EgoController extends ObjectController {
  14. // either rad is zero or width/height is zero (guaranteed by constructors)
  15. private double rad = 0;
  16. private double width = 0;
  17. private double height = 0;
  18. private Integer pressedKey = null;
  19. private Integer lastPressedKey = null;
  20. private static Logger logger = LogManager.getLogger(EgoController.class);
  21. /**
  22. * constructor that gives the ego controller a radius to stop the ego object when it reaches the level boundaries.
  23. * @param egoRad radius to use as a boundary stop for level borders (usually use the same dimensions as your ego object)
  24. */
  25. public EgoController(double egoRad) {
  26. this.rad = egoRad;
  27. }
  28. /**
  29. * constructor that gives the ego controller a width and height to stop the ego object when it reaches the level boundaries.
  30. * @param width width to use as a boundary stop for level borders (usually use the same dimensions as your ego object)
  31. * @param height height to use as a boundary stop for level borders (usually use the same dimensions as your ego object)
  32. */
  33. public EgoController(double width, double height) {
  34. this.width = width;
  35. this.height = height;
  36. }
  37. /**
  38. * moves ego up by {@link SpaceInvadersLevel#EGOSPEED}.
  39. * @param kc KeyEvent to process
  40. * @param ego the ego object
  41. */
  42. public void onUp(KeyEvent kc, GameObject ego) {
  43. ego.setVX(0.0);
  44. ego.setVY(-SpaceInvadersLevel.EGOSPEED);
  45. }
  46. /**
  47. * moves ego down by {@link SpaceInvadersLevel#EGOSPEED}.
  48. * @param kc KeyEvent to process
  49. * @param ego the ego object
  50. */
  51. public void onDown(KeyEvent kc, GameObject ego) {
  52. ego.setVX(0.0);
  53. ego.setVY(SpaceInvadersLevel.EGOSPEED);
  54. }
  55. /**
  56. * moves ego left by {@link SpaceInvadersLevel#EGOSPEED}.
  57. * @param kc KeyEvent to process
  58. * @param ego the ego object
  59. */
  60. public void onLeft(KeyEvent kc, GameObject ego) {
  61. ego.setVY(0.0);
  62. ego.setVX(-SpaceInvadersLevel.EGOSPEED);
  63. }
  64. /**
  65. * moves ego right by {@link SpaceInvadersLevel#EGOSPEED}.
  66. * @param kc KeyEvent to process
  67. * @param ego the ego object
  68. */
  69. public void onRight(KeyEvent kc, GameObject ego) {
  70. ego.setVY(0.0);
  71. ego.setVX(SpaceInvadersLevel.EGOSPEED);
  72. }
  73. public void onStop(KeyEvent kc, GameObject ego) {
  74. ego.setVY(0.0);
  75. ego.setVX(0.0);
  76. ego.setComponentProperty("controller", "setDummy", "NEW");
  77. ego.setComponentProperty("controller", "setDummy2", "XXX");
  78. }
  79. /** checks the position and respects level boundaries and own radius or width/height set on constructor.
  80. *
  81. * @return true if the object reached the boundaries of the level, false otherwise.
  82. */
  83. public boolean stopObject() {
  84. // check whether ego object is at level boundaries
  85. // can use radius (rad) and width or height in one check as either rad or width/height is zero.
  86. int pgSizeX = this.getPlayground().getSizeX();
  87. int pgSizeY = this.getPlayground().getSizeY();
  88. double ts = this.getTimestep();
  89. if (this.getX() + rad + (width/2d) + this.getVX() * ts >= pgSizeX
  90. || this.getX() - rad - (width/2d) + this.getVX() * ts < 0) {
  91. return true;
  92. }
  93. if (this.getY() + rad + (height/2d) + this.getVY() * ts >= pgSizeY
  94. || this.getY() - rad - (height/2d) + this.getVY() * ts < 0) {
  95. return true;
  96. }
  97. return false;
  98. }
  99. /** behavior for shooting on key space. Creates a new shot using {#link SimpleShotController} with a {@link RectObject}.
  100. *
  101. * @param e KeyEvent of the space key
  102. * @param ego EgoObject instance (used to determine position of shot object's start)
  103. */
  104. public void onSpace(KeyEvent e, GameObject ego) {
  105. pressedKey = lastPressedKey;
  106. lastPressedKey = null;
  107. // create unique name for object
  108. // read Flag nextShot read (if not existing already it will be set)
  109. // it will be updated by 1 and saved
  110. Integer nextShot =
  111. (Integer) this.getPlayground().getOrCreateLevelFlag("nextShot", Integer.valueOf(0));
  112. String shotName = "simpleShot" + nextShot++;
  113. this.getPlayground().setLevelFlag("nextShot", nextShot);
  114. SimpleShotController simpleshot = new SimpleShotController();
  115. GameObject ss = new RectObject(shotName, this.getPlayground(), ego.getX(), ego.getY(), 0,
  116. -1. * SpaceInvadersLevel.SHOTSPEED, 4, 12, Color.CYAN).addController(simpleshot);
  117. ss.generateColliders();
  118. this.getPlayground().addObject(ss);
  119. }
  120. /**
  121. * updates position based on key events (mouse currently ignored).
  122. */
  123. public void updateObject() {
  124. logger.trace("Playground inst is"+this.getPlayground()) ;
  125. Stack<KeyEvent> keyEvents = this.getPlayground().getKeyEvents();
  126. GameObject ego = this.gameObject;
  127. while (!keyEvents.isEmpty()) {
  128. KeyEvent e = keyEvents.pop();
  129. boolean pressed = false;
  130. boolean released = true;
  131. int kc = e.getKeyCode();
  132. if (e.paramString().indexOf("PRESSED") >= 0) {
  133. pressed = true;
  134. released = false;
  135. }
  136. /**
  137. * Generelle Idee: Wenn eine Taste gedrckt wird wird sie gespeichert. wenn die zuvor
  138. * gespeicherte Taste wieder losgelassen wird stoppt das Ego-Objekt. Falls vor dem Loslassen
  139. * eine andere Taste gedrckt wird, wird diese gespeichert und die alte vergessen. Dh das
  140. * loslassen der alten Taste stoppt das Objekt nicht. Spezialfall: space, das loslassen von
  141. * space stoppt das Objekt nicht!
  142. */
  143. if (pressed == true) {
  144. lastPressedKey = pressedKey;
  145. pressedKey = kc;
  146. }
  147. /**
  148. * Nur eine losgelassene Taste die auch vorher gedrckt wurde stoppt das Objekt. Eine
  149. * losgelassene Taste die nicht vorher gedrckt wurde bzw vergessen wurde stoppt das Objekt
  150. * nicht
  151. */
  152. if (released == true) {
  153. if (pressedKey != null) {
  154. if (pressedKey.equals(kc)) {
  155. ego.setVX(0);
  156. ego.setVY(0);
  157. pressedKey = null;
  158. }
  159. }
  160. continue;
  161. }
  162. if (kc == KeyEvent.VK_LEFT) {
  163. this.onLeft(e, ego);
  164. }
  165. if (kc == KeyEvent.VK_RIGHT) {
  166. this.onRight(e, ego);
  167. }
  168. if (kc == KeyEvent.VK_UP) {
  169. this.onUp(e, ego);
  170. }
  171. if (kc == KeyEvent.VK_DOWN) {
  172. this.onDown(e, ego);
  173. }
  174. // stop
  175. if (kc == KeyEvent.VK_Z) {
  176. this.onStop(e, ego);
  177. }
  178. // shot
  179. if (kc == KeyEvent.VK_SPACE) {
  180. // space is not registered! Releasing space does not stop the egoobject
  181. this.onSpace(e, ego);
  182. }
  183. }
  184. boolean stop = this.stopObject();
  185. if (stop) {
  186. this.setVX(0);
  187. this.setVY(0);
  188. }
  189. // updateSpeed and position
  190. applySpeedVector();
  191. }
  192. }