2016-11-12 58 views
2

我一直在用Java 8編寫2D圖形的教程,NetBeans給了我一個提示,即Thread.Sleep會影響性能。不過,儘管我已經能夠找到更好的方法,但我一直無法找到一種方法來將它們包含進來,而不會讓代碼變得麻煩。讓線程睡眠的更好方法

package platformer; 

import java.awt.*; 
import javax.swing.*; 
import java.util.Scanner; 

@SuppressWarnings("serial") 
public class Platformer extends JPanel { 
    int x = 0;//Sets the starting coords. of the ball 
    int y = 0; 
    private void moveBall() {//How much the ball moves by 
     x = x+1; 
     y = y+1; 
    } 
    @Override 
     public void paint(Graphics g) {//Essentially al the graphics functions 
     super.paint(g); 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
       RenderingHints.VALUE_ANTIALIAS_ON); 
     g2d.fillOval(x, y, 30, 30); 
    } 

    public static void main(String[] args) throws InterruptedException { 
     Scanner reader = new Scanner(System.in); 
     Scanner reader1 = new Scanner(System.in); 
     System.out.print("Enter an x-value for the window (whole numbers only): "); 
     int setx = reader.nextInt(); 
     System.out.print("Enter a y-value for the window (whole numbers only): "); 
     int sety = reader.nextInt(); 

     JFrame gameFrame = new JFrame("Sample Frame");//Makes the window variable w/ the name in quotations. 
     Platformer game = new Platformer();//'Copies' the graphics functions above into a variable 
     gameFrame.add(game);//Adds the above variable into th window 
     gameFrame.setSize(setx,sety);//Sets the resolution/size of the window(x,y) 
     gameFrame.setVisible(true);//Makse the window visible 
     gameFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//Makes the window close when the close button is hit 

     while (true){ 
      game.moveBall(); 
      game.repaint(); 
      Thread.sleep(10); 
     } 
    }  
} 

我不知道我怎麼能有一個更好的辦法,使在一個循環中線程睡眠,或以其他方式NetBeans的只是做循環。

+0

Netbeans的可能不明白,爲什麼你使用'的Thread.sleep(',並給你一個錯誤的提示。 – Kayaman

+0

我在想自己 - 非常合理的解釋。 –

回答

1

而是在while(true)使用Thread.sleep(10),你可以使用ScheduledExecutorService調用爲每10秒moveBall()paint()如下圖所示賦予更清潔的方式,如下圖所示:

public class Platformer extends JPanel implements Runnable { 

    int x = 0;//Sets the starting coords. of the ball 
    int y = 0; 

    public void add() { 
      JFrame gameFrame = new JFrame("Sample Frame");//Makes the window variable w/ the name in quotations. 
     Platformer game = new Platformer();//'Copies' the graphics functions above into a variable 
     gameFrame.add(game);//Adds the above variable into th window 
     gameFrame.setSize(setx,sety);//Sets the resolution/size of the window(x,y) 
     gameFrame.setVisible(true);//Makse the window visible 
     gameFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//Makes the window close when the close button is hit 
    } 

     private void moveBall() {//How much the ball moves by 
     x = x+1; 
     y = y+1; 
    } 


    @Override 
     public void paint(Graphics g) {//Essentially al the graphics functions 
     super.paint(g); 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
       RenderingHints.VALUE_ANTIALIAS_ON); 
     g2d.fillOval(x, y, 30, 30); 
    } 


    @Override 
    public void run() { 
     //this code will be executed for every 10 seconds 
     moveBall(); 
     paint(); 
    } 


    public static void main(String[] args) throws InterruptedException { 
     Scanner reader = new Scanner(System.in); 
     Scanner reader1 = new Scanner(System.in); 
     System.out.print("Enter an x-value for the window (whole numbers only): "); 
     int setx = reader.nextInt(); 
     System.out.print("Enter a y-value for the window (whole numbers only): "); 
     int sety = reader.nextInt(); 

     JFrame gameFrame = new JFrame("Sample Frame");//Makes the window variable w/ the name in quotations. 
     Platformer game = new Platformer();//'Copies' the graphics functions above into a variable 
     gameFrame.add(game);//Adds the above variable into th window 
     gameFrame.setSize(setx,sety);//Sets the resolution/size of the window(x,y) 
     gameFrame.setVisible(true);//Makse the window visible 
     gameFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//Makes the window close when the close button is hit 

     //schedule it to run for every 10 seconds 
     //this calls the run() method above 
     ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); 
     scheduler.scheduleAtFixedRate(game, 0, 10, TimeUnit.SECONDS); 

    }  
} 
+0

你不應該從'paintComponent'覆蓋繪畫嗎? [參考價格](http://www.oracle.com/technetwork/java/painting-140037.html#swing):'Swing程序應該重寫paintComponent(),而不是覆蓋塗料()' –

+0

是,事實上,來自OP,我的答案只關注沒有Thread.sleep(10)的更好方法。 – developer

2

雖然我能夠找到一些更好的方法

那麼你不覺得你應該告訴我們的方法,你已經找到,所以我們不會花時間去小號你已經知道的uggetions?我們不介意讀者,我們無法猜測您嘗試了什麼。

我一直沒有找到一種方法來包含它們,而不會弄亂你的代碼。

那麼,你的代碼應該重新設計。

您的代碼的動畫應該是您的遊戲面板的功能,而不是main()方法。所以你應該有你的面板中內置的startGame()stopGame()這樣的方法,你可以調用它。

Netbeans給了我一個暗示,做thread.sleep會影響性能。

是一般,因爲通常代碼爲一些用戶操作的結果執行,代碼執行的Event Dispatch Thread (EDT)你不應該使用Thread.sleep()方法。由於美國東部時間公司負責繪製圖形用戶界面,所以你一直告訴它睡覺,這顯然會影響性能。

但是,在你的情況下,循環邏輯不在EDT上執行,所以它不應該是一個問題(除了總​​體設計問題)。

實際上,你不應該使用循環。相反,您應該使用Swing Timer來安排動畫。

另請參閱Concurrency in Swing上的教程部分,該部分將詳細解釋EDT以及爲什麼Swing組件應在EDT上更新。 )