2015-10-15 78 views
-1

我想讓我的生活程序面向對象的遊戲遵循我的教授的風格指南,並沒有失分,但我無法弄清楚如何以我的程序編碼的方式這樣做。如何讓我的遊戲生活程序面向對象?

import java.awt.*; 
import java.awt.event.*; 
import java.util.Hashtable; 

import javax.swing.*; 

public class GameOfLife2 extends JFrame implements ActionListener { 
static final Color[] color = { Color.LIGHT_GRAY, Color.BLUE }; 
// size in pixel of every label 
static final int size = 15; 
static final Dimension dim = new Dimension(size, size); 

// the cells labels 
private LifeLabel[][] label; 
// timer that fires the next feneration 
private Timer timer; 
// generation counter 
private int generation = 0; 
private JLabel generationLabel = new JLabel("Generation: 0"); 
// the 3 buttons 
private JButton bClear = new JButton("Clear"), bPause = new JButton("Pause"), bGo = new JButton("Go"); 
// the slider for the speed 
JSlider slider = new JSlider(0, 5000); // 0 to 5000 milliseconds (5 seconds) 
// state of the game (running or pause) 
private boolean gameRunning = false; 
// if the mouse is down or not 
private boolean mouseDown = false; 

GameOfLife2(int nbRow, int nbCol) { 
    super("GameOfLife"); 
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 

    // create the labels (2 more on each size) these wont be shown 
    // but will be used in calculating the cells alive around 
    label = new LifeLabel[nbRow + 2][nbCol + 2]; 
    for (int r = 0; r < nbRow + 2; r++) { 
     for (int c = 0; c < nbCol + 2; c++) { 
      label[r][c] = new LifeLabel(); 
     } 
    } 

    // panel in the center with the labels 
    JPanel panel = new JPanel(new GridLayout(nbRow, nbCol, 1, 1)); 
    panel.setBackground(Color.BLACK); 
    panel.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 

    // add each label (not the one on the border) to the panel and add to 
    // each of them its neighbours 
    for (int r = 1; r < nbRow + 1; r++) { 
     for (int c = 1; c < nbCol + 1; c++) { 
      panel.add(label[r][c]); 
      label[r][c].addNeighbour(label[r - 1][c]); // North 
      label[r][c].addNeighbour(label[r + 1][c]); // South 
      label[r][c].addNeighbour(label[r][c - 1]); // West 
      label[r][c].addNeighbour(label[r][c + 1]); // East 
      label[r][c].addNeighbour(label[r - 1][c - 1]); // North West 
      label[r][c].addNeighbour(label[r - 1][c + 1]); // North East 
      label[r][c].addNeighbour(label[r + 1][c - 1]); // South West 
      label[r][c].addNeighbour(label[r + 1][c + 1]); // South East 
     } 
    } 

    // now the panel can be added 
    add(panel, BorderLayout.CENTER); 

    // the bottom panel with the buttons the generation label and the slider 
    // this panel is formed grid panels 
    panel = new JPanel(new GridLayout(1, 3)); 
    // another panel for the 3 buttons 
    JPanel buttonPanel = new JPanel(new GridLayout(1, 3)); 
    bClear.addActionListener(this); 
    buttonPanel.add(bClear); 
    bPause.addActionListener(this); 
    bPause.setEnabled(false); // game is pause the pause button is disabled 
    buttonPanel.add(bPause); 
    bGo.addActionListener(this); 
    buttonPanel.add(bGo); 
    // add the 3 buttons to the panel 
    panel.add(buttonPanel); 
    // the generation label 
    generationLabel.setHorizontalAlignment(SwingConstants.CENTER); 
    panel.add(generationLabel); 
    // the slider 
    slider.setMajorTickSpacing(1000); 
    slider.setMinorTickSpacing(250); 
    slider.setPaintTicks(true); 
    // the labels for the Slider 
    Hashtable<Integer, JLabel> labelTable = new Hashtable<Integer, JLabel>(); 
    for (int i = 0; i <= 5; i++) { 
     labelTable.put(new Integer(i * 1000), new JLabel("" + i)); 
    } 
    slider.setLabelTable(labelTable); 
    slider.setPaintLabels(true); 

    panel.add(slider); 
    // in the JFrame 
    add(panel, BorderLayout.SOUTH); 

    // put the frame on 
    setLocation(20, 20); 
    pack(); 
    setVisible(true); 
    // start the thread that run the cycles of life 
    timer = new Timer(5000 - slider.getValue(), this); 
} 

// called by the Timer and the JButtons 
public synchronized void actionPerformed(ActionEvent e) { 
    // test the JButtons first 
    Object o = e.getSource(); 
    // the clear button 
    if (o == bClear) { 
     timer.stop(); // stop timer 
     gameRunning = false; // flag gamme not running 
     bPause.setEnabled(false); // disable pause button 
     bGo.setEnabled(true); // enable go button 
     // clear all cells 
     for (int r = 1; r < label.length - 1; r++) { 
      for (int c = 1; c < label[r].length - 1; c++) { 
       label[r][c].clear(); 
      } 
     } 
     // reset generation number and its label 
     generation = 0; 
     generationLabel.setText("Generation: 0"); 
     return; 
    } 
    // the pause button 
    if (o == bPause) { 
     timer.stop(); // stop timer 
     gameRunning = false; // flag not running 
     bPause.setEnabled(false); // disable myself 
     bGo.setEnabled(true); // enable go button 
     return; 
    } 
    // the go button 
    if (o == bGo) { 
     bPause.setEnabled(true); // enable pause button 
     bGo.setEnabled(false); // disable myself 
     gameRunning = true; // flag game is running 
     timer.setDelay(5000 - slider.getValue()); 
     timer.start(); 
     return; 
    } 
    // not a JButton so it is the timer 
    // set the delay for the next time 
    timer.setDelay(5000 - slider.getValue()); 
    // if the game is not running wait for next time 
    if (!gameRunning) 
     return; 
    ++generation; 
    generationLabel.setText("Generation: " + generation); 
    for (int r = 0; r < label.length; r++) { 
     for (int c = 0; c < label[r].length; c++) { 
      label[r][c].checkState(); 
     } 
    } 
    for (int r = 0; r < label.length; r++) { 
     for (int c = 0; c < label[r].length; c++) { 
      label[r][c].updateState(); 
     } 
    } 
} 

// to start the whole thing as a Java application 
public static void main(String[] arg) { 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      new GameOfLife2(30, 50); 
     } 
    }); 
} 

// A class that extends JLabel but also check for the neigbour 
// when asked to do so 
class LifeLabel extends JLabel implements MouseListener { 
    private int state, newState; 
    private int nbNeighbour; 
    private LifeLabel[] neighbour = new LifeLabel[8]; 

    LifeLabel() { 
     state = newState = 0; // Dead 
     setOpaque(true); // so color will be showed 
     setBackground(color[0]); 
     addMouseListener(this); // to select new LIVE cells 
     this.setPreferredSize(dim); 
    } 

    // to add a neibour 
    void addNeighbour(LifeLabel n) { 
     neighbour[nbNeighbour++] = n; 
    } 

    // to see if I should live or not 
    void checkState() { 
     // number alive around 
     int nbAlive = 0; 
     // see the state of my neighbour 
     for (int i = 0; i < nbNeighbour; i++) 
      nbAlive += neighbour[i].state; 
     // newState 
     if (state == 1) { // if alive 
      if (nbAlive < 2) // 1.Any live cell with fewer than two live 
           // neighbours dies 
       newState = 0; 
      if (nbAlive > 3) // 2.Any live cell with more than three live 
           // neighbours dies 
       newState = 0; 
     } else { 
      if (nbAlive == 3) // 4.Any dead cell with exactly three live 
           // neighbours becomes a live cell 
       newState = 1; 
     } 
    } 

    // after the run switch the state to new state 
    void updateState() { 
     if (state != newState) { // do the test to avoid re-setting same 
            // color for nothing 
      state = newState; 
      setBackground(color[state]); 
     } 
    } 

    // called when the game is reset/clear 
    void clear() { 
     if (state == 1 || newState == 1) { 
      state = newState = 0; 
      setBackground(color[state]); 
     } 
    } 

    @Override 
    public void mouseClicked(MouseEvent arg0) { 
    } 

    // if the mouse enter a cell and it is down we make the cell alive 
    public void mouseEntered(MouseEvent arg0) { 
     if (mouseDown) { 
      state = newState = 1; 
      setBackground(color[1]); 
     } 
    } 

    @Override 
    public void mouseExited(MouseEvent arg0) { 
    } 

    // if the mouse is pressed on a cell you register the fact that it is 
    // down 
    // and make that cell alive 
    public void mousePressed(MouseEvent arg0) { 
     mouseDown = true; 
     state = newState = 1; 
     setBackground(color[1]); 
    } 

    // turn off the fact that the cell is down 
    public void mouseReleased(MouseEvent arg0) { 
     mouseDown = false; 
    } 
} 
} 

我從來都沒有非常善於使我的計劃是面向對象的,通常堅持一個類,但我目前正在被迫做出面向這一計劃的對象。

如果您不僅可以幫我改這個程序是OOP,也給我如何採取一個程序,是不是OOP,使這種方式的提示,那將是絕對精彩。

+0

一個鐵道部的Java具體的事情,如果你想添加註釋的方法,使用Javadoc註釋:/ **註釋* /,看到http://www.oracle.com/technetwork/java/javase/documentation /index-137868.html –

回答

1

OOP是關於對象(顧名思義:))。因此,爲了改進您的OOP編程,首先要考慮遊戲中各個組件的常見屬性。

你已經做了,對於lifeLabel。已經被設置爲鄰居。而不是這種方法,每個鄰居應該是一個對象,你可以有一個列表。然後更新狀態並檢查狀態可以被最小化並且更容易理解。

世上本沒有很多變化,使你的代碼OOP

3

只有一個辦法真正進入OO:實踐。想出解決問題的表示,在你看到的元素中尋找可辨別的實體,並設計表示這些元素的類。規劃這些元素之間的相互作用和關係。

然後實現,看看有什麼效果很好,什麼不可行。即使只有一個特定的選擇沒有很好地發揮作用,你也會學到,即使從你的不好的選擇中。

一開始,想象遊戲人生,如果它是在你的眼前一個真實的,物理世界。不同的實體應該是容易的,並且這是設計的好開始。

當然,我們可以建議你到抽象這樣那樣爲一個或另一個對象,但如果你不這樣做的工作很多自己的選擇將永遠都是一個謎給你。只有實際做出自己的選擇,你纔會真正學到一些東西。

+0

我喜歡這個答案。最後一段碰撞了頭部。你在OOP中想的越多,就越容易。 –