我一直在做一个关于 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 只执行循环。
好吧,你虽然我已经能够找到几种更好的方法
不认为你应该告诉我们你找到的方法,这样我们就不会花时间做你已经知道的谎言吗?我们不是读心者,我们无法猜测您尝试过什么。
我一直无法找到一种方法来包含它们而不会弄乱您的代码。
好吧,无论如何,您的代码都应该重新设计。
代码的动画应该是游戏面板的功能,而不是main((方法。因此,您应该在面板中内置startGame()
和stopGame()
等方法,以便您可以调用这些方法。
Netbeans 给了我一个提示,做 thread.sleep 会影响性能。
是的,一般来说,您不应该使用 Thread.sleep((,因为通常代码是作为某些用户操作的结果执行的,并且代码在Event Dispatch Thread (EDT)
上执行。由于 EDT 负责绘制 GUI,因此您一直告诉它进入睡眠状态,因此这显然会影响性能。
但是,在您的情况下,循环逻辑不会在 EDT 上执行,因此它应该不是问题(整体设计问题除外(。
实际上,您不应该使用循环。相反,您应该使用摆动计时器来安排动画。
另请查看教程中关于Concurrency in Swing
的部分,该部分将解释有关EDT
的更多信息以及为什么应该在EDT
上更新 Swing 组件。
而不是在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);
}
}