2013-02-20 52 views
0

我正在嘗試爲我的Java課程製作一個Breakout遊戲程序,其中包含一組彩色塊(Brick)。我已經成功完成了這個任務,但現在我的老師希望我們添加不同的Bricks子類。他希望的一個子類是一個ColorBrick,它繼承了Brick超類的所有行爲,除了它具有每5個刻度更改一次的顏色數組。構造函數獲取一組顏色而不是單一顏色。在Java中創建我的第一個子類時遇到困難

這是我有我的磚超:

package Breakout; 

import java.awt.Color; 
import java.awt.Graphics; 

    public class Brick { 

     public int x, y, i, j; 
     public Color c; 
     Brick[][] brick; 

     public Brick() { 
     } 

     public Brick(Color c, Brick[][] brick, int i, int j) { 
      this.c = c; 
      this.brick = brick; 
      this.x = i * 40; 
      this.y = j * 10 + 50; 
      this.i = i; 
      this.j = j; 



     } 

     public void tick() { 
     } 

     public void paint(Graphics g) { 
      g.setColor(c); 
      g.fillRect(x, y, Breakout.brickWidth, Breakout.brickHeight); 

     } 

     public void hit(Ball b) { 
      if (b.yThen > y + Breakout.brickHeight) { 
       b.yv = -b.yv; 
       b.yNow = 2 * (y + Breakout.brickHeight) - b.yNow; 
      } 
      if (b.yThen < y) { 
       b.yv = -b.yv; 
       b.yNow = 2 * (y) - b.yNow; 
      } 
      if (b.xThen > x + Breakout.brickWidth) { 
       b.xv = -b.xv; 
       b.xNow = 2 * (x + Breakout.brickWidth) - b.xNow; 
      } 
      if (b.xThen < x) { 
       b.xv = -b.xv; 
       b.xNow = 2 * (x) - b.xNow; 
      } 
      brick[i][j] = null; 
     } 
    } 

這是我到目前爲止我colorBrick子類:

package Breakout; 

import java.awt.Color; 

    public class ColorBrick extends Brick { 

     Color colors[] = {Color.red, Color.green, Color.blue, Color.yellow}; 

     public ColorBrick(Color[] colors, Brick[][] brick, int i, int j){ 
      this.colors = colors; 
      this.brick = brick; 
      this.i = i; 
      this.j = j; 
     } 

     public void tick(){ 

     } 

    } 

在這一點上我已經打了一堵牆我不確定在這裏做什麼。我的老師說由於某種原因,tick方法在超類中需要是空的。如果它需要是空的,他爲什麼要讓我們把它放在那裏?我也不確定我應該把什麼放在子類tick方法中。我是否與我的子類一起朝着正確的方向前進,還是我迄今所做的一切完全錯誤?任何指導將非常感激!

這裏是我的主分會場的代碼,如果它是有用的:

package Breakout; 

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.Random; 
import javax.swing.JPanel; 
import javax.swing.Timer; 

    public class Breakout extends javax.swing.JFrame { 

     public static final int fieldHeight = 600; 
     public static final int fieldWidth = 400; 
     public int diameter = 5; 
     public int xNow = 200 - (diameter/2); 
     public int yNow = 300 - (diameter - 2); 
     public int paddleWidth = 50; 
     public int paddleHeight = 5; 
     public int platform = 580; 
     public static int mousex; 
     public int mousey; 
     public static int brickWidth = 40; 
     public static int brickHeight = 10; 
     public Random randoms = new Random(); 
     Brick[][] bricks = new Brick[arrayWide][arrayHigh]; 
     public static boolean startUp; 
     public static int arrayWide = 10; 
     public static int arrayHigh = 5; 
     Ball ball = new Ball(200 - (diameter/2), 20 /*300 - (diameter /2)*/, 0, 0, diameter, Color.white); 
     Paddle myPaddle = new Paddle(platform, paddleWidth, paddleHeight); 

     /** 
     * Creates new form Breakout 
     */ 
     public Breakout() { 
      initComponents(); 
      clock.start(); 
     } 

     public class MyPanel extends JPanel { 

      @Override 
      public void paint(Graphics g) { 
       super.paint(g); 
       if (startUp) { 
        ball.paint(g); 
       } 
       myPaddle.paint(g); 

       for (int i = 0; i < arrayWide; i++) { 
        for (int j = 0; j < arrayHigh; j++) { 
         if (bricks[i][j] != null) { 
          bricks[i][j].paint(g); 
         } 

        } 
       } 
       // Insert code to paint the scene here. 
       // Use methods in the Graphics class to do the painting 
       // Remember coordinates use (0,0) at the top left 

      } 
     } 
     public Timer clock = new Timer(50, new ActionListener() { // 50ms delay between ticks 
      public void actionPerformed(ActionEvent e) { 
       tick();    // Write a method named tick to advance your game 
       jPanel1.repaint(); 
      } 
     }); // panel is the name of the JPanel that displays the game 

     public void launchball() { 
     } 

     public void tick() { 
      ball.move(); 
      Brick brick2 = brickAt(ball); 
      if (brick2 != null) { 
       brick2.hit(ball); 
      } 


      myPaddle.move(mousex); 
      myPaddle.bounce(ball); 
      System.out.println(); 


     } 

     public Brick brickAt(Ball b) { 
      int j = (int) (b.yNow - 50)/10; 
      int i = (int) (b.xNow/40); 
      if (i < arrayWide && i >= 0 && j < arrayHigh && j >= 0) { 
       return (bricks[i][j]); 



      } 


      return null; 
     } 

     /** 
     * This method is called from within the constructor to initialize the form. 
     * WARNING: Do NOT modify this code. The content of this method is always 
     * regenerated by the Form Editor. 
     */ 
     @SuppressWarnings("unchecked") 
     // <editor-fold defaultstate="collapsed" desc="Generated Code">       
     private void initComponents() { 

      jPopupMenu1 = new javax.swing.JPopupMenu(); 
      jPanel2 = new javax.swing.JPanel(); 
      jPanel1 = new MyPanel(); 
      jLabel1 = new javax.swing.JLabel(); 
      start = new javax.swing.JButton(); 

      org.jdesktop.layout.GroupLayout jPanel2Layout = new org.jdesktop.layout.GroupLayout(jPanel2); 
      jPanel2.setLayout(jPanel2Layout); 
      jPanel2Layout.setHorizontalGroup(
       jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) 
       .add(0, 100, Short.MAX_VALUE) 
      ); 
      jPanel2Layout.setVerticalGroup(
       jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) 
       .add(0, 100, Short.MAX_VALUE) 
      ); 

      setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 

      jPanel1.setBackground(new java.awt.Color(0, 0, 0)); 
      jPanel1.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() { 
       public void mouseMoved(java.awt.event.MouseEvent evt) { 
        mouseMove(evt); 
       } 
      }); 

      org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1); 
      jPanel1.setLayout(jPanel1Layout); 
      jPanel1Layout.setHorizontalGroup(
       jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) 
       .add(0, 400, Short.MAX_VALUE) 
      ); 
      jPanel1Layout.setVerticalGroup(
       jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) 
       .add(0, 600, Short.MAX_VALUE) 
      ); 

      jLabel1.setFont(new java.awt.Font("Hobo Std", 1, 24)); // NOI18N 
      jLabel1.setForeground(new java.awt.Color(153, 51, 255)); 
      jLabel1.setText("Breakout"); 

      start.setFont(new java.awt.Font("Hobo Std", 0, 13)); // NOI18N 
      start.setForeground(new java.awt.Color(255, 51, 0)); 
      start.setText("Start"); 
      start.addActionListener(new java.awt.event.ActionListener() { 
       public void actionPerformed(java.awt.event.ActionEvent evt) { 
        startActionPerformed(evt); 
       } 
      }); 

      org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane()); 
      getContentPane().setLayout(layout); 
      layout.setHorizontalGroup(
       layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) 
       .add(layout.createSequentialGroup() 
        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) 
         .add(layout.createSequentialGroup() 
          .add(164, 164, 164) 
          .add(jLabel1)) 
         .add(layout.createSequentialGroup() 
          .add(15, 15, 15) 
          .add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) 
         .add(layout.createSequentialGroup() 
          .add(175, 175, 175) 
          .add(start))) 
        .addContainerGap(17, Short.MAX_VALUE)) 
      ); 
      layout.setVerticalGroup(
       layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) 
       .add(layout.createSequentialGroup() 
        .add(16, 16, 16) 
        .add(jLabel1) 
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) 
        .add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) 
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) 
        .add(start) 
        .addContainerGap(10, Short.MAX_VALUE)) 
      ); 

      pack(); 
     }// </editor-fold>       

     private void mouseMove(java.awt.event.MouseEvent evt) {       
      mousex = evt.getX(); 
      mousey = evt.getY(); 
     }       

     private void startActionPerformed(java.awt.event.ActionEvent evt) {          

      startUp = true; 
      ball.xNow = 200 - (diameter/2); 
      ball.yNow = 300 - (diameter - 2); 
      ball.xv = 0; 
      ball.yv = 8; 
      for (int i = 0; i < arrayWide; i++) { 
       for (int j = 0; j < arrayHigh; j++) { 
        if ((j % 2 == 0 && i % 2 == 0) || (j % 2 == 1 && i % 2 == 1)) { 
         bricks[i][j] = new Brick(Color.magenta, bricks, i, j); 
        } else { 
         bricks[i][j] = new Brick(Color.gray, bricks, i, j); 
        } 

       } 
      } 
     }          

     /** 
     * @param args the command line arguments 
     */ 
     public static void main(String args[]) { 
      /* Set the Nimbus look and feel */ 
      //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> 
      /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. 
      * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
      */ 
      try { 
       for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { 
        if ("Nimbus".equals(info.getName())) { 
         javax.swing.UIManager.setLookAndFeel(info.getClassName()); 
         break; 
        } 
       } 
      } catch (ClassNotFoundException ex) { 
       java.util.logging.Logger.getLogger(Breakout.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
      } catch (InstantiationException ex) { 
       java.util.logging.Logger.getLogger(Breakout.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
      } catch (IllegalAccessException ex) { 
       java.util.logging.Logger.getLogger(Breakout.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
      } catch (javax.swing.UnsupportedLookAndFeelException ex) { 
       java.util.logging.Logger.getLogger(Breakout.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
      } 
      //</editor-fold> 

      /* Create and display the form */ 
      java.awt.EventQueue.invokeLater(new Runnable() { 
       public void run() { 
        new Breakout().setVisible(true); 
       } 
      }); 
     } 
+0

你可以發佈'Breakout'的代碼嗎? – amphibient 2013-02-20 22:29:15

+0

是的! Breakout代碼添加到底部。 – FionaCat86 2013-02-20 22:30:07

+0

將其添加到原始帖子 – amphibient 2013-02-20 22:31:13

回答

0

因爲這聽起來像homework.classwork,我不打算進入的全部細節。

推測,某事(TBD)會每隔5秒(或定期)調用tick()。正常的Brick什麼都不做。您的ColorBrick應每5秒更換一次下一個顏色。不知何故,它需要知道它是當前的顏色,並轉到下一個顏色。

0

需要在Brick中有一個空的tick方法,這樣另一個類只需要處理Bricks;調用tick的類不需要知道它是Brick還是ColorBricktick的行爲由運行時類指定;這是多態性 - 相關類對同一方法調用作出不同反應的能力。

方法需要跟蹤生成的滴答數。當需要時,它會改變顏色變量c

我可能做出的一個額外更改是在您的ColorBrick構造函數中:利用super來調用超類的構造函數,以免重複您的代碼。

此外,聲明你的實例變量(cxy等)protected所以只有類本身和子類必須將它們直接訪問。

0

tick方法需要存在於父類中,因爲我猜測對於存在的每個Brick,都會調用tick()(可能在主Breakout類中,可能在循環中)。超類中的tick()方法指定了「默認」行爲,即什麼也不做。對於ColorBrick類,當調用tick時,顏色需要每5個刻度更改一次,因此您需要在子類(ColorBrick)中指定這種特殊情況的行爲。

要做到這一點,ColorBrick需要一種方法來保持tick()被調用的次數。一旦你添加了一些可以做到這一點的代碼,你就可以考慮改變某些刻度上的ColorBrick的顏色:你的ColorBrick已經「知道」它的當前顏色,因爲它從具有Color屬性的Brick c),所以這是一個改變某些刻度的價值的情況。

我已經故意模糊了,因爲我不想爲你完成任務,但請隨時提出任何問題。

0

你需要實現你的tick方法ColorBrick類似如下:

private int i = 0; 
public void tick(){ 
    c = colors[i++ % colors.length]; 
} 

現在,讓您的圖形應用程序時,你可以簡單地使用Brick類來創建ColorBricks爲好。例如,加入多個磚,使壁:

Brick[][] wall = new Brick[5][5]; 

在上述陣列一些Brick的可能是ColorBrick。這允許每個Brick對象具有通用接口,即tick()方法。但是對於ColorBrick,此方法實際上會更改Brick的顏色,因爲在其他情況下Brick它什麼都不做!

你可以做更多的東西,如DancingBrick,每tick後改變大小。您的圖形實現不會被要求進行大幅改變,以便添加不同種類的Brick,因爲它使用的基本類型爲Brick