Space Invaders

   UAS PBO-B 

Nama Anggota Kelompok :
1. Sabrina Lydia Simanjuntak (05111940000107)
2. Fitrah Mutiara (05111940000126)

     Space Invaders adalah sebuah permainan arkade yang di rilis pada tahun 1978. Permainan ini awalnya dibuat dan dijual di Jepang , dan kemudian di lisensi kan di Amerika Serikat. Space Invaders adalah salah satu permainan tembak-menembak pertama dan menampilkan grafik 2D. Tujuan dari permainan adalah menembak seluruh alien dengan meriam laser dan membuat skor setinggi mungkin.

    Game ini terdiri dari beberapa kelas, diantaranya beberapa kelas utama yaitu Class SpaceInvaders, Class Commons, dan Class Board, dan juga kelas-kelas untuk mengatur aliennya, yaitu Class Alien, Class Player, Class Sprite, dan Class Shot. Berikut merupakan diagram classnya.



Source Code

1. Class SpaceInvaders
Class SpaceInvaders merupakan kelas utama yang berfungsi mengatur/menyetel aplikasi dan desain tampilan dari Game Space Invaders.

  1. package com.zetcode;
  2.  
  3. import java.awt.EventQueue;
  4. import javax.swing.JFrame;
  5.  
  6. public class SpaceInvaders extends JFrame {
  7.  
  8. public SpaceInvaders() {
  9.  
  10. initUI();
  11. }
  12.  
  13. private void initUI() {
  14.  
  15. add(new Board());
  16.  
  17. setTitle("Space Invaders");
  18. setSize(Commons.BOARD_WIDTH, Commons.BOARD_HEIGHT);
  19.  
  20. setDefaultCloseOperation(EXIT_ON_CLOSE);
  21. setResizable(false);
  22. setLocationRelativeTo(null);
  23. }
  24.  
  25. public static void main(String[] args) {
  26.  
  27. EventQueue.invokeLater(() -> {
  28.  
  29. var ex = new SpaceInvaders();
  30. ex.setVisible(true);
  31. });
  32. }
  33. }

2.Class Common
Class Common berisikan konstanta-konstanta umum yang digunakan pada aplikasi seperti ukuran tinggi dan lebar board beserta border kiri dan kanannya, ukuran ground, tinggi bom, ukuran alien, dan konstanta" lainnya. 

  1. package com.zetcode;
  2.  
  3. public interface Commons {
  4.  
  5. int BOARD_WIDTH = 358;
  6. int BOARD_HEIGHT = 350;
  7. int BORDER_RIGHT = 30;
  8. int BORDER_LEFT = 5;
  9.  
  10. int GROUND = 290;
  11. int BOMB_HEIGHT = 5;
  12.  
  13. int ALIEN_HEIGHT = 12;
  14. int ALIEN_WIDTH = 12;
  15. int ALIEN_INIT_X = 150;
  16. int ALIEN_INIT_Y = 5;
  17.  
  18. int GO_DOWN = 15;
  19. int NUMBER_OF_ALIENS_TO_DESTROY = 24;
  20. int CHANCE = 5;
  21. int DELAY = 17;
  22. int PLAYER_WIDTH = 15;
  23. int PLAYER_HEIGHT = 10;
  24. }

3.Class Board
Class Board berisikan logika utama pada game yang berfungsi untuk mengatur tampilan game yang sedang dimainkan, mulai dari memunculkan gambar-gambar, membentuk susunan 24 alien, mengatur tampilan saat game over, mengecek jumlah alien yang mati, mengecek jika pemain memenangkan game, mengecek syarat untuk alien menjatuhkan bom, dan logika-logika lainnya.

  1. package com.zetcode;
  2.  
  3. import com.zetcode.sprite.Alien;
  4. import com.zetcode.sprite.Player;
  5. import com.zetcode.sprite.Shot;
  6.  
  7. import javax.swing.ImageIcon;
  8. import javax.swing.JPanel;
  9. import javax.swing.Timer;
  10. import java.awt.Color;
  11. import java.awt.Dimension;
  12. import java.awt.Font;
  13. import java.awt.Graphics;
  14. import java.awt.Toolkit;
  15. import java.awt.event.ActionEvent;
  16. import java.awt.event.ActionListener;
  17. import java.awt.event.KeyAdapter;
  18. import java.awt.event.KeyEvent;
  19. import java.util.ArrayList;
  20. import java.util.Iterator;
  21. import java.util.List;
  22. import java.util.Random;
  23.  
  24. public class Board extends JPanel {
  25.  
  26. private Dimension d;
  27. private List<Alien> aliens;
  28. private Player player;
  29. private Shot shot;
  30.  
  31. private int direction = -1;
  32. private int deaths = 0;
  33.  
  34. private boolean inGame = true;
  35. private String explImg = "src/images/explosion.png";
  36. private String message = "Game Over";
  37.  
  38. private Timer timer;
  39.  
  40.  
  41. public Board() {
  42.  
  43. initBoard();
  44. gameInit();
  45. }
  46.  
  47. private void initBoard() {
  48.  
  49. addKeyListener(new TAdapter());
  50. setFocusable(true);
  51. d = new Dimension(Commons.BOARD_WIDTH, Commons.BOARD_HEIGHT);
  52. setBackground(Color.black);
  53.  
  54. timer = new Timer(Commons.DELAY, new GameCycle());
  55. timer.start();
  56.  
  57. gameInit();
  58. }
  59.  
  60.  
  61. private void gameInit() {
  62.  
  63. aliens = new ArrayList<>();
  64.  
  65. for (int i = 0; i < 4; i++) {
  66. for (int j = 0; j < 6; j++) {
  67.  
  68. var alien = new Alien(Commons.ALIEN_INIT_X + 18 * j,
  69. Commons.ALIEN_INIT_Y + 18 * i);
  70. aliens.add(alien);
  71. }
  72. }
  73.  
  74. player = new Player();
  75. shot = new Shot();
  76. }
  77.  
  78. private void drawAliens(Graphics g) {
  79.  
  80. for (Alien alien : aliens) {
  81.  
  82. if (alien.isVisible()) {
  83.  
  84. g.drawImage(alien.getImage(), alien.getX(), alien.getY(), this);
  85. }
  86.  
  87. if (alien.isDying()) {
  88.  
  89. alien.die();
  90. }
  91. }
  92. }
  93.  
  94. private void drawPlayer(Graphics g) {
  95.  
  96. if (player.isVisible()) {
  97.  
  98. g.drawImage(player.getImage(), player.getX(), player.getY(), this);
  99. }
  100.  
  101. if (player.isDying()) {
  102.  
  103. player.die();
  104. inGame = false;
  105. }
  106. }
  107.  
  108. private void drawShot(Graphics g) {
  109.  
  110. if (shot.isVisible()) {
  111.  
  112. g.drawImage(shot.getImage(), shot.getX(), shot.getY(), this);
  113. }
  114. }
  115.  
  116. private void drawBombing(Graphics g) {
  117.  
  118. for (Alien a : aliens) {
  119.  
  120. Alien.Bomb b = a.getBomb();
  121.  
  122. if (!b.isDestroyed()) {
  123.  
  124. g.drawImage(b.getImage(), b.getX(), b.getY(), this);
  125. }
  126. }
  127. }
  128.  
  129. @Override
  130. public void paintComponent(Graphics g) {
  131. super.paintComponent(g);
  132.  
  133. doDrawing(g);
  134. }
  135.  
  136. private void doDrawing(Graphics g) {
  137.  
  138. g.setColor(Color.black);
  139. g.fillRect(0, 0, d.width, d.height);
  140. g.setColor(Color.green);
  141.  
  142. if (inGame) {
  143.  
  144. g.drawLine(0, Commons.GROUND,
  145. Commons.BOARD_WIDTH, Commons.GROUND);
  146.  
  147. drawAliens(g);
  148. drawPlayer(g);
  149. drawShot(g);
  150. drawBombing(g);
  151.  
  152. } else {
  153.  
  154. if (timer.isRunning()) {
  155. timer.stop();
  156. }
  157.  
  158. gameOver(g);
  159. }
  160.  
  161. Toolkit.getDefaultToolkit().sync();
  162. }
  163.  
  164. private void gameOver(Graphics g) {
  165.  
  166. g.setColor(Color.black);
  167. g.fillRect(0, 0, Commons.BOARD_WIDTH, Commons.BOARD_HEIGHT);
  168.  
  169. g.setColor(new Color(0, 32, 48));
  170. g.fillRect(50, Commons.BOARD_WIDTH / 2 - 30, Commons.BOARD_WIDTH - 100, 50);
  171. g.setColor(Color.white);
  172. g.drawRect(50, Commons.BOARD_WIDTH / 2 - 30, Commons.BOARD_WIDTH - 100, 50);
  173.  
  174. var small = new Font("Helvetica", Font.BOLD, 14);
  175. var fontMetrics = this.getFontMetrics(small);
  176.  
  177. g.setColor(Color.white);
  178. g.setFont(small);
  179. g.drawString(message, (Commons.BOARD_WIDTH - fontMetrics.stringWidth(message)) / 2,
  180. Commons.BOARD_WIDTH / 2);
  181. }
  182.  
  183. private void update() {
  184.  
  185. if (deaths == Commons.NUMBER_OF_ALIENS_TO_DESTROY) {
  186.  
  187. inGame = false;
  188. timer.stop();
  189. message = "Game won!";
  190. }
  191.  
  192. // player
  193. player.act();
  194.  
  195. // shot
  196. if (shot.isVisible()) {
  197.  
  198. int shotX = shot.getX();
  199. int shotY = shot.getY();
  200.  
  201. for (Alien alien : aliens) {
  202.  
  203. int alienX = alien.getX();
  204. int alienY = alien.getY();
  205.  
  206. if (alien.isVisible() && shot.isVisible()) {
  207. if (shotX >= (alienX)
  208. && shotX <= (alienX + Commons.ALIEN_WIDTH)
  209. && shotY >= (alienY)
  210. && shotY <= (alienY + Commons.ALIEN_HEIGHT)) {
  211.  
  212. var ii = new ImageIcon(explImg);
  213. alien.setImage(ii.getImage());
  214. alien.setDying(true);
  215. deaths++;
  216. shot.die();
  217. }
  218. }
  219. }
  220.  
  221. int y = shot.getY();
  222. y -= 4;
  223.  
  224. if (y < 0) {
  225. shot.die();
  226. } else {
  227. shot.setY(y);
  228. }
  229. }
  230.  
  231. // aliens
  232.  
  233. for (Alien alien : aliens) {
  234.  
  235. int x = alien.getX();
  236.  
  237. if (x >= Commons.BOARD_WIDTH - Commons.BORDER_RIGHT && direction != -1) {
  238.  
  239. direction = -1;
  240.  
  241. Iterator<Alien> i1 = aliens.iterator();
  242.  
  243. while (i1.hasNext()) {
  244.  
  245. Alien a2 = i1.next();
  246. a2.setY(a2.getY() + Commons.GO_DOWN);
  247. }
  248. }
  249.  
  250. if (x <= Commons.BORDER_LEFT && direction != 1) {
  251.  
  252. direction = 1;
  253.  
  254. Iterator<Alien> i2 = aliens.iterator();
  255.  
  256. while (i2.hasNext()) {
  257.  
  258. Alien a = i2.next();
  259. a.setY(a.getY() + Commons.GO_DOWN);
  260. }
  261. }
  262. }
  263.  
  264. Iterator<Alien> it = aliens.iterator();
  265.  
  266. while (it.hasNext()) {
  267.  
  268. Alien alien = it.next();
  269.  
  270. if (alien.isVisible()) {
  271.  
  272. int y = alien.getY();
  273.  
  274. if (y > Commons.GROUND - Commons.ALIEN_HEIGHT) {
  275. inGame = false;
  276. message = "Invasion!";
  277. }
  278.  
  279. alien.act(direction);
  280. }
  281. }
  282.  
  283. // bombs
  284. var generator = new Random();
  285.  
  286. for (Alien alien : aliens) {
  287.  
  288. int shot = generator.nextInt(15);
  289. Alien.Bomb bomb = alien.getBomb();
  290.  
  291. if (shot == Commons.CHANCE && alien.isVisible() && bomb.isDestroyed()) {
  292.  
  293. bomb.setDestroyed(false);
  294. bomb.setX(alien.getX());
  295. bomb.setY(alien.getY());
  296. }
  297.  
  298. int bombX = bomb.getX();
  299. int bombY = bomb.getY();
  300. int playerX = player.getX();
  301. int playerY = player.getY();
  302.  
  303. if (player.isVisible() && !bomb.isDestroyed()) {
  304.  
  305. if (bombX >= (playerX)
  306. && bombX <= (playerX + Commons.PLAYER_WIDTH)
  307. && bombY >= (playerY)
  308. && bombY <= (playerY + Commons.PLAYER_HEIGHT)) {
  309.  
  310. var ii = new ImageIcon(explImg);
  311. player.setImage(ii.getImage());
  312. player.setDying(true);
  313. bomb.setDestroyed(true);
  314. }
  315. }
  316.  
  317. if (!bomb.isDestroyed()) {
  318.  
  319. bomb.setY(bomb.getY() + 1);
  320.  
  321. if (bomb.getY() >= Commons.GROUND - Commons.BOMB_HEIGHT) {
  322.  
  323. bomb.setDestroyed(true);
  324. }
  325. }
  326. }
  327. }
  328.  
  329. private void doGameCycle() {
  330.  
  331. update();
  332. repaint();
  333. }
  334.  
  335. private class GameCycle implements ActionListener {
  336.  
  337. @Override
  338. public void actionPerformed(ActionEvent e) {
  339.  
  340. doGameCycle();
  341. }
  342. }
  343.  
  344. private class TAdapter extends KeyAdapter {
  345.  
  346. @Override
  347. public void keyReleased(KeyEvent e) {
  348.  
  349. player.keyReleased(e);
  350. }
  351.  
  352. @Override
  353. public void keyPressed(KeyEvent e) {
  354.  
  355. player.keyPressed(e);
  356.  
  357. int x = player.getX();
  358. int y = player.getY();
  359.  
  360. int key = e.getKeyCode();
  361.  
  362. if (key == KeyEvent.VK_SPACE) {
  363.  
  364. if (inGame) {
  365.  
  366. if (!shot.isVisible()) {
  367.  
  368. shot = new Shot(x, y);
  369. }
  370. }
  371. }
  372. }
  373. }
  374. }

4. Class Alien
Kelas ini digunakan untuk meload gambar alien dan juga memberi tahu posisi awal alien.

  1. package com.zetcode.sprite;
  2.  
  3. import javax.swing.ImageIcon;
  4.  
  5. public class Alien extends Sprite {
  6.  
  7. private Bomb bomb;
  8.  
  9. public Alien(int x, int y) {
  10.  
  11. initAlien(x, y);
  12. }
  13.  
  14. private void initAlien(int x, int y) {
  15.  
  16. this.x = x;
  17. this.y = y;
  18.  
  19. bomb = new Bomb(x, y);
  20.  
  21. var alienImg = "src/images/alien.png";
  22. var ii = new ImageIcon(alienImg);
  23.  
  24. setImage(ii.getImage());
  25. }
  26.  
  27. public void act(int direction) {
  28.  
  29. this.x += direction;
  30. }
  31.  
  32. public Bomb getBomb() {
  33.  
  34. return bomb;
  35. }
  36.  
  37. public class Bomb extends Sprite {
  38.  
  39. private boolean destroyed;
  40.  
  41. public Bomb(int x, int y) {
  42.  
  43. initBomb(x, y);
  44. }
  45.  
  46. private void initBomb(int x, int y) {
  47.  
  48. setDestroyed(true);
  49.  
  50. this.x = x;
  51. this.y = y;
  52.  
  53. var bombImg = "src/images/bomb.png";
  54. var ii = new ImageIcon(bombImg);
  55. setImage(ii.getImage());
  56. }
  57.  
  58. public void setDestroyed(boolean destroyed) {
  59.  
  60. this.destroyed = destroyed;
  61. }
  62.  
  63. public boolean isDestroyed() {
  64.  
  65. return destroyed;
  66. }
  67. }
  68. }

5. Class Player
kelas ini digunakan agar player bisa melakukan tembakan pada alien atau musuh, juga untuk meload ikon shot itu sendiri.

  1. package com.zetcode.sprite;
  2.  
  3. import com.zetcode.Commons;
  4.  
  5. import javax.swing.ImageIcon;
  6. import java.awt.event.KeyEvent;
  7.  
  8. public class Player extends Sprite {
  9.  
  10. private int width;
  11.  
  12. public Player() {
  13.  
  14. initPlayer();
  15. }
  16.  
  17. private void initPlayer() {
  18.  
  19. var playerImg = "src/images/player.png";
  20. var ii = new ImageIcon(playerImg);
  21.  
  22. width = ii.getImage().getWidth(null);
  23. setImage(ii.getImage());
  24.  
  25. int START_X = 270;
  26. setX(START_X);
  27.  
  28. int START_Y = 280;
  29. setY(START_Y);
  30. }
  31.  
  32. public void act() {
  33.  
  34. x += dx;
  35.  
  36. if (x <= 2) {
  37.  
  38. x = 2;
  39. }
  40.  
  41. if (x >= Commons.BOARD_WIDTH - 2 * width) {
  42.  
  43. x = Commons.BOARD_WIDTH - 2 * width;
  44. }
  45. }
  46.  
  47. public void keyPressed(KeyEvent e) {
  48.  
  49. int key = e.getKeyCode();
  50.  
  51. if (key == KeyEvent.VK_LEFT) {
  52.  
  53. dx = -2;
  54. }
  55.  
  56. if (key == KeyEvent.VK_RIGHT) {
  57.  
  58. dx = 2;
  59. }
  60. }
  61.  
  62. public void keyReleased(KeyEvent e) {
  63.  
  64. int key = e.getKeyCode();
  65.  
  66. if (key == KeyEvent.VK_LEFT) {
  67.  
  68. dx = 0;
  69. }
  70.  
  71. if (key == KeyEvent.VK_RIGHT) {
  72.  
  73. dx = 0;
  74. }
  75. }
  76. }

6. Class Sprite
Kelas ini digunakan untuk melakukan return atau mengembalikan nilai dari kelas-kelas lain.

  1. package com.zetcode.sprite;
  2.  
  3. import java.awt.Image;
  4.  
  5. public class Sprite {
  6.  
  7. private boolean visible;
  8. private Image image;
  9. private boolean dying;
  10.  
  11. int x;
  12. int y;
  13. int dx;
  14.  
  15. public Sprite() {
  16.  
  17. visible = true;
  18. }
  19.  
  20. public void die() {
  21.  
  22. visible = false;
  23. }
  24.  
  25. public boolean isVisible() {
  26.  
  27. return visible;
  28. }
  29.  
  30. protected void setVisible(boolean visible) {
  31.  
  32. this.visible = visible;
  33. }
  34.  
  35. public void setImage(Image image) {
  36.  
  37. this.image = image;
  38. }
  39.  
  40. public Image getImage() {
  41.  
  42. return image;
  43. }
  44.  
  45. public void setX(int x) {
  46.  
  47. this.x = x;
  48. }
  49.  
  50. public void setY(int y) {
  51.  
  52. this.y = y;
  53. }
  54.  
  55. public int getY() {
  56.  
  57. return y;
  58. }
  59.  
  60. public int getX() {
  61.  
  62. return x;
  63. }
  64.  
  65. public void setDying(boolean dying) {
  66.  
  67. this.dying = dying;
  68. }
  69.  
  70. public boolean isDying() {
  71.  
  72. return this.dying;
  73. }
  74. }

7. Class Shot
Kelas ini digunakan agar ketika ditembak, kapal alien dapat meledak seperti terkena bomb ketika shot mengenai kapal alien, di kelas ini juga digunakan sintaks untuk meload ikon bomb.

  1. package com.zetcode.sprite;
  2.  
  3. import javax.swing.ImageIcon;
  4.  
  5. public class Shot extends Sprite {
  6.  
  7. public Shot() {
  8. }
  9.  
  10. public Shot(int x, int y) {
  11.  
  12. initShot(x, y);
  13. }
  14.  
  15. private void initShot(int x, int y) {
  16.  
  17. var shotImg = "src/images/shot.png";
  18. var ii = new ImageIcon(shotImg);
  19. setImage(ii.getImage());
  20.  
  21. int H_SPACE = 6;
  22. setX(x + H_SPACE);
  23.  
  24. int V_SPACE = 1;
  25. setY(y - V_SPACE);
  26. }
  27. }

Output
Berikut merupakan tampilan dari game Space Invaders.


Pemain bisa bergerak ke kiri dan ke kanan, dan menembak alien dengan menekan tombol spasi.


Jika alien tertembak, maka alien akan menghilang(mati). Di sini pemain juga harus menghindari bom yang dijatuhkan oleh alien, jika pemain terkena bomnya, maka pemain akan mati dan game over.




-thankyou-

Komentar

Postingan populer dari blog ini

Ticket Machine

ETS PWEB-A

Tugas 10 PBKK