我在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 :(得分:2)
虽然我已经找到了几种更好的方法
你觉得你不应该告诉我们你找到的方法,所以我们不花时间制作你已经知道的建议吗?我们不介意读者,我们无法猜测你尝试过的东西。
我还没有找到一种方法来包含它们而不会弄乱你的代码。
嗯,无论如何,你的代码应该重新设计。
代码的动画应该是游戏面板的功能,而不是main()方法。因此,您应该在面板中内置startGame()
和stopGame()
等可以调用的方法。
Netbeans给了我一个提示,即执行thread.sleep会影响性能。
通常,您不应该使用Thread.sleep(),因为通常代码是由某些用户Action执行的,并且代码在Event Dispatch Thread (EDT)
上执行。由于EDT负责绘制GUI,你一直告诉它要睡觉,这显然会影响性能。
但是,在您的情况下,循环逻辑不会在EDT上执行,所以它不应该是一个问题(除了整体设计问题)。
实际上你不应该使用循环。相反,您应该使用Swing Timer来安排动画。
另请参阅Concurrency in Swing
教程中的部分,该部分将详细介绍EDT
以及为什么应在EDT
上更新Swing组件。
答案 1 :(得分:1)
您可以使用Thread.sleep(10)
每隔10秒调用while(true)
和ScheduledExecutorService
,而不是在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);
}
}