University stuff.
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.

MinOppgave5.java 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907
  1. import javax.swing.JPanel;
  2. import javax.swing.JFrame;
  3. import javax.swing.JButton;
  4. import javax.sound.sampled.AudioInputStream;
  5. import javax.sound.sampled.AudioSystem;
  6. import javax.sound.sampled.AudioFormat;
  7. import javax.sound.sampled.DataLine;
  8. import javax.sound.sampled.Clip;
  9. import java.awt.event.KeyListener;
  10. import java.awt.event.KeyEvent;
  11. import java.awt.event.WindowEvent;
  12. import java.awt.Graphics;
  13. import java.awt.Graphics2D;
  14. import java.awt.Color;
  15. import java.awt.Font;
  16. import java.awt.FontMetrics;
  17. import java.awt.BasicStroke;
  18. import java.awt.geom.Rectangle2D;
  19. import java.util.ArrayList;
  20. import java.util.Scanner;
  21. import java.util.HashMap;
  22. import java.util.Date;
  23. import java.io.File;
  24. import java.io.FileNotFoundException;
  25. import java.lang.Thread;
  26. class Key {
  27. static int LEFT = 65;
  28. static int RIGHT = 68;
  29. static int JUMP = 32;
  30. static int RESTART = 82;
  31. }
  32. class GraphicsUtils {
  33. public static void boxShadow(Graphics2D gfx, int x, int y, int width, int height) {
  34. Color c = new Color(0, 0, 0, 20);
  35. for (int i = 40; i >0; i -= 1) {
  36. gfx.setColor(c);
  37. gfx.fillRect(
  38. x - i,
  39. y - i,
  40. width + (i * 2),
  41. height + (i * 2)
  42. );
  43. }
  44. }
  45. public static void drawDoneMessage(Graphics2D gfx, Game.State state, JFrame window) {
  46. Color textColor = null;
  47. String str = "";
  48. if (state == Game.State.WON) {
  49. textColor = Color.GREEN;
  50. str = "Congratulations! You won!";
  51. } else if (state == Game.State.LOST) {
  52. textColor = Color.RED;
  53. str = "You lost!";
  54. }
  55. gfx.setFont(new Font("Serif", Font.PLAIN, 32));
  56. FontMetrics metrics = gfx.getFontMetrics();
  57. Rectangle2D bounds = metrics.getStringBounds(str, gfx);
  58. GraphicsUtils.boxShadow(
  59. gfx,
  60. (window.getWidth() / 2) - ((int)bounds.getWidth() / 2) - 5,
  61. window.getHeight() / 2 - (int)bounds.getHeight() - 40,
  62. (int)bounds.getWidth() + 10,
  63. (int)bounds.getHeight() + 10
  64. );
  65. gfx.setColor(textColor);
  66. gfx.drawString(
  67. str,
  68. (window.getWidth() / 2) - ((int)bounds.getWidth() / 2),
  69. (window.getHeight() / 2) - 40
  70. );
  71. gfx.setFont(new Font("Serif", Font.PLAIN, 20));
  72. gfx.setColor(Color.BLACK);
  73. gfx.drawString(
  74. "Press R to play again.",
  75. (window.getWidth() / 2) - ((int)bounds.getWidth() / 2),
  76. (window.getHeight() / 2) + 60
  77. );
  78. if (Coin.totalCoins != 0) {
  79. gfx.drawString(
  80. "you got "+(Coin.totalCoins - Coin.curCoins)+"/"+(Coin.totalCoins)+" coins.",
  81. (window.getWidth() / 2) - ((int)bounds.getWidth() / 2),
  82. (window.getHeight() / 2) + 90
  83. );
  84. }
  85. }
  86. }
  87. enum Side {
  88. LEFT,
  89. RIGHT,
  90. TOP,
  91. BOTTOM
  92. }
  93. class Vec2 {
  94. public double x;
  95. public double y;
  96. Vec2(double x, double y) {
  97. this.x = x;
  98. this.y = y;
  99. }
  100. public Vec2 clone() {
  101. return new Vec2(x, y);
  102. }
  103. public Vec2 scale(double n) {
  104. x *= n;
  105. y *= n;
  106. return this;
  107. }
  108. public Vec2 set(Vec2 vec) {
  109. return set(vec.x, vec.y);
  110. }
  111. public Vec2 set(double ax, double ay) {
  112. x = ax;
  113. y = ay;
  114. return this;
  115. }
  116. public Vec2 add(Vec2 vec) {
  117. return add(vec.x, vec.y);
  118. }
  119. public Vec2 add(double ax, double ay) {
  120. x += ax;
  121. y += ay;
  122. return this;
  123. }
  124. public String identify() {
  125. return "Vec2, x: "+x+", y: "+y;
  126. }
  127. }
  128. class Entity {
  129. protected double mass;
  130. private Vec2 force;
  131. private boolean shouldBounceX;
  132. private boolean shouldBounceY;
  133. private double bounceForceX;
  134. private Vec2 bounceForce;
  135. public Vec2 vel;
  136. public Vec2 pos;
  137. public int width;
  138. public int height;
  139. public int lastDTime = 0;
  140. public boolean dead = false;;
  141. public Game game;
  142. Entity(int x, int y, int w, int h) {
  143. pos = new Vec2(x, y);
  144. width = w;
  145. height = h;
  146. mass = width * height;
  147. bounceForce = new Vec2(0, 0);
  148. vel = new Vec2(0, 0);
  149. force = new Vec2(0, 0);
  150. }
  151. public void bounceX(double n) {
  152. bounceX();
  153. bounceForce.x += n;
  154. }
  155. public void bounceX() {
  156. shouldBounceX = true;
  157. }
  158. public void bounceY(double n) {
  159. bounceY();
  160. bounceForce.y += n;
  161. }
  162. public void bounceY() {
  163. shouldBounceY = true;
  164. }
  165. public Vec2 getCenter() {
  166. return new Vec2(pos.x + (width * 0.5), pos.y + (height * 0.5));
  167. }
  168. //Apply force; move for an arbitrary number of frames (e.g movement)
  169. public void force(Vec2 vec) {
  170. force.add(vec);
  171. }
  172. //Apply impulse; set velocity for one frame (e.g jumping)
  173. public void impulse(Vec2 vec) {
  174. vel.add(vec);
  175. }
  176. //Move, accounting for variable frame rate
  177. public void move(int deltaTime) {
  178. if (shouldBounceX)
  179. vel.x = -vel.x + bounceForce.x;
  180. if (shouldBounceY)
  181. vel.y = -vel.y + bounceForce.y;
  182. shouldBounceX = false;
  183. shouldBounceY = false;
  184. bounceForce.set(0, 0);
  185. lastDTime = deltaTime;
  186. vel.add(force.scale(1/mass).scale(deltaTime));
  187. pos.add(vel.clone().scale(deltaTime));
  188. force.set(0, 0);
  189. }
  190. public boolean shouldUpdate() {
  191. return !(
  192. -game.camera.x > pos.x + width ||
  193. (-game.camera.x + game.window.getWidth()) + 100 < pos.x
  194. );
  195. }
  196. public void init() {};
  197. public void update() {};
  198. public void draw(Graphics2D gfx) {};
  199. public void die() {
  200. dead = true;
  201. }
  202. public Side intersects(Entity e) {
  203. if (!(
  204. pos.x < e.pos.x + e.width && pos.x + width > e.pos.x &&
  205. pos.y < e.pos.y + e.height && pos.y + height > e.pos.y
  206. )) {
  207. return null;
  208. }
  209. if (pos.y + (height / 2) <= e.pos.y + (vel.y + e.vel.y) * lastDTime) {
  210. return Side.TOP;
  211. } else if (pos.y >= e.pos.y + e.height - (-vel.y + e.vel.y) * lastDTime) {
  212. return Side.BOTTOM;
  213. } else if (pos.x + width < e.pos.x + (e.width / 2)) {
  214. return Side.LEFT;
  215. } else {
  216. return Side.RIGHT;
  217. }
  218. }
  219. public String identify() {
  220. return this.getClass().getName()+" at "+pos.x+", "+pos.y;
  221. }
  222. }
  223. class Victory extends Entity {
  224. Victory(int x, int y) {
  225. super(x, y, 30, 30);
  226. }
  227. @Override public void update() {
  228. if (intersects(game.player) != null)
  229. game.win();
  230. }
  231. @Override public void draw(Graphics2D gfx) {
  232. gfx.setColor(new Color(20, 20, 255));
  233. gfx.fillRect(0, 0, width, height);
  234. gfx.setColor(new Color(10, 10, 155));
  235. gfx.drawRect(0, 0, width, height);
  236. }
  237. }
  238. class Coin extends Entity {
  239. public static int totalCoins = 0;
  240. public static int curCoins = 0;
  241. Coin(int x, int y) {
  242. super(x, y, 10, 10);
  243. totalCoins += 1;
  244. curCoins += 1;
  245. }
  246. //We always want to update coins, as we always want to show
  247. //how many coins are left in the upper left
  248. @Override public boolean shouldUpdate() {
  249. return true;
  250. }
  251. @Override public void update() {
  252. if (intersects(game.player) != null) {
  253. curCoins -= 1;
  254. die();
  255. if (totalCoins <= 0)
  256. game.win();
  257. }
  258. }
  259. @Override public void draw(Graphics2D gfx) {
  260. gfx.setColor(new Color(255, 255, 20));
  261. gfx.fillOval(0, 0, width, height);
  262. gfx.setColor(new Color(155, 155, 10));
  263. gfx.setStroke(new BasicStroke(3));
  264. gfx.drawOval(0, 0, width, height);
  265. game.displayText(this, "Coins left: "+curCoins);
  266. }
  267. public static void reset() {
  268. totalCoins = 0;
  269. curCoins = 0;
  270. }
  271. }
  272. class Platform extends Entity {
  273. Platform(int x, int y, int w, int h) {
  274. super(x, y, w, h);
  275. }
  276. @Override public void draw(Graphics2D gfx) {
  277. gfx.drawRect(0, 0, width, height);
  278. }
  279. }
  280. class Player extends Entity {
  281. private final double moveForce = 0.4;
  282. private final double gravityForce = 0.6;
  283. private final double jumpForce = 0.6;
  284. private final double airResistance = 0.5;
  285. private final double friction = 2;
  286. private boolean onGround = false;
  287. Player(int x, int y) {
  288. super(x, y, 20, 20);
  289. }
  290. @Override public void init() {
  291. game.camera.x = -pos.x + (game.window.getWidth() / 2);
  292. game.camera.y = -pos.y + (game.window.getHeight() / 2);
  293. }
  294. @Override public void update() {
  295. //Movement
  296. if (game.isKeyPressed(Key.LEFT))
  297. force(new Vec2(-moveForce, 0));
  298. if (game.isKeyPressed(Key.RIGHT))
  299. force(new Vec2(moveForce, 0));
  300. //Collide with platforms
  301. onGround = false;
  302. for (Entity e: game.entities) {
  303. if (e == this)
  304. continue;
  305. Side side = intersects(e);
  306. if (e instanceof Platform && side != null) {
  307. if (side == Side.TOP) {
  308. onGround = true;
  309. if (vel.y > 0)
  310. vel.y = 0;
  311. pos.y = e.pos.y - height;
  312. } else if (side == Side.LEFT) {
  313. bounceX();
  314. pos.x = e.pos.x - width;;
  315. } else if (side == Side.RIGHT) {
  316. bounceX();
  317. pos.x = e.pos.x + e.width;
  318. } else if (side == Side.BOTTOM) {
  319. bounceY();
  320. }
  321. }
  322. }
  323. //Jump
  324. if (onGround && game.isKeyPressed(Key.JUMP))
  325. impulse(new Vec2(0, -jumpForce));
  326. //Gravity
  327. if (!onGround)
  328. force(new Vec2(0, gravityForce));
  329. //"Friction" (kind of) and air resistance
  330. if (onGround)
  331. force(new Vec2(-vel.x * friction, 0));
  332. else
  333. force(new Vec2(-vel.x * airResistance, 0));
  334. //Update camera
  335. Vec2 dist = new Vec2(
  336. -pos.x + (game.window.getWidth() / 2) - game.camera.x,
  337. -pos.y + (game.window.getHeight() / 2) - game.camera.y
  338. );
  339. game.camera.set(dist.scale(0.1).add(game.camera));
  340. //Die if we fall through the ground
  341. if (pos.y > 300)
  342. die();
  343. }
  344. @Override public void draw(Graphics2D gfx) {
  345. gfx.setColor(new Color(20, 255, 20));
  346. gfx.fillRect(0, 0, width, height);
  347. gfx.setColor(new Color(10, 155, 10));
  348. gfx.drawRect(0, 0, width, height);
  349. }
  350. @Override public void die() {
  351. super.die();
  352. game.lose();
  353. }
  354. }
  355. class Enemy extends Entity {
  356. protected final double moveForce = 0.1;
  357. protected final double gravityForce = 0.4;
  358. protected final double jumpForce = 0.3;
  359. protected final double airResistance = 0.5;
  360. protected final double friction = 2;
  361. protected double resurrectTimeout = 0;
  362. protected boolean onGround = false;
  363. protected boolean collidedTop;
  364. protected boolean collidedBottom;
  365. protected boolean collidedLeft;
  366. protected boolean collidedRight;
  367. private int timesJumped = 0;
  368. protected int maxResurrectTimeout = 5000;
  369. Enemy(int x, int y, int w, int h) {
  370. super(x, y, w, h);
  371. }
  372. @Override public void update() {
  373. //Check if we're on ground
  374. onGround = false;
  375. collidedTop = false;
  376. collidedLeft = false;
  377. collidedRight = false;
  378. collidedBottom = false;
  379. for (Entity e: game.entities) {
  380. if (e == this)
  381. continue;
  382. Side side = intersects(e);
  383. //Collide with platforms
  384. if (e instanceof Platform && side != null) {
  385. collidedTop = true;
  386. if (side == Side.TOP) {
  387. collidedTop = true;
  388. onGround = true;
  389. if (vel.y > 0)
  390. vel.y = 0;
  391. pos.y = e.pos.y - height;
  392. } else if (side == Side.LEFT) {
  393. collidedLeft = true;
  394. vel.x = -vel.x;
  395. pos.x = e.pos.x - width;
  396. } else if (side == Side.RIGHT) {
  397. collidedRight = true;
  398. vel.x = -vel.x;
  399. pos.x = e.pos.x + e.width;
  400. } else if (side == Side.BOTTOM) {
  401. collidedBottom = true;
  402. bounceY();
  403. }
  404. }
  405. }
  406. //Die when a player hits the enemy on top,
  407. //kill the player if it's hit on the sides or bottom
  408. Side side = intersects(game.player);
  409. if (side != null) {
  410. if (side == Side.BOTTOM) {
  411. game.player.bounceY(vel.y);
  412. if (maxResurrectTimeout > 0 && timesJumped < 1) {
  413. resurrectTimeout = maxResurrectTimeout / lastDTime;
  414. onGround = false;
  415. timesJumped += 1;
  416. height = height / 2;
  417. }
  418. else {
  419. die();
  420. }
  421. } else {
  422. if (timesJumped == 0) {
  423. game.player.die();
  424. } else {
  425. vel.x = game.player.vel.x * 2;
  426. }
  427. }
  428. }
  429. //Gravity
  430. if (!onGround)
  431. force(new Vec2(0, gravityForce));
  432. //Friction and air resistance
  433. if (onGround)
  434. force(new Vec2(-vel.x * friction, 0));
  435. else
  436. force(new Vec2(-vel.x * airResistance, 0));
  437. if (resurrectTimeout > 0) {
  438. resurrectTimeout -= 1;
  439. if (resurrectTimeout == 0) {
  440. height *= timesJumped + 1;
  441. timesJumped = 0;
  442. }
  443. }
  444. }
  445. @Override public void draw(Graphics2D gfx) {
  446. gfx.setColor(new Color(255, 20, 20));
  447. gfx.fillRect(0, 0, width, height);
  448. gfx.setColor(new Color(155, 10, 10));
  449. gfx.drawRect(0, 0, width, height);
  450. }
  451. }
  452. class EnemyWalker extends Enemy {
  453. private int direction = -1;
  454. EnemyWalker(int x, int y, int dir) {
  455. super(x, y, 30, 30);
  456. direction = dir;
  457. }
  458. @Override public void update() {
  459. super.update();
  460. if (resurrectTimeout > 0)
  461. return;
  462. if (collidedLeft) {
  463. direction = -1;
  464. } else if (collidedRight) {
  465. direction = 1;
  466. }
  467. force(new Vec2(moveForce * direction, 0));
  468. }
  469. }
  470. class EnemyJumper extends Enemy {
  471. EnemyJumper(int x, int y) {
  472. super(x, y, 20, 30);
  473. }
  474. @Override public void update() {
  475. super.update();
  476. if (resurrectTimeout > 0)
  477. return;
  478. if (!collidedRight && game.player.pos.x + game.player.width <= pos.x)
  479. force(new Vec2(-moveForce, 0));
  480. else if (!collidedLeft && game.player.pos.x >= pos.x + width)
  481. force(new Vec2(moveForce, 0));
  482. if (onGround && (collidedRight || collidedLeft))
  483. impulse(new Vec2(0, -jumpForce));
  484. if (collidedLeft || collidedRight)
  485. vel.x = 0;
  486. }
  487. }
  488. class EnemyFlyer extends Enemy {
  489. private final double gravityForce = 0;
  490. private double flyForce = 1;
  491. private int targetY;
  492. EnemyFlyer(int x, int y) {
  493. super(x, y, 30, 15);
  494. targetY = y;
  495. impulse(new Vec2(0, -0.5));
  496. }
  497. @Override public void update() {
  498. super.update();
  499. if (resurrectTimeout > 0)
  500. return;
  501. if (pos.y > targetY) {
  502. force(new Vec2(0, -flyForce));
  503. } else {
  504. force(new Vec2(0, flyForce));
  505. }
  506. }
  507. }
  508. @SuppressWarnings("serial")
  509. class Game extends JPanel implements KeyListener {
  510. private static Clip playAudio(String filename) throws Exception {
  511. File file = new File(filename);
  512. AudioInputStream stream = AudioSystem.getAudioInputStream(file);
  513. AudioFormat format = stream.getFormat();
  514. DataLine.Info info = new DataLine.Info(Clip.class, format);
  515. Clip clip = (Clip)AudioSystem.getLine(info);
  516. clip.open(stream);
  517. clip.start();
  518. return clip;
  519. }
  520. public enum State {
  521. RUNNING,
  522. WON,
  523. LOST
  524. }
  525. private State state;
  526. private ArrayList<Integer> pressedKeys;
  527. private final int targetDTime = 16;
  528. private HashMap<String, String> entityMessages;
  529. private File level;
  530. public ArrayList<Entity> entities;
  531. public Vec2 camera;
  532. public Entity player;
  533. public Clip music;
  534. public boolean gameEnded;
  535. public JFrame window;
  536. Game(JFrame window) {
  537. state = State.RUNNING;
  538. pressedKeys = new ArrayList<Integer>();
  539. entityMessages = new HashMap<String, String>();
  540. entities = new ArrayList<Entity>();
  541. camera = new Vec2(0, 0);
  542. player = null;
  543. music = null;
  544. gameEnded = false;
  545. this.window = window;
  546. window.addKeyListener(this);
  547. window.add(this);
  548. }
  549. public void addEntity(Entity e) {
  550. System.out.println("adding "+e.identify());
  551. e.game = this;
  552. entities.add(e);
  553. e.init();
  554. if (e instanceof Player)
  555. player = e;
  556. }
  557. public void run() throws InterruptedException {
  558. while (true) {
  559. if (state != State.RUNNING) {
  560. Thread.sleep(100);
  561. continue;
  562. }
  563. long startTime = new Date().getTime();
  564. for (int i = 0; i < entities.size(); ++i) {
  565. Entity e = entities.get(i);
  566. if (e.dead) {
  567. entities.remove(i);
  568. continue;
  569. }
  570. if (!e.shouldUpdate())
  571. continue;
  572. e.move(targetDTime);
  573. }
  574. for (int i = 0; i < entities.size(); ++i) {
  575. Entity e = entities.get(i);
  576. if (!e.shouldUpdate())
  577. continue;
  578. e.update();
  579. }
  580. paintComponent((Graphics2D)getGraphics());
  581. window.revalidate();
  582. window.repaint();
  583. int sleepTime = targetDTime - (int)(new Date().getTime() - startTime);
  584. if (sleepTime > 0)
  585. Thread.sleep(sleepTime);
  586. //Reset entity messages
  587. entityMessages = new HashMap<String, String>();
  588. }
  589. }
  590. @Override public void paintComponent(Graphics g) {
  591. Graphics2D gfx = (Graphics2D)g;
  592. resetGfx(gfx);
  593. if (state == State.RUNNING) {
  594. gfx.translate(camera.x, camera.y);
  595. for (int i = 0; i < entities.size(); ++i) {
  596. Entity e = entities.get(i);
  597. if (!e.shouldUpdate())
  598. continue;
  599. gfx.translate(e.pos.x, e.pos.y);
  600. e.draw(gfx);
  601. resetGfx(gfx);
  602. gfx.translate(-e.pos.x, -e.pos.y);
  603. }
  604. gfx.translate(-camera.x, -camera.y);
  605. int i = 0;
  606. for (String s: entityMessages.values()) {
  607. gfx.drawString(s, 10, 20 * (i + 1));
  608. i += 1;
  609. }
  610. } else {
  611. GraphicsUtils.drawDoneMessage(gfx, state, window);
  612. }
  613. }
  614. public void win() {
  615. System.out.println("Congratulations! You win!");
  616. state = State.WON;
  617. window.repaint();
  618. gameEnded = true;
  619. }
  620. public void lose() {
  621. System.out.println("You lost!");
  622. state = State.LOST;
  623. window.repaint();
  624. gameEnded = true;
  625. }
  626. public void displayText(Entity e, String str) {
  627. entityMessages.put(e.getClass().getName(), str);
  628. }
  629. public void loadLevel(File file) throws Exception {
  630. System.out.println("Loading level...");
  631. Coin.reset();
  632. level = file;
  633. Scanner s = new Scanner(file);
  634. int lineNum = 0;
  635. try {
  636. while (s.hasNextLine()) {
  637. lineNum += 1;
  638. String line = s.nextLine();
  639. String[] tokens = line.split("\\s+");
  640. String name = tokens[0];
  641. //If the line starts with #, it's a comment
  642. if (name.equals("#"))
  643. continue;
  644. //Play audio if the line starts with 'audio'
  645. if (name.equals("audio")) {
  646. if (music == null)
  647. music = playAudio(line.replace("audio", "").trim());
  648. continue;
  649. }
  650. //Ignore empty lines
  651. if (name.equals(""))
  652. continue;
  653. int[] args = new int[tokens.length - 1];
  654. for (int i = 0; i < args.length; ++i) {
  655. args[i] = Integer.parseInt(tokens[i + 1]);
  656. }
  657. switch (name) {
  658. case "player":
  659. addEntity(new Player(args[0], args[1]));
  660. break;
  661. case "platform":
  662. addEntity(new Platform(args[0], args[1], args[2], args[3]));
  663. break;
  664. case "enemyWalker":
  665. addEntity(new EnemyWalker(args[0], args[1], args[2]));
  666. break;
  667. case "enemyJumper":
  668. addEntity(new EnemyJumper(args[0], args[1]));
  669. break;
  670. case "enemyFlyer":
  671. addEntity(new EnemyFlyer(args[0], args[1]));
  672. break;
  673. case "victory":
  674. addEntity(new Victory(args[0], args[1]));
  675. break;
  676. case "coin":
  677. addEntity(new Coin(args[0], args[1]));
  678. break;
  679. default:
  680. System.out.println("Unknown entity "+name+" on line "+lineNum);
  681. }
  682. }
  683. } catch (ArrayIndexOutOfBoundsException e) {
  684. System.out.println("Too few arguments on line "+lineNum);
  685. }
  686. System.out.println("Done.");
  687. }
  688. public void resetGfx(Graphics2D gfx) {
  689. gfx.setStroke(new BasicStroke(1));
  690. gfx.setColor(new Color(0, 0, 0));
  691. gfx.setFont(new Font("Serif", Font.PLAIN, 13));
  692. }
  693. public boolean isKeyPressed(int c) {
  694. return (pressedKeys.indexOf(c) != -1);
  695. }
  696. @Override public void keyPressed(KeyEvent e) {
  697. if (pressedKeys.indexOf(e.getKeyCode()) == -1)
  698. pressedKeys.add(e.getKeyCode());
  699. if (gameEnded && isKeyPressed(Key.RESTART)) {
  700. gameEnded = false;
  701. System.out.println("restarting");
  702. state = State.RUNNING;
  703. entities.clear();
  704. window.repaint();
  705. try {
  706. loadLevel(level);
  707. } catch (Exception ex) {
  708. ex.printStackTrace();
  709. }
  710. }
  711. }
  712. @Override public void keyReleased(KeyEvent e) {
  713. int i = pressedKeys.indexOf(e.getKeyCode());
  714. if (i != -1)
  715. pressedKeys.remove(i);
  716. }
  717. @Override public void keyTyped(KeyEvent e) {}
  718. }
  719. class MinOppgave5 {
  720. private static JFrame window;
  721. private static void start(File file) throws Exception {
  722. window = new JFrame("Game");
  723. window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  724. window.setSize(800, 800);
  725. window.setVisible(true);
  726. Game game = new Game(window);
  727. game.loadLevel(file);
  728. game.run();
  729. }
  730. public static void main(String[] args) throws Exception {
  731. Scanner in = new Scanner(System.in);
  732. File level;
  733. if (args.length != 1) {
  734. System.out.println("Usage: MinOppgave5 <level>");
  735. System.out.println("Available levels:");
  736. for (File f: new File(".").listFiles()) {
  737. String name = f.toPath().getFileName().toString();
  738. if (!name.endsWith(".level"))
  739. continue;
  740. System.out.println("* "+name);
  741. }
  742. System.exit(1);
  743. return;
  744. } else {
  745. level = new File(args[0]);
  746. start(level);
  747. }
  748. System.out.println(" ---------------- ");
  749. System.out.println("| Controls: |");
  750. System.out.println("| A: Move Left |");
  751. System.out.println("| D: Move Right |");
  752. System.out.println("| Space: Jump |");
  753. System.out.println(" ---------------- ");
  754. System.out.println("Press Enter to start.");
  755. in.nextLine();
  756. }
  757. }