2014-02-07 15 views
1

我對如何使用ArrayList有一些疑問。我是java的新手,所以我想知道它的實際用法和使用它的正確方法。我被告知我可以使用數組列表來顯示我的對象,但似乎無法理解如何將其添加到我當前的項目中。如何使用ArrayList顯示移動對象?

我正在同時顯示3個管道,用定時器控制速度和刷新率。我想我終於明白了JFrameJPanel的基礎知識,但最近我已經介紹了神祕的CardLayout,所以任何關於這方面的例子都會有所幫助。

到目前爲止,我已經能夠添加一個開始菜單,其中包含一個播放按鈕。在用戶點擊「Play!」後,菜單應該被遊戲面板所取代,並且設置playerIsReadytrue,啓動定時器,該定時器應該向屏幕添加三個pipe.java實例,每個定位器被調用timer 「速度」。所有管道都從屏幕右側開始。

我想更好地瞭解如何在每個pipe對象之間添加間距。 我也對如何加載和打印本地圖像到屏幕感興趣。

如果您嘗試回答以上任何問題,請詳細解釋每一步,因爲我是Java的新手。感謝您花時間提供幫助。如果你不是在這裏回答一個問題,我希望你能從這裏的任何代碼/答案中學到一些東西。

遊戲

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.*; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import javax.swing.border.EmptyBorder; 
import javax.swing.SwingUtilities; 

public class Game { 

    public static void main(String[] args) { 
     Runnable r = new Runnable() { 
      @Override 
      public void run() {    
       // the GUI as seen by the user (without frame) 
       final CardLayout cl = new CardLayout(); 
       final JPanel gui = new JPanel(cl); 
       // remove if no border is needed 
       gui.setBorder(new EmptyBorder(10,10,10,10)); 

       JPanel menu = new JPanel(new GridBagLayout()); 
       JButton playGame = new JButton("Play!"); 
       ActionListener playGameListener = new ActionListener() { 

        @Override 
        public void actionPerformed(ActionEvent e) { 
         cl.show(gui, "game"); 
        } 
       }; 
       playGame.addActionListener(playGameListener); 
       Insets margin = new Insets(20, 50, 20, 50); 
       playGame.setMargin(margin); 
       menu.add(playGame); 
       gui.add(menu); 
       cl.addLayoutComponent(menu, "menu"); 

       final JPanel pipes = new Pipes(); 
       gui.add(pipes); 
       cl.addLayoutComponent(pipes, "game"); 

       JFrame f = new JFrame("Pipes Game"); 
       f.add(gui); 
       // Ensures JVM closes after frame(s) closed and 
       // all non-daemon threads are finished 
       f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
       // See http://stackoverflow.com/a/7143398/418556 for demo. 
       f.setLocationByPlatform(true); 

       // ensures the frame is the minimum size it needs to be 
       // in order display the components within it 
       f.pack(); 
       // should be done last, to avoid flickering, moving, 
       // resizing artifacts. 
       f.setVisible(true); 

       /*if (playerIsReady) { 
        Timer speed = new Timer(10, new ActionListener() { //pipe speed 
         @Override 
         public void actionPerformed(ActionEvent e) { 
          pipes.move(); 
         } 
        }); 
        speed.start(); 

        Timer refresh = new Timer(30, new ActionListener() { //refresh rate 
         @Override 
         public void actionPerformed(ActionEvent e) { 
          pipes.repaint(); 
         } 
        }); 
        refresh.start(); 
       }*/ 
      } 
     }; 
     // Swing GUIs should be created and updated on the EDT 
     // http://docs.oracle.com/javase/tutorial/uiswing/concurrency 
     SwingUtilities.invokeLater(r); 
    } 
} 

PipeObject

import java.awt.Graphics; 

public class PipeObject { 
    //Declare and initialiaze variables 
    int x1 = 754;    //xVal start 
    int x2 = 75;    //pipe width 
           //total width is 83 
    int y1 = -1;    //yVal start 
    int y2 = setHeightVal(); //pipe height 
    int gap = 130;    //gap height 

    public void drawPipe(Graphics g) { 

     g.clearRect(0,0,750,500);      //Clear screen 
     g.drawRect(x1,y1,x2,y2);      //Draw part 1 
     g.drawRect(x1-3,y2-1,x2+6,25);     //Draw part 2 
     g.drawRect(x1-3,y2+25+gap,x2+6,25);    //Draw part 3 
     g.drawRect(x1,y2+25+gap+25,x2,500-y2-49-gap); //Draw part 4 
    } 

    public void move() { 
     x1--; 
    } 

    public int getMyX() { //To determine where the pipe is horizontally 
     return x1-3; 
    } 

    public int getMyY() { //To determine where the pipe is vertically 
     return y2+25; 
    } 

    public int setHeightVal() {  //Get a random number and select a preset height 
     int num = (int)(9*Math.random() + 1); 
     int val = 0; 
     if (num == 9) 
     { 
      val = 295; 
     } 
     else if (num == 8) 
     { 
      val = 246; 
     } 
     else if (num == 7) 
     { 
      val = 216; 
     } 
     else if (num == 6) 
     { 
      val = 185; 
     } 
     else if (num == 5) 
     { 
      val = 156; 
     } 
     else if (num == 4) 
     { 
      val = 125; 
     } 
     else if (num == 3) 
     { 
      val = 96; 
     } 
     else if (num == 2) 
     { 
      val = 66; 
     } 
     else 
     { 
      val = 25; 
     } 
     return val; 
    } 
} 

回答

2

所以你PipeObject類只是一個數據模型類。 drawPipe方法實際上並沒有自己繪製任何東西。您需要一個JPanel類來呈現此數據,並調用drawPipe方法中JPanelpaintComponent方法,並將Graphics上下文傳遞給它。

另外,如果你想要有不同的x位置值,你需要一個構造函數來獲取不同的x值。看起來y值應該是相同的,因爲總是會保持在相同的軸上。你在你的PipeObject類的構造函數應該是這個樣子

int x1; // no need to give them values. 
int x2; // This will be done when you create a new PipeObject object 

public PipeObject(int x1, int x2) { 
    this.x1 = x1; 
    this.x1 = x2; 
} 

而且當你創建new PipeObject對象,你會通過不同的值給它。總結以上兩點,你會有這樣的事情。

public class PipePanel extends JPanel { 
    List<PipeObject> pipes = new ArrayList<PipeObject>(); 

    public PipePanel() { 
     pipes.add(new PipeObject(100, 90)); 
     pipes.add(new PipeObject(300, 290)); 
     pipes.add(new PipeObject(500, 490)); 
    } 

    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     for (PipeObject pipe : pipes){ 
      pipe.drawPipe(g); 
     } 
    } 
} 

然後你就可以的PipesPanel您添加相框和實例。另外要注意,在你PipesPanel應覆蓋getPreferredSize,所以它有一個偏好的尺寸,你可以pack()框架

@Override 
public Dimension getPreferredSize() { 
    return new Dimension(800, 500); // or what ever values you want for screen size 
} 

而且,當你想操縱或動畫PipeObject你只需要調用的一個其methods like移動(), then call repaint`。喜歡的東西

Timer timer = new Timer(50, new ActionListener(){ 
    public void actionPerformed(ActionEvent e) { 
     for (PipeObject pipe : pipes) { 
      pipe.move(); 
     } 
     repaint(); 
    } 
}); 
+0

這將需要一些練習,但能說明問題 –

+0

按住[**真正的大指數**](http://docs.oracle.com/javase/tutorial/reallybigindex.html)作爲參考教程。嘗試每天完成一些部分。它會讓你瞭解java的基礎知識。對象是一個非常基本的Java概念。您可以從[**面向對象編程概念**]一節開始(http://docs.oracle.com/javase/tutorial/java/concepts/index.html)。快樂編碼! –

+0

任何時候,如果你有一個你不明白的概念,95%的時間,你會在鏈接中找到參考教程。 –