Programmierung 2 - Praktikum
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.

678 lines
22 KiB

2 years ago
  1. package playground;
  2. // import utilities.* ;
  3. import java.awt.Color;
  4. import java.awt.Font;
  5. import java.awt.Graphics2D;
  6. import java.awt.Polygon;
  7. import java.awt.RenderingHints;
  8. import java.awt.font.TextAttribute;
  9. import java.awt.image.BufferedImage;
  10. import java.io.*;
  11. import java.text.AttributedString;
  12. import java.util.LinkedList;
  13. import controller.EnemyController;
  14. import controller.FallingStarController;
  15. import controller.LimitedTimeController;
  16. import controller.ObjectController;
  17. import controller.EgoController;
  18. import controller.CollisionAwareEgoController;
  19. import gameobjects.AnimatedGameobject;
  20. import gameobjects.FallingStar;
  21. import gameobjects.GameObject;
  22. import gameobjects.EgoObject;
  23. import gameobjects.TextObject;
  24. import org.apache.logging.log4j.Logger;
  25. import org.apache.logging.log4j.LogManager;
  26. /**
  27. * Class that realizes all the game logic of a very simple game level. The level contains for now
  28. * only two objects that are {@link GameObject} subclasses: {@link FallingStar} and
  29. * {@link EgoObject}. Functions performed by this class are:
  30. * <ul>
  31. * <li>initially set up the level, spawn all object etc., in method {@link #prepareLevel}
  32. * <li>React to game events in {@link #actionIfEgoCollidesWithCollect(GameObject, GameObject)} ,
  33. * {@link #actionIfEgoCollidesWithEnemy(GameObject, GameObject)}, etc.
  34. * <li>define basic object movement rules for all objects in the level in the various
  35. * ObjectController subclasses: {@link EgoController} and {@link FallingStarController}.
  36. * </ul>
  37. */
  38. public class SpaceInvadersLevel extends Playground {
  39. public static final double SHOTSPEED = 175;
  40. public static final double EGOSPEED = 220;
  41. protected static final int LEVEL2STARS = 80;
  42. protected static final double BONUS_DURATION = 1.;
  43. protected static final double ENEMYSPEEDX = 60;
  44. protected static final double ENEMYSPEEDY = 40;
  45. protected static final double ENEMYSCALE = 1.0;
  46. protected static final double ENEMYSHOTSPEED = 75;
  47. protected static final int NRSHARDS = 50;
  48. protected static final double EXPL_DURATION = 1.;
  49. protected static final int NR_ENEMIES = 30;
  50. protected static final int NR_COLLECT = 5;
  51. protected static final Color EXPL_COLOR = Color.RED;
  52. protected static final double SHARDSPEED = 200;
  53. protected static final double STARSPEED = 100;
  54. protected static final double STARTTEXTSPEED = 75;
  55. protected static final double STARTPERIOD = 5.;
  56. protected static final double DYING_INTERVAL = 2.0;
  57. protected static final int CANVASX = 700;
  58. protected static final int CANVASY = 700;
  59. protected static final double EGORAD = 15;
  60. protected static final double LEVEL_INIT_TIME = 1.0;
  61. protected int nextShot = 0;
  62. protected boolean lost = false;
  63. protected boolean doneLevel = false;
  64. protected double starttime = 0;
  65. protected File smash = null;
  66. protected File laser = null;
  67. protected BufferedImage[] alienImage = null;
  68. protected double[] alienshowTime = null;
  69. protected BufferedImage[] heartImage = null;
  70. protected double[] heartshowTime = null;
  71. protected Animation enemyAnim = null;
  72. protected Animation heartAnim = null;
  73. private static Logger logger = LogManager.getLogger(SpaceInvadersLevel.class);
  74. public SpaceInvadersLevel() {
  75. super();
  76. this.canvasX = this.preferredSizeX();
  77. this.canvasY = this.preferredSizeY();
  78. }
  79. /**
  80. * initially sets up the level. Not called by user interaction, but called every time a layer is
  81. * restarted from scratch. So make sure that this is possible. Here, resources are loaded only
  82. * once even if method is called several times.
  83. *
  84. * @param id String identifies level.
  85. */
  86. @Override
  87. public void prepareLevel(String id) {
  88. logger.info("PREPARE");
  89. reset();
  90. this.doneLevel = false;
  91. this.lost = false;
  92. resetFlags(FLAGS_LEVEL);
  93. // set up flags that some objects rely on
  94. setLevelFlag("delete", new LinkedList<String>());
  95. setLevelFlag("replace", new LinkedList<String>());
  96. getOrCreateGlobalFlag("points", Integer.valueOf(0));
  97. setLevelFlag("enemyShotCounter", Integer.valueOf(0));
  98. setLevelFlag("gameStatus", "start");
  99. setLevelFlag("detailedStatus", "std");
  100. getOrCreateGlobalFlag("egoLives", Integer.valueOf(5));
  101. setLevelFlag("dying", Double.valueOf(-1));
  102. // start time measure
  103. this.starttime = this.getGameTime();
  104. // music load
  105. if (this.smash == null) {
  106. this.smash = new File("./audio/smash.wav");
  107. }
  108. if (this.laser == null) {
  109. this.laser = new File("./audio/laser.wav");
  110. }
  111. // ----- Alien
  112. if (this.enemyAnim == null) {
  113. String dateiName = "./video/sweetAlien.txt";
  114. this.enemyAnim = new Animation(dateiName);
  115. }
  116. // -----Heart
  117. if (this.heartAnim == null) {
  118. String heartName = "./video/heart.txt";
  119. this.heartAnim = new Animation(heartName);
  120. }
  121. // load highscore and update
  122. HighscoreManager dh = new HighscoreManager();
  123. int alltimeHighscore = dh.readHSFromFile();
  124. setGlobalFlag("highscore", alltimeHighscore);
  125. logger.info("HIGHSCORE" + alltimeHighscore);
  126. }
  127. /**
  128. * (re)draws the level but NOT the objects, they draw themselves. Called by the main game loop.
  129. * This method mainly draws the background and the scoreboard.
  130. *
  131. * @param g2 Graphics2D object that can, and should be, draw on.
  132. */
  133. @Override
  134. public void redrawLevel(Graphics2D g2) {
  135. // Set anti-alias!
  136. g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
  137. // Set anti-alias for text
  138. g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
  139. RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
  140. // fill background with black
  141. int[] x = {0, canvasX, canvasX, 0};
  142. int[] y = {0, 0, canvasY, canvasY};
  143. Polygon bg = new Polygon(x, y, 4);
  144. g2.setColor(Color.BLACK);
  145. g2.fill(bg);
  146. // draw score in upper left part of playground
  147. Integer pts = (Integer) getGlobalFlag("points");
  148. Font drawFont = new Font("SansSerif", Font.PLAIN, 20);
  149. AttributedString as = new AttributedString("Points: " + pts);
  150. as.addAttribute(TextAttribute.FONT, drawFont);
  151. as.addAttribute(TextAttribute.FOREGROUND, Color.yellow);
  152. g2.drawString(as.getIterator(), 10, 20);
  153. // draw lives counter in upper left part of playground
  154. Integer lives = (Integer) getGlobalFlag("egoLives");
  155. Font drawFont2 = new Font("SansSerif", Font.PLAIN, 20);
  156. AttributedString as2 = new AttributedString("Lives: " + lives);
  157. as2.addAttribute(TextAttribute.FONT, drawFont2);
  158. as2.addAttribute(TextAttribute.FOREGROUND, Color.yellow);
  159. g2.drawString(as2.getIterator(), canvasX - 100, 20);
  160. // draw highscore in left part of playground under score
  161. Integer highscore = (Integer) getGlobalFlag("highscore");
  162. Font drawFont3 = new Font("SansSerif", Font.PLAIN, 20);
  163. AttributedString as3 = new AttributedString("Highscore: " + highscore);
  164. as3.addAttribute(TextAttribute.FONT, drawFont3);
  165. as3.addAttribute(TextAttribute.FOREGROUND, Color.yellow);
  166. g2.drawString(as3.getIterator(), 10, 40);
  167. if (isPaused()) {
  168. Font drawFont4 = new Font("SansSerif", Font.PLAIN, 50);
  169. AttributedString as4 = new AttributedString("Das Spiel wurde pausiert.");
  170. as4.addAttribute(TextAttribute.FONT, drawFont4);
  171. as4.addAttribute(TextAttribute.FOREGROUND, Color.red);
  172. g2.drawString(as4.getIterator(), 30, 400);
  173. }
  174. }
  175. /**
  176. * applies the logic of the level: For now, this is just about deleting shots that are leaving the
  177. * screen and calling methods 'actionIf..' in case objects collide.
  178. *
  179. */
  180. @Override
  181. public void applyGameLogic() {
  182. double gameTime = this.getGameTime();
  183. String gameStatus = (String) getLevelFlag("gameStatus");
  184. String subStatus = (String) getLevelFlag("detailedStatus");
  185. if (gameStatus.equals("start") == true) {
  186. setupInitialState();
  187. } else if (gameStatus.equals("starting") == true) {
  188. if ((gameTime - starttime) > LEVEL_INIT_TIME) {
  189. setLevelFlag("gameStatus", "init");
  190. }
  191. } else if (gameStatus.equals("init") == true) {
  192. this.createEnemies();
  193. this.createCollectables();
  194. setLevelFlag("gameStatus", "playing");
  195. } else if (gameStatus.equals("playing") == true) {
  196. GameObject s = this.getObject("ego");
  197. if (subStatus.equals("std")) {
  198. // check for collisions of enemy and shots, reuse shots list from before..
  199. LinkedList<GameObject> enemies = collectObjects("enemy", false);
  200. // check whether all enemies have been destroyed or escaped
  201. if (enemies.size() == 0) {
  202. HighscoreManager hsm = new HighscoreManager();
  203. HighscoreManager.writeHSToFile((Integer) Playground.getGlobalFlag("points"),
  204. (Integer) Playground.getGlobalFlag("highscore"));
  205. this.doneLevel = true;
  206. logger.info("no enemies left, level done.");
  207. }
  208. // loop over enemies to check for collisions or suchlike ...
  209. LinkedList<GameObject> shots = collectObjects("simpleShot", true);
  210. for (GameObject e : enemies) {
  211. // if ego collides with enemy..
  212. if (s.collisionDetection(e)) {
  213. actionIfEgoCollidesWithEnemy(e, s);
  214. }
  215. // if shot collides with enemy
  216. for (GameObject shot : shots) {
  217. if (e.collisionDetection(shot)) {
  218. actionIfEnemyIsHit(e, shot);
  219. }
  220. }
  221. }
  222. // collecting hearts
  223. LinkedList<GameObject> collects = collectObjects("collect", false);
  224. for (GameObject c : collects) {
  225. if (s.collisionDetection(c)) {
  226. actionIfEgoCollidesWithCollect(c, s);
  227. }
  228. }
  229. // loop over enemies and, with a certain probability, launch an enemy shot for each one
  230. for (GameObject e : enemies) {
  231. createEnemyShot(e);
  232. }
  233. // check for collisions between ego object and enemy shots
  234. LinkedList<GameObject> eshots = collectObjects("enmyShot", true);
  235. for (GameObject eshot : eshots) {
  236. if (s.collisionDetection(eshot)) {
  237. logger.trace("COLLISION" + eshot.scol.get(0) + "/" + s.scol.get(0));
  238. actionIfEgoObjectIsHit(eshot, s);
  239. }
  240. }
  241. } // if substatus..
  242. else if (subStatus.equals("dying")) {
  243. Double t0 = (Double) getLevelFlag("t0");
  244. if (gameTime - t0 > DYING_INTERVAL) {
  245. LinkedList<GameObject> enemies = collectObjects("enemy", false);
  246. setLevelFlag("detailedStatus", "std");
  247. s.setActive(true);
  248. for (GameObject e : enemies) {
  249. logger.trace("activating" + e.getId());
  250. e.setActive(true);
  251. }
  252. }
  253. }
  254. } // if (gameStatus == "playing")
  255. }
  256. public boolean gameOver() {
  257. return lost;
  258. }
  259. public boolean levelFinished() {
  260. return doneLevel;
  261. }
  262. /**
  263. * calculates and returns the preferred size of the level (in pixel) for X-direction
  264. */
  265. public int preferredSizeX() {
  266. return CANVASX;
  267. }
  268. /**
  269. * calculates and returns the preferred size of the level (in pixel) for Y-direction
  270. */
  271. public int preferredSizeY() {
  272. return CANVASY;
  273. }
  274. /** Adds ego object and stars and displays startup message. Is called from applyGameLogic */
  275. protected void setupInitialState() {
  276. double gameTime = this.getGameTime();
  277. setLevelFlag("gameStatus", "starting");
  278. this.createStars();
  279. // set up ego object
  280. this.createEgoObject();
  281. // add text object to playground
  282. ObjectController ctrl = new LimitedTimeController(gameTime, 3.);
  283. GameObject readyText = new TextObject("ready?", this, getSizeX() / 2, 0, 0, 100,
  284. this.getStartupMessage(), 50, Color.RED).addController(ctrl);
  285. addObject(readyText);
  286. }
  287. /**
  288. * simply returns the text that should be displayed at level start
  289. *
  290. * @return a string that is displayed at start. Should be not longer than 30 characters.
  291. */
  292. protected String getStartupMessage() {
  293. return "Get ready for level X!";
  294. }
  295. /**
  296. * returns a number representing the speed of an enemy object in X direction (pixels/second)
  297. *
  298. * @return a positive value
  299. */
  300. protected double calcEnemySpeedX() {
  301. return SpaceInvadersLevel.ENEMYSPEEDX;
  302. }
  303. /**
  304. * returns a number representing the speed of an enemy object in Y direction (pixels/second)
  305. *
  306. * @return a positive value
  307. */
  308. protected double calcEnemySpeedY() {
  309. return SpaceInvadersLevel.ENEMYSPEEDY;
  310. }
  311. /**
  312. * returns the maximum number of enemy instances (which are created at level start)
  313. *
  314. * @return a positive value
  315. */
  316. protected int calcNrEnemies() {
  317. return SpaceInvadersLevel.NR_ENEMIES;
  318. }
  319. /**
  320. * returns the maximum number of collectables' instances (which are created at level start)
  321. *
  322. * @return a positive value
  323. */
  324. protected int calcNrCollect() {
  325. return SpaceInvadersLevel.NR_COLLECT;
  326. }
  327. protected GameObject createEnemyShotObject(GameObject parentObject, String name,
  328. ObjectController limitedTimeController) {
  329. GameObject to =
  330. new TextObject(name, this, parentObject.getX(), parentObject.getY(), 0, ENEMYSHOTSPEED, "I",
  331. 20, Color.YELLOW).generateColliders().addController(limitedTimeController);
  332. /*
  333. * // also possible: GameObject to = new RectObject(name, this, parentObject.getX(),
  334. * parentObject.getY(), 0, ENEMYSHOTSPEED, 4, 20,
  335. * Color.YELLOW).addController(limitedTimeController) ; to.generateColliders();
  336. */
  337. return to;
  338. }
  339. protected void createEnemyShot(GameObject e) {
  340. double gameTime = this.getGameTime();
  341. double PROB = calcEnemyShotProb();
  342. double diceThrow = Math.random();
  343. Integer nrEnemyShots = (Integer) (getLevelFlag("enemyShotCounter"));
  344. if (diceThrow < PROB) {
  345. setLevelFlag("enemyShotCounter", Integer.valueOf(++nrEnemyShots));
  346. LimitedTimeController limitedTimeController = new LimitedTimeController(gameTime, 10.);
  347. GameObject textObject =
  348. createEnemyShotObject(e, "enmyShot" + nrEnemyShots, limitedTimeController);
  349. addObject(textObject);
  350. }
  351. }
  352. /**
  353. * calculates and returns the probability that an enemy shots. Used by
  354. * {@link SpaceInvadersLevel#createEnemyShot(GameObject)}.
  355. *
  356. * @return a positive value between 0 (no chance) to 1 (for sure).
  357. */
  358. double calcEnemyShotProb() {
  359. return 0.1 * this.getTimestep();
  360. }
  361. ObjectController createEnemyController() {
  362. return new EnemyController();
  363. }
  364. GameObject createSingleEnemy(String name, double x_enemy, double y_enemy, double vx_enemy,
  365. double vy_enemy, ObjectController enemyController, double gameTime) {
  366. GameObject tmp =
  367. new AnimatedGameobject(name, this, x_enemy, y_enemy, vx_enemy, vy_enemy, ENEMYSCALE,
  368. this.enemyAnim, gameTime, "loop").addController(enemyController).generateColliders();
  369. return tmp;
  370. }
  371. GameObject createSingleCollect(String name) {
  372. double gameTime = this.getGameTime();
  373. double cspeedy = 20.;
  374. double x_collect = Math.random() * this.canvasX;
  375. double y_collect = Math.random() * this.canvasY / 3;
  376. double vx_collect = 2 * (Math.random() - 0.5) * 0;
  377. double vy_collect = Math.random() * cspeedy;
  378. GameObject tmp = new AnimatedGameobject(name, this, x_collect, y_collect, vx_collect,
  379. vy_collect, 0.3, this.heartAnim, gameTime, "loop").generateColliders()
  380. .addController(new EnemyController());
  381. return tmp;
  382. }
  383. void createEnemies() {
  384. // create enemies
  385. double gameTime = this.getGameTime();
  386. double speedx = this.calcEnemySpeedX();
  387. double speedy = this.calcEnemySpeedY();
  388. for (int i = 0; i < this.calcNrEnemies(); i++) {
  389. double x_enemy = Math.random() * this.canvasX;
  390. double y_enemy = Math.random() * this.canvasY / 3;
  391. double vx_enemy = 2 * (Math.random() - 0.5) * speedx;
  392. double vy_enemy = Math.random() * speedy;
  393. ObjectController enemyController = createEnemyController();
  394. GameObject enemy = createSingleEnemy("enemy" + i, x_enemy, y_enemy, vx_enemy, vy_enemy,
  395. enemyController, gameTime);
  396. addObject(enemy);
  397. }
  398. }
  399. void createCollectables() {
  400. double gameTime = this.getGameTime();
  401. // create collectables
  402. for (int i = 0; i < this.calcNrCollect(); i++) {
  403. GameObject collect = createSingleCollect("collect" + i);
  404. addObject(collect);
  405. }
  406. }
  407. void createEgoObject() {
  408. // add ego to playground at lower bottom
  409. EgoController egoController =
  410. new CollisionAwareEgoController(SpaceInvadersLevel.EGORAD, this.laser);
  411. GameObject ego = new EgoObject("ego", this, canvasX / 2, canvasY - (EGORAD * 2), 0, 0, EGORAD)
  412. .addController(egoController).generateColliders();
  413. addObject(ego);
  414. }
  415. void createStars() {
  416. // add stars to playground
  417. for (int i = 1; i <= LEVEL2STARS; i++) {
  418. FallingStarController fsc = new FallingStarController();
  419. GameObject star = new FallingStar("star" + i, this, Math.random() * canvasX,
  420. Math.random() * 15, 0.0, Math.random() * STARSPEED, Color.WHITE, 1.).addController(fsc);
  421. addObject(star);
  422. }
  423. }
  424. void createExplosion(double gameTime, GameObject e, String basename, double interval,
  425. Color color) {
  426. // spawn a cloud of exploded shards
  427. for (int i = 0; i < NRSHARDS; i++) {
  428. double vx = 2 * (Math.random() - 0.5) * SHARDSPEED + e.getVX();
  429. double vy = 2 * (Math.random() - 0.5) * SHARDSPEED + e.getVY();
  430. addObject(
  431. new FallingStar("shard" + gameTime + "/" + i, this, e.getX(), e.getY(), vx, vy, color, 2)
  432. .addController(new LimitedTimeController(gameTime, interval)));
  433. }
  434. }
  435. /**
  436. * implements game behavior if an enemy object is hit by a players' shot. It creates an explosion
  437. * effect, plays a sound and adds 200 points to the current score (and it removes the enemy object
  438. * and the shot object).
  439. *
  440. * @param e enemy which was hit
  441. * @param shot the shot object that hit the enemy
  442. */
  443. void actionIfEnemyIsHit(GameObject e, GameObject shot) {
  444. double gameTime = this.getGameTime();
  445. createExplosion(gameTime, e, "shard", DYING_INTERVAL, Color.RED);
  446. Music.music(smash);
  447. // delete enemy
  448. deleteObject(e.getId());
  449. // delete shot
  450. deleteObject(shot.getId());
  451. // add to points counter
  452. Integer pts = (Integer) getGlobalFlag("points");
  453. setGlobalFlag("points", pts + 200);
  454. }
  455. /**
  456. * implements game behavior if ego object of player touches a collectable
  457. * {@link gameobjects.GameObject }. Here it adds one extra life and displays a text for a limited
  458. * time on screen "Extra life!!". The duration is set in constant
  459. * {@link SpaceInvadersLevel#EXPL_DURATION}.
  460. *
  461. *
  462. * @param collect item touched by ego
  463. * @param ego the players ego object
  464. */
  465. void actionIfEgoCollidesWithCollect(GameObject collect, GameObject ego) {
  466. double gameTime = this.getGameTime();
  467. if (this.getObject("bonustext") == null) {
  468. // spawn a bonus points object
  469. double vx = 2 * (Math.random() - 0.5) * SHARDSPEED + collect.getVX();
  470. double vy = 2 * (Math.random() - 0.5) * SHARDSPEED + collect.getVY();
  471. LimitedTimeController bonusTextController =
  472. new LimitedTimeController(gameTime, SpaceInvadersLevel.EXPL_DURATION);
  473. GameObject bonusText = new TextObject("bonustext", this, collect.getX(), collect.getY(), vx,
  474. vy, "Extra life!!", 20, Color.YELLOW).addController(bonusTextController);
  475. addObject(bonusText);
  476. // delete collect
  477. deleteObject(collect.getId());
  478. // add to points counter
  479. Integer lives = (Integer) getGlobalFlag("egoLives");
  480. lives++;
  481. setGlobalFlag("egoLives", lives);
  482. }
  483. }
  484. /**
  485. * implements behaviour of game when ego object is touching an enemy. It displays a text "AUAA!!"
  486. * for a certain time on the game screen. Time span is defined as constant in
  487. * {@link SpaceInvadersLevel#BONUS_DURATION } .
  488. *
  489. * @param enemy the enemy that was hit
  490. * @param ego the ego object of the player
  491. */
  492. void actionIfEgoCollidesWithEnemy(GameObject enemy, GameObject ego) {
  493. /**
  494. * set temporary text over ego. This object lives only for a short time. While it lives, further
  495. * collisions are ignored. Otherwise a single collision would result in a lot of deducted
  496. * points...
  497. */
  498. double gameTime = this.getGameTime();
  499. GameObject auaObj = this.getObject("AUA-EGO");
  500. if (auaObj == null) {
  501. addObject(new TextObject("AUA-EGO", this, ego.getX(), ego.getY() - 20, ego.getVX(),
  502. ego.getVY(), "AUAA!!", 10, Color.RED)
  503. .addController(new LimitedTimeController(gameTime, BONUS_DURATION)));
  504. // deduct points
  505. Integer pts = (Integer) getGlobalFlag("points");
  506. setGlobalFlag("points", pts - 500);
  507. }
  508. }
  509. /**
  510. * implements what happens if the eog object of player is hit by a shot. It removes the shot from
  511. * screen, reduces lives by 1, removes the ego and end current playing.
  512. *
  513. * @param eshot the shot object that hits the ego
  514. * @param ego the ego object of the player
  515. */
  516. void actionIfEgoObjectIsHit(GameObject eshot, GameObject ego) {
  517. logger.debug("collision of " + eshot.getId() + " and " + ego.getId());
  518. double gameTime = this.getGameTime();
  519. this.deleteObject(eshot.getId());
  520. Integer oldLives = (Integer) getGlobalFlag("egoLives");
  521. int newLives = oldLives - 1;
  522. setGlobalFlag("egoLives", newLives);
  523. logger.debug("set egoLives to " + newLives + " (was " + oldLives + ")");
  524. if (newLives <= 0) {
  525. lost = true;
  526. HighscoreManager.writeHSToFile((Integer) Playground.getGlobalFlag("points"),
  527. (Integer) Playground.getGlobalFlag("highscore"));
  528. }
  529. LinkedList<GameObject> eshots = collectObjects("enmyShot", true);
  530. for (GameObject _eshot : eshots) {
  531. deleteObject(_eshot.getId());
  532. }
  533. setLevelFlag("detailedStatus", "dying");
  534. setLevelFlag("t0", gameTime);
  535. ego.setActive(false);
  536. createExplosion(gameTime, ego, "egoexp", DYING_INTERVAL, Color.WHITE);
  537. LinkedList<GameObject> enemies = collectObjects("enemy", false);
  538. for (GameObject enemy : enemies) {
  539. enemy.setY(0);
  540. enemy.setActive(false);
  541. }
  542. }
  543. }