Sign in with
Sign up | Sign in
Your question
Solved

Please review this code

Last response: in Applications
Share
December 3, 2012 9:11:26 AM

I'm learning Java and this is what I've been able to come up with.

Please take a look at my code and tell me about the wrong approaches I've employed
(Apart from the lack of comments).

Also:
--tell me the good habits I should keep-up with.
--What does line 163 do?
--How do I make the keyboard control the player (My **keyPressed()** method doesn't work)

There are five Classes: Is it OO enough?



Class 1:
  1. //SpaceInvaders.java
  2. //This is the main class that runs the Applet
  3.  
  4. package space_game;
  5.  
  6. import acm.program.*;
  7. import acm.graphics.*;
  8. import acm.util.*;
  9.  
  10. import java.applet.AudioClip;
  11. import java.awt.Color;
  12. import java.awt.event.*;
  13. import java.util.ArrayList;
  14.  
  15. public class SpaceInvaders extends GraphicsProgram{
  16.  
  17. private static final int APP_WIDTH = 1100;
  18. private static final int APP_HEIGHT = 600;
  19.  
  20. private static final int GAME_BOARD_WIDTH = 800;
  21. private static final int GAME_BOARD_HEIGHT = 400;
  22.  
  23.  
  24. private static final double BULLET_DIM = 3;
  25. private static final double PLAYER_WIDTH = 15;
  26. private static final double PLAYER_HEIGHT = 5;
  27. private static final double INVADER_WIDTH = 9;
  28. private static final double INVADER_HEIGHT = 12;
  29. private static final int PADDING = 5;
  30.  
  31.  
  32. private static final Color BG_COLOR = Color.WHITE;
  33. private static final Color BULLET_COLOR = Color.ORANGE;
  34. private static final Color PLAYER_COLOR = Color.GREEN;
  35.  
  36. //private static final Color INVADER_COLOR = Color.LIGHT_GRAY;
  37.  
  38. private GameBoard board;
  39. private GRect[] backGround;
  40. private GRect playArea;
  41. private Color[] boardCols;
  42. private Player player = new Player(PLAYER_WIDTH, PLAYER_HEIGHT,PLAYER_COLOR);
  43. private ArrayList<Bullet> bullet = new ArrayList<Bullet>();
  44. private Invader invader[];
  45. private int curBullet = 0;
  46. private double totalBullets = 0.0;
  47. private int level = 0;
  48. private double score = 0;
  49. private double speed;
  50.  
  51. private Invader.Type type;
  52. private Bullet.Type bType;
  53.  
  54. private RandomGenerator rgen = new RandomGenerator();
  55. private double yCord;
  56. private int invadersRemovalCount = 0;
  57. private int totalInvadersRemoved = 0;
  58. private boolean gamePaused;
  59. private boolean gameOver;
  60.  
  61. private AudioClip coming;
  62. private AudioClip invaded;
  63. private AudioClip shoot;
  64. private AudioClip killed;
  65.  
  66. public void init(){
  67. resize(APP_WIDTH, APP_HEIGHT);
  68. setBackground(BG_COLOR);
  69.  
  70. addMouseListeners();
  71.  
  72. backGround = new GRect[4];
  73.  
  74. boardCols = new Color[4];
  75. boardCols[0] = Color.BLACK;
  76. boardCols[1] = Color.BLUE;
  77. boardCols[2] = Color.GRAY;
  78. boardCols[3] = Color.WHITE;
  79.  
  80. speed = 0.3;
  81. bType = Bullet.Type.BALLER;
  82.  
  83. coming = MediaTools.loadAudioClip("audio/CrayonRock.au");
  84. invaded = MediaTools.loadAudioClip("audio/OnTheHunt.au");
  85. shoot = MediaTools.loadAudioClip("audio/gun.au");
  86. killed = MediaTools.loadAudioClip("audio/tweeters.au");
  87.  
  88. gamePaused = false;
  89. gameOver = false;
  90. }
  91.  
  92. public void run(){
  93.  
  94. setup();
  95. int scoreChecker;
  96.  
  97. while(true){
  98.  
  99. if(level_1()){
  100. type = Invader.Type.PAWN;
  101. bType = Bullet.Type.BALLER;
  102. scoreChecker = 1;
  103. }
  104. else if(level_2()){
  105. type = Invader.Type.KNIGHT;
  106. bType = Bullet.Type.BALLER;
  107. speed = 0.2;
  108. scoreChecker = 2;
  109. }
  110. else if(level_3()){
  111. type = Invader.Type.QUEEN;
  112. bType = Bullet.Type.SNIPER;
  113. speed = 0.1;
  114. scoreChecker = 3;
  115. }
  116. else {
  117. coming.stop();
  118. coming = MediaTools.loadAudioClip("audio/BussaMove.au");
  119. coming.loop();
  120. break;
  121. }
  122. score *= scoreChecker;
  123. board.updateInfo(1, String.valueOf((int) score));
  124.  
  125. createInvaders(new GPoint((playArea.getX()+playArea.getWidth())-PADDING, playArea.getY()+PADDING), playArea.getWidth(), playArea.getHeight()-PADDING, type, rgen.nextInt((int) (APP_HEIGHT*0.03), (int) (APP_HEIGHT*0.05)));
  126.  
  127. board.updateInfo(2, String.valueOf(level+1).concat(" / 10"));
  128.  
  129. invadersRemovalCount = 0;
  130. moveInvaders(invader);
  131.  
  132. level++;
  133.  
  134. }
  135. gameOver = true;
  136. reset();
  137.  
  138. }
  139.  
  140. private void setup(){
  141.  
  142. board = new GameBoard(GAME_BOARD_WIDTH, GAME_BOARD_HEIGHT, boardCols ,">>>SP4C3 INV4D3RS<<<", PADDING, 13, "Invaders Exterminated: ", "Bullets Used: ");
  143. add(board, (getWidth()-board.getWidth())/2, (getHeight()-board.getHeight())/2);
  144. playArea = new GRect(board.getX(), board.getY()+(board.getHeight()*0.15), board.getWidth(), board.getPlayArea().getHeight());
  145.  
  146. backGround[0] = new GRect(APP_WIDTH, APP_HEIGHT);
  147. backGround[0].setFilled(true);
  148. backGround[0].setColor(boardCols[2]);
  149. add(backGround[0], 0, 0);
  150.  
  151. backGround[1] = new GRect(APP_WIDTH, APP_HEIGHT);
  152. backGround[1].setFilled(true);
  153. backGround[1].setColor(getBackground());
  154. add(backGround[1], 0, playArea.getY());
  155.  
  156. backGround[2] = new GRect(APP_WIDTH, APP_HEIGHT);
  157. backGround[2].setFilled(true);
  158. backGround[2].setColor(boardCols[2]);
  159. add(backGround[2], 0, getYEnd(playArea));
  160.  
  161.  
  162. add(playArea);
  163. playArea.setVisible(false);
  164. playArea.addMouseMotionListener(this);
  165. board.sendToFront();
  166.  
  167. add(player, board.getX()+PADDING, (playArea.getY()+(playArea.getHeight()*0.5)));
  168.  
  169. backGround[3] = new GRect(0,0);
  170. backGround[3].setBounds(board.getPauseButton().getBounds());
  171. backGround[3].setLocation(playArea.getX()+((playArea.getWidth()-backGround[3].getWidth())/2), (playArea.getY()-((board.getStatusArea().getHeight()-backGround[3].getHeight())/2)-backGround[3].getHeight()));
  172. add(backGround[3]);
  173. //backGround[3].setVisible(false);
  174.  
  175. coming.loop();
  176.  
  177. }
  178.  
  179. private void createInvaders(GPoint pos, double wdt, double hgt, Invader.Type type, int numInvaders){
  180. invader = new Invader[numInvaders];
  181. for(int i=0; i<numInvaders; i++){
  182. invader[i] = new Invader(INVADER_WIDTH, INVADER_HEIGHT, type);
  183. add(invader[i], pos.getX()+rgen.nextDouble(0.0, wdt*0.25), pos.getY()+((hgt/numInvaders)*i));
  184. invader[i].setVisible(false);
  185. }
  186.  
  187. }
  188.  
  189. private void moveInvaders(Invader[] inv){
  190. int i ;
  191. while(true){
  192. if(gamePaused){
  193. board.changeState();
  194. waitForClick();
  195. board.changeState();
  196. }
  197.  
  198. gamePaused = false;
  199. if (!bullet.isEmpty())
  200. for(int j=0; j<bullet.size(); j++){
  201. bullet.get(j).move(2, 0);
  202.  
  203. if(collides(bullet.get(j), inv) || bullet.get(j).getX()>=getXEnd(playArea))
  204. remove(bullet.get(j));
  205. }
  206.  
  207. if(invadersExited(inv, invadersRemovalCount)){
  208. invaded.play();
  209. if(levelChanging()){
  210. reset();
  211. }
  212. break;
  213. }
  214.  
  215. for(i=0; i<inv.length; i++){
  216. inv[i].move(-1, 0);
  217.  
  218. if(xIsInPlayArea(inv[i].getX(), inv[i].getWidth())){
  219. inv[i].setVisible(true);
  220. }
  221.  
  222. if(!inv[i].isDead() && inv[i].getX()<=playArea.getX()){
  223. inv[i].changeState();
  224. remove(inv[i]);
  225.  
  226. invadersRemovalCount++;
  227. }
  228.  
  229. }
  230.  
  231. pause(100*speed);
  232. animatebottomBar();
  233. }
  234. for(i=0; i<inv.length; i++){
  235. remove(inv[i]);
  236. }
  237.  
  238. }
  239. private void animatebottomBar() {
  240. board.name.move(-1, 0);
  241. if(board.name.getX()<board.getPlayArea().getX())
  242. board.name.setLocation(getXEnd(board.getPlayArea()), board.name.getY());
  243. }
  244.  
  245.  
  246. private boolean levelChanging(){
  247. return (level==2||level==5||level==9);
  248. }
  249.  
  250. private boolean collides(Bullet b, Invader[] inv){
  251.  
  252. for(int i =0; i<inv.length; i++){
  253. if(!inv[i].isDead() && (inv[i].contains(b.getX()+b.getWidth()*0.9, b.getY()+b.getHeight()) || inv[i].contains(b.getX()+b.getWidth()*0.9, b.getY()+b.getHeight()))){
  254. inv[i].hit();
  255.  
  256. if(inv[i].maxHitReached()){
  257. inv[i].changeState();
  258. killed.play();
  259.  
  260. remove(inv[i]);
  261. invadersRemovalCount++;
  262.  
  263. totalInvadersRemoved++;
  264. score = ((totalInvadersRemoved/totalBullets)*1000);
  265. board.updateInfo(3, "Invaders Exterminated: "+totalInvadersRemoved);
  266. board.updateInfo(1, String.valueOf((int) score));
  267. }
  268. return true;
  269. }
  270. }
  271. return false;
  272. }
  273.  
  274. private boolean invadersExited(Invader[] inv, int count){
  275. return count == inv.length;
  276.  
  277. }
  278.  
  279.  
  280. private boolean level_1(){
  281. return level<3;
  282. }
  283.  
  284. private boolean level_2(){
  285. return level<6;
  286. }
  287.  
  288. private boolean level_3(){
  289. return level<10;
  290. }
  291.  
  292. public void keyPressed(KeyEvent k){
  293. if(k.getKeyCode() == KeyEvent.VK_ENTER)
  294. shoot();
  295. if(k.getKeyCode() == KeyEvent.VK_UP)
  296. player.move(0,-1);
  297. if(k.getKeyCode() == KeyEvent.VK_DOWN)
  298. player.move(0,1);
  299.  
  300. shoot();
  301. showStatus("..."+k.getKeyCode());
  302. }
  303.  
  304. public void mouseClicked(MouseEvent e){
  305.  
  306. if(backGround[3].contains(e.getX(), e.getY())){
  307.  
  308. gamePaused = true;
  309. //((GCompound) getElementAt(e.getX(), e.getY())).scale(50);
  310. }
  311. }
  312.  
  313. public void mousePressed(MouseEvent e){
  314. if(!gameOver){
  315. shoot();
  316. }
  317. }
  318.  
  319. public void mouseMoved(MouseEvent e){
  320.  
  321. if(yIsInPlayArea(player.getY(), player.getHeight())){
  322. player.move(0, e.getY()-yCord);
  323. yCord = e.getY();
  324. }
  325.  
  326. if(outUpwards(player.getY())){
  327. player.move(0, 2);
  328. }
  329. if(outDownwards(getYEnd(player))){
  330. player.move(0, -2);
  331. }
  332.  
  333. }
  334.  
  335. public void mouseEntered(MouseEvent e){
  336. player.setLocation(player.getX(), e.getY());
  337. }
  338.  
  339. private void shoot(){
  340. switch(bType){
  341. case SNIPER:
  342. bullet.add(new Bullet(BULLET_DIM,Color.WHITE, bType));
  343. break;
  344. default:
  345. bullet.add(new Bullet(BULLET_DIM,BULLET_COLOR, bType));
  346. break;
  347. }
  348.  
  349. add(bullet.get(curBullet), player.getX()+player.getWidth(), player.getY());
  350.  
  351. if(yIsInPlayArea((bullet.get(curBullet).getY()), bullet.get(curBullet).getHeight())){
  352. shoot.play();
  353. curBullet++;
  354. totalBullets++;
  355. score = ((totalInvadersRemoved/totalBullets)*1000);
  356. board.updateInfo(4, "Bullets Used: ".concat(String.valueOf((int) totalBullets)));
  357. board.updateInfo(1, String.valueOf((int) score));
  358. }
  359.  
  360. else{
  361. bullet.get(curBullet).sendToBack();
  362. }
  363.  
  364. }
  365.  
  366. private boolean xIsInPlayArea(double x, double wdt){
  367. return (playArea.getX()<=x)&&((playArea.getX()+playArea.getWidth()>=x+wdt));
  368. }
  369.  
  370. private boolean yIsInPlayArea(double y, double hgt){
  371. return (playArea.getY()<=y)&&((playArea.getY()+playArea.getHeight()>=y+hgt));
  372. }
  373.  
  374. private boolean outUpwards(double y){
  375. return playArea.getY()>y;
  376. }
  377.  
  378. private boolean outDownwards(double y){
  379. return playArea.getY()+playArea.getHeight()<y;
  380. }
  381.  
  382. private double getXEnd(GObject g){
  383. return g.getX()+g.getWidth();
  384. }
  385.  
  386. private double getYEnd(GObject g){
  387. return (g.getY()+g.getHeight());
  388. }
  389.  
  390. private void reset(){
  391. for(int j=0; j<bullet.size(); j++){
  392. remove(bullet.get(j));
  393. }
  394. bullet.clear();
  395. curBullet = 0;
  396. board.name.setLocation((board.getPlayArea().getX()+(board.getPlayArea().getWidth()-board.name.getWidth())/2), board.name.getY());
  397.  
  398. showStatus("RESET CARRIED OUT!");
  399. }
  400. }




Class 2:
  1. //Player.java creates a shooting object [a Gun]
  2.  
  3. package space_game;
  4.  
  5. import acm.graphics.*;
  6. import java.awt.Color;
  7.  
  8. public class Player extends GCompound{
  9.  
  10. private GRect player;
  11.  
  12. public Player(double wdt, double hgt, Color col1, Color col2){
  13. player = new GRect(wdt, hgt);
  14. player.setFilled(true);
  15. player.setColor(col1);
  16. player.setFillColor(col2);
  17. add(player, 0,0);
  18.  
  19. player = new GRect(wdt*0.4, hgt*0.7);
  20. player.setFilled(true);
  21. player.setColor(col1);
  22. player.setFillColor(col2);
  23. add(player, 0,hgt);
  24.  
  25. player = new GRect(wdt*0.2, hgt*0.5);
  26. player.setFilled(true);
  27. player.setColor(col1);
  28. player.setFillColor(col2);
  29. add(player, 0,hgt*1.7);
  30. }
  31.  
  32. public Player(double wdt, double hgt, Color col){
  33. this(wdt, hgt, col, col);
  34. }
  35.  
  36. public Player(double wdt, Color col){
  37. this(wdt,wdt,col);
  38. }
  39. }



Class 3:
  1. //Bullet.java creates the bullet fired by the gun above
  2.  
  3. package space_game;
  4.  
  5. import acm.graphics.*;
  6. import java.awt.Color;
  7.  
  8. public class Bullet extends GCompound{
  9.  
  10. private GOval bullet;
  11. private GOval[] bulletArr = new GOval[4];
  12. private Type type;
  13.  
  14. public Bullet(double dia, Color col){
  15. this(dia, col, col, Type.BALLER);
  16. }
  17.  
  18. public Bullet(double dia, Color col, Type t){
  19. this(dia, col, col, t);
  20. }
  21.  
  22. public Bullet(double dia, Color col1, Color col2, Type t){
  23. type = t;
  24.  
  25.  
  26. switch(type){
  27. case BALLER:
  28. bullet = new GOval(dia,dia);
  29. bullet.setFilled(true);
  30. bullet.setColor(col1);
  31. bullet.setFillColor(col2);
  32. add(bullet, 0 ,0);
  33.  
  34. break;
  35.  
  36. case SNIPER:
  37.  
  38. dia*=2;
  39. for(int i = 0; i<4; i++){
  40. bulletArr[i] = new GOval(dia*((i+1)*(0.55)),dia*((i+1)*(0.2)));
  41. bulletArr[i].setFilled(true);
  42. bulletArr[i].setColor(col1);
  43. bulletArr[i].setFillColor(col2);
  44.  
  45. switch(i){
  46. case 0:
  47. add(bulletArr[0], 0 ,0);
  48. break;
  49. default:
  50. add(bulletArr[i], bulletArr[i-1].getWidth()*0.9 , -bulletArr[i-1].getHeight()*0.5);
  51. break;
  52. }
  53.  
  54. }
  55. break;
  56. }
  57. }
  58.  
  59. public enum Type{
  60. BALLER, SNIPER
  61. }
  62. }



Class 4:
  1. //Invader.java creates an enemy object
  2.  
  3. package space_game;
  4.  
  5. import acm.graphics.*;
  6. import acm.util.ErrorException;
  7.  
  8. import java.awt.Color;
  9.  
  10. public class Invader extends GCompound{
  11.  
  12. private GPolygon invader;
  13. private Color bodyColor;
  14. private Color skinColor;
  15. private int hits;
  16. private Type type;
  17. private State state;
  18.  
  19. public Invader(double wdt, double hgt, Color col1, Type t){
  20. switch(t){
  21. case PAWN:
  22. type = Type.PAWN;
  23. bodyColor = Color.PINK;
  24. break;
  25. case KNIGHT:
  26. type = Type.KNIGHT;
  27. bodyColor = Color.MAGENTA;
  28. break;
  29. case QUEEN:
  30. type = Type.QUEEN;
  31. bodyColor = Color.RED;
  32. wdt*=1.5;
  33. hgt*=1.5;
  34. break;
  35. default: throw new ErrorException("Invalid Type!");
  36. }
  37.  
  38. hits = 0;
  39. state = State.ALIVE;
  40. skinColor = col1;
  41. invader = new GPolygon();
  42.  
  43. invader.addVertex(-wdt, hgt*0.125);
  44. invader.addEdge(wdt*0.5, hgt*0.125);
  45. invader.addEdge(-wdt*0.5, hgt*0.125);
  46. invader.addEdge(wdt*0.5, hgt*0.125);
  47. invader.addEdge(-wdt*0.5, hgt*0.125);
  48. invader.addEdge(wdt*0.5, hgt*0.125);
  49. invader.addEdge(-wdt*0.5, hgt*0.125);
  50. invader.addEdge(wdt, hgt*0.125);
  51. invader.addVertex(0,0);
  52.  
  53.  
  54. invader.setFilled(true);
  55. invader.setColor(skinColor);
  56. invader.setFillColor(bodyColor);
  57. add(invader, 0,0);
  58. }
  59.  
  60. public Invader(double wdt, double hgt, Type t){
  61. this(wdt, hgt, Color.BLACK, t);
  62. }
  63.  
  64. public Invader(double wdt, Color col, Type t){
  65. this(wdt,wdt,Color.BLACK,t);
  66. }
  67.  
  68. public void setType(Type t){
  69.  
  70. switch(t){
  71. case PAWN:
  72. bodyColor = Color.PINK;
  73. type = Type.PAWN;
  74. break;
  75. case KNIGHT:
  76. bodyColor = Color.MAGENTA;
  77. type = Type.KNIGHT;
  78. break;
  79. case QUEEN:
  80. bodyColor = Color.RED;
  81. type = Type.QUEEN;
  82. break;
  83. default: throw new ErrorException("Invalid Type!");
  84. }
  85.  
  86. }
  87.  
  88. public void hit(){
  89. this.hits++;
  90. }
  91.  
  92. public int getHits(){
  93. return hits;
  94. }
  95.  
  96. public boolean maxHitReached(){
  97. switch (this.type){
  98. case PAWN:
  99. return(this.hits==2);
  100. case KNIGHT:
  101. return(this.hits==4);
  102. case QUEEN:
  103. return(this.hits==4);
  104. default:
  105. return false;
  106. }
  107. }
  108.  
  109. public void changeState(){
  110. if(state == State.ALIVE)
  111. state = State.DEAD;
  112. else{
  113. state = State.ALIVE;
  114. }
  115. }
  116.  
  117. public boolean isDead(){
  118. return (state == State.DEAD);
  119. }
  120.  
  121. public enum Type{
  122. PAWN, KNIGHT, QUEEN
  123. }
  124.  
  125. public enum State{
  126. ALIVE, DEAD
  127. }
  128. }




Class 5:
  1. //GameBoard.java creates a game-board that can be used by other 2d 'arcade' games
  2. package space_game;
  3.  
  4. /**
  5. * >>>[File: GameBoard.java]<<<
  6. * [=======================]
  7. *
  8. * Creates a Game-Board Template
  9. *
  10. * [=======================]
  11. *
  12. * This is an arcade-style-GameBoard Java class.
  13. * The Game-Board objects created from here can
  14. * be used by various game objects from other
  15. * classes
  16. *
  17. * [================================================]
  18. *
  19. * @author ac3Takwas
  20. *
  21. */
  22. import acm.graphics.*;
  23.  
  24. import java.awt.Color;
  25.  
  26. public class GameBoard extends GCompound{
  27.  
  28. /*Declaration of instance variables*/
  29.  
  30. private GRect statusArea;
  31. private GRect pauseButton;
  32. private GRoundRect playArea;
  33. private GRoundRect bottom;
  34. public GLabel name;
  35. private GLabel scoreArea;
  36. private GLabel level;
  37. private GLabel info_1;
  38. private GLabel info_2;
  39. private GLabel pauseLabel;
  40. private int padding;
  41.  
  42.  
  43.  
  44. /**
  45. * Constructs a Game-Board given the listed parameters.
  46. * @param width
  47. * @param height
  48. * @param col
  49. * @param gameName
  50. * @param padding
  51. * @param statusFont
  52. * @param info_1
  53. * @param info_2
  54. */
  55. public GameBoard(double width, double height, Color[] col, String gameName, int padding, int statusFont, String info_1, String info_2){
  56.  
  57. playArea = new GRoundRect(width, height*0.75);
  58. statusArea = new GRect(playArea.getWidth()-(playArea.getArcWidth()*2), height*0.15);
  59. bottom = new GRoundRect(playArea.getWidth(), height*0.1);
  60.  
  61. pauseLabel = new GLabel("PAUSE");
  62. this.padding = padding;
  63. createCanvas(height, col);
  64.  
  65. addBoardElements(col, gameName, padding, statusFont, info_1, info_2);
  66.  
  67. addPauseButton(col, width, padding, statusFont);
  68. }
  69.  
  70.  
  71. /**
  72. * Creates the Game-Board canvas when called by a Constructor
  73. * [========================================================]
  74. *
  75. * @param hgt
  76. * @param colorPack
  77. */
  78. private void createCanvas(double hgt, Color[] colorPack){
  79. statusArea.setFilled(true);
  80. statusArea.setFillColor(colorPack[1]);
  81. statusArea.setColor(colorPack[0]);
  82.  
  83. playArea.setFilled(true);
  84. playArea.setFillColor(colorPack[0]);
  85. playArea.setColor(colorPack[1]);
  86.  
  87. bottom.setFilled(true);
  88. bottom.setFillColor(colorPack[1]);
  89. bottom.setColor(colorPack[0]);
  90.  
  91. add(statusArea, playArea.getArcWidth(), 0);
  92.  
  93. add(playArea, 0, hgt*0.15);
  94.  
  95. add(bottom, 0, playArea.getY()+playArea.getHeight());
  96.  
  97. }
  98.  
  99. /**
  100. * Adds the various screen elements to the already drawn canvas.
  101. * For instance the element that displays the game score is created
  102. * by this method
  103. * [===============================================================]
  104. *
  105. * @param colorPack
  106. * @param gameName
  107. * @param padding
  108. * @param statusFont
  109. * @param info_1
  110. * @param info_2
  111. */
  112. private void addBoardElements(Color colorPack[], String gameName, int padding, int statusFont, String info_1, String info_2) {
  113. addTopLevelElements(colorPack, padding, statusFont, info_1, info_2);
  114.  
  115. addBottomLevelElements(colorPack, gameName);
  116.  
  117. }
  118.  
  119. /*Adds the Game-Board elements displayed at the top of the Playing-Area*/
  120. private void addTopLevelElements(Color[] colorPack, int padding, int statusFont, String info_1, String info_2) {
  121. scoreArea = new GLabel("SCORE: 0");
  122. scoreArea.setFont("Courier-BOLD-"+statusFont);
  123. scoreArea.setColor(colorPack[3]);
  124. add(scoreArea, ((statusArea.getY()+statusArea.getWidth())-((scoreArea.getWidth())+padding)), statusArea.getY()+padding+scoreArea.getAscent());
  125.  
  126. level = new GLabel("LEVEL: 1");
  127. level.setFont("Courier-BOLD-"+statusFont);
  128. level.setColor(colorPack[3]);
  129. add(level, ((statusArea.getY()+statusArea.getWidth())-((level.getWidth())+padding)), (statusArea.getY()+statusArea.getHeight())-(padding/2));
  130.  
  131. if(info_1 != null){
  132. this.info_1 = new GLabel(""+info_1);
  133. this.info_1.setFont("Courier-BOLD-"+statusFont);
  134. this.info_1.setColor(colorPack[3]);
  135. add(this.info_1, (playArea.getArcWidth())+padding, statusArea.getY()+padding+this.info_1.getAscent());
  136. }
  137.  
  138. if(info_2 != null){
  139. this.info_2 = new GLabel(""+info_2);
  140. this.info_2.setFont("Courier-BOLD-"+statusFont);
  141. this.info_2.setColor(colorPack[3]);
  142. add(this.info_2, (playArea.getArcWidth())+padding, (statusArea.getY()+statusArea.getHeight())-(padding/2));
  143. }
  144.  
  145. }
  146.  
  147. /*Adds the Game-Board elements displayed at the bottom of the Playing-Area*/
  148. private void addBottomLevelElements(Color[] colorPack, String gameName) {
  149. name = new GLabel(gameName);
  150. name.setFont("Courier-BOLD-15");
  151. name.setColor(colorPack[2]);
  152.  
  153. add(name, (getWidth()-name.getWidth())/2, (bottom.getY()+bottom.getHeight())-bottom.getArcHeight());
  154.  
  155.  
  156. }
  157.  
  158.  
  159. /**
  160. * Creates and adds the button that pauses and resumes the game
  161. * [==========================================================]
  162. *
  163. * @param col
  164. * @param width
  165. * @param padding
  166. * @param statusFont
  167. */
  168. private void addPauseButton(Color[] col, double width, int padding, int statusFont) {
  169. pauseLabel.setFont("Courier-BOLD-"+statusFont);
  170. pauseLabel.setColor(col[3]);
  171.  
  172. pauseButton = new GRect(pauseLabel.getWidth()+padding*2, pauseLabel.getAscent()+padding*2);
  173. pauseButton.setFilled(true);
  174. pauseButton.setFillColor(col[2]);
  175. pauseButton.setColor(col[0]);
  176. add(pauseButton, (getWidth()-pauseButton.getWidth())/2, (statusArea.getHeight() - pauseButton.getHeight())/2);
  177.  
  178. add(pauseLabel, pauseButton.getX()+padding, pauseButton.getY()+padding+pauseLabel.getAscent());
  179.  
  180. }
  181.  
  182. @Override
  183. public void repaint(){
  184.  
  185. }
  186.  
  187. public boolean isInPlayArea(GObject g){
  188. return contains(playArea, g);
  189. }
  190.  
  191. /**
  192. * @param g1
  193. * @param g2
  194. * @return true if g1 contains g2
  195. */
  196. private boolean contains(GObject g1, GObject g2){
  197. return (g1.getY()<=g2.getY())&&((g1.getY()+g1.getHeight()>=g2.getY()+g2.getHeight()))
  198. &&
  199. (g1.getX()<=g2.getX())&&((g1.getX()+g1.getWidth()>=g2.getX()+g2.getWidth()));
  200. }
  201.  
  202. public boolean yIsInPlayArea(double y, double hgt){
  203. return (this.playArea.getY()<=y)&&((this.playArea.getY()+this.playArea.getHeight()>=y+hgt));
  204. }
  205.  
  206. public boolean xIsInPlayArea(double x, double wdt){
  207. return (this.playArea.getX()<=x)&&((this.playArea.getX()+this.playArea.getWidth()>=x+wdt));
  208. }
  209.  
  210. public boolean outUpwards(double y){
  211. return this.playArea.getY()>y;
  212. }
  213.  
  214. public boolean outDownwards(double y){
  215. return this.playArea.getY()+this.playArea.getHeight()<y;
  216. }
  217.  
  218. public GObject getPlayArea(){
  219. return this.playArea;
  220. }
  221. public GObject getPauseButton(){
  222. return this.pauseButton;
  223. }
  224. public GObject getStatusArea(){
  225. return this.statusArea;
  226. }
  227.  
  228. public void changeState(){
  229. if(pauseLabel.getLabel().equalsIgnoreCase("Start")){
  230. pauseLabel.setLabel("PAUSE");
  231. }
  232. else{
  233. pauseLabel.setLabel("START");
  234. }
  235.  
  236. repaint();
  237. }
  238.  
  239.  
  240. public void updateInfo(int index, String str){
  241.  
  242. switch(index){
  243. case 1:
  244. scoreArea.setLabel("SCORE: "+str);
  245. scoreArea.setLocation((statusArea.getY()+statusArea.getWidth())-((scoreArea.getWidth())+padding), scoreArea.getY());
  246. break;
  247. case 2:
  248. level.setLabel("LEVEL: "+str);
  249. level.setLocation((statusArea.getY()+statusArea.getWidth())-((level.getWidth())+padding), level.getY());
  250. break;
  251. case 3:
  252. info_1.setLabel(""+str);
  253. break;
  254. default:
  255. info_2.setLabel(""+str);
  256. break;
  257. }
  258.  
  259. repaint();
  260. }
  261.  
  262.  
  263. }

More about : review code

December 3, 2012 1:55:36 PM

Correction:
What does line 164 (not 163) do?

I mean "playArea.addMouseMotionListener(this)".
a b L Programming
December 3, 2012 5:18:52 PM

No idea what that means, because GRect class isn't defined in your source code. However, in the future I'd advice naming variables so it would be clear what they are made for from their names.
Related resources
December 3, 2012 7:17:39 PM

Sunius said:
No idea what that means, because GRect class isn't defined in your source code. However, in the future I'd advice naming variables so it would be clear what they are made for from their names.


Sorry, I don't quite understand you.

GRect (which creates a rectangle) is not defined by me. It's defined in the ACM package which I imported.

What's wrong with my naming convention?
a b L Programming
December 4, 2012 3:19:52 AM

For example, take Player class. It's confusing it has field 'player'. Also, there are some variable in GCompound that uses shortenings of words and it's hard to understand them (like bulletArr). And generally, I don't think you want to define same objects inside of class (like bullet inside Bullet class). Bullet class should consist of fields about one bullet and when you write
  1. Bullet bullet = new Bullet()

then a single bullet is created.
December 4, 2012 8:05:48 AM

Sunius said:
For example, take Player class. It's confusing it has field 'player'. Also, there are some variable in GCompound that uses shortenings of words and it's hard to understand them (like bulletArr). And generally, I don't think you want to define same objects inside of class (like bullet inside Bullet class). Bullet class should consist of fields about one bullet and when you write
  1. Bullet bullet = new Bullet()

then a single bullet is created.



Thanks. That's noted.

Best solution

a b L Programming
December 5, 2012 8:19:02 AM
Share

Takwas said:
There are five Classes: Is it OO enough?


It can be improved. You have a class Invader which has several different types, each which behave slightly differently (eg. they all have different max hits and different colours). You are using an enum to switch the behaviour of the class when you should be extending Invader instead. Each derived class can then override the methods and fields of the Invader class which differ depending on the type, while the common members will only be defined once in the parent class.

The rest of your application can then, for the most part, continue to work with Invader objects since derived classes are still valid Invader instances. It won't have to keep using switches and other checks to see what type it's working with because it doesn't care, since each derived class of Invader takes care of its own peculiarities internally.

This also applies to any other similar usages of enums to define types, like the Bullet class.
December 5, 2012 9:40:13 AM

randomizer said:
It can be improved. You have a class Invader which has several different types, each which behave slightly differently (eg. they all have different max hits and different colours). You are using an enum to switch the behaviour of the class when you should be extending Invader instead. Each derived class can then override the methods and fields of the Invader class which differ depending on the type, while the common members will only be defined once in the parent class.

The rest of your application can then, for the most part, continue to work with Invader objects since derived classes are still valid Invader instances. It won't have to keep using switches and other checks to see what type it's working with because it doesn't care, since each derived class of Invader takes care of its own peculiarities internally.

This also applies to any other similar usages of enums to define types, like the Bullet class.



Thanks for pointing that out randomizer. I would like to ask if the new Invader superClass is what is called an Abstract class.

Also, if you were to run the updated version of my code which is posted as one of the comments (NOT THE ORIGINAL POST!) in here:

http://www.dreamincode.net/forums/topic/302496-im-unabl...

You will find out that as the levels get increased the game speed gets slower instead of the contrary. I've looked at my code but nothing seems to be wrong with. Could it be a problem with my CPU or an increased number of computations.
December 8, 2012 3:12:49 AM

Best answer selected by Takwas.
a b L Programming
December 9, 2012 4:41:32 AM

Takwas said:
Thanks for pointing that out randomizer. I would like to ask if the new Invader superClass is what is called an Abstract class.


Only if you declare it as such. Abstract classes are classes that can't be instantiated; that is, you can't call the constructor for one. you are only able to call the constructor for its derived classes (unless they are also marked as abstract and have their own derived classes). A class that has derived classes does not necessarily need to be abstract, there are uses for both abstract and normal classes. A common example for needing an abstract class would be if you want to force all derived classes to provide their own implementation of one or more methods. The method would need to be abstract as well as the parent class that declares it.

Takwas said:
You will find out that as the levels get increased the game speed gets slower instead of the contrary. I've looked at my code but nothing seems to be wrong with. Could it be a problem with my CPU or an increased number of computations.


I don't have the Java compiler installed so I can't actually run it myself. If you have a notably faster or slower computer available you could test it on that to see if it is getting slower because your game speed logic is wrong or due to performance problems (a slow PC will slow down more quickly and vice versa for a faster PC). You might also want to run it against a performance profiler and look for locations in the code where the CPU is spending too much time.
December 9, 2012 7:21:59 AM

randomizer said:
Only if you declare it as such. Abstract classes are classes that can't be instantiated; that is, you can't call the constructor for one. you are only able to call the constructor for its derived classes (unless they are also marked as abstract and have their own derived classes). A class that has derived classes does not necessarily need to be abstract, there are uses for both abstract and normal classes. A common example for needing an abstract class would be if you want to force all derived classes to provide their own implementation of one or more methods. The method would need to be abstract as well as the parent class that declares it.



I don't have the Java compiler installed so I can't actually run it myself. If you have a notably faster or slower computer available you could test it on that to see if it is getting slower because your game speed logic is wrong or due to performance problems (a slow PC will slow down more quickly and vice versa for a faster PC). You might also want to run it against a performance profiler and look for locations in the code where the CPU is spending too much time.



Alright thanks.

BTW, I'm already building in more functionality into the game and yes most of the superclasses are declared abstract (cos I wrote some abstract methods).

Also I'm learning about simulating multiple inheritance with Interfaces, so I've also used a few interfaces like Killable, Shooter...

Indeed, it looks a lot more Object - Oriented with all these new implementations. I really appreciate the fact that you pointed-out about the need for more classes.


In general, it's fun!




----------------------******************------------------
  1. while (ALIVE) {
  2. idea ++;
  3. implement (idea);
  4. }


----------------------******************-----------------
!