为什么我的椭圆形没有向右移动?我有一个游戏循环,但不知何故,圆圈停留在它出现的地方,而不是每个循环向右移动2个像素。 奇怪的是它在实际绘画之前进入循环。但随后图形对象出现(在固定位置)。
public class GamePanel extends JPanel implements Runnable {
public static int WIDTH = 1024;
public static int HEIGHT = WIDTH / 16 * 9;
private Thread t1;
boolean running;
private int FPS = 60;
private long optimalTime = 1000 / FPS;
private int heroX = 200;
private int heroY = 200;
public void addNotify(){
Dimension size = new Dimension(WIDTH,HEIGHT);
setPreferredSize(size);
setFocusable(true);
requestFocus();
running = true;
t1 = new Thread(this);
t1.start();
}
public void paintComponent (Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.WHITE);
g2.fillRect(0, 0, WIDTH, HEIGHT);
g2.setColor(Color.BLACK);
g2.fillOval(heroX, heroY, 50, 50);
g2.dispose();
}
public void run() {
long startTime;
long passedTime;
long waitTime;
while (running){
startTime = System.nanoTime();
System.out.println("Runs");
update();
draw();
repaint();
passedTime = System.nanoTime() - startTime;
waitTime = optimalTime - passedTime / 1000000;
try {
if (waitTime <= 0){
waitTime = 2;
}
Thread.sleep(waitTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void draw() {
}
private void update() {
heroX += 2;
}
}
答案 0 :(得分:1)
你应该使用swing Timer而不是尝试使用线程。如果您需要在后台执行某些操作,请使用SwingWorkers。如果你真的需要(你需要一个扭曲的用户案例需要这样做),你可以使用自己的线程和摆动,但是在你很好地掌握线程和之前不要尝试这样做。 em>使用swing的方式。
public class GamePanel extends JPanel {
private static final int DELAY = 1000 / 60;
private final Timer timer;
// ...
private int heroX = 200;
private int heroY = 200;
public GamePanel() {
timer = new Timer(DELAY, new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
update();
repaint();
}
});
// ...
}
// No need to make this public
@Override
protected void paintComponent (Graphics g) {
// ...
}
@Override
public Dimension getPreferredSize() {
// Overriding is cleaner than using set*Size(). Search old questions to see why
}
public void startAnimation() {
timer.start();
}
public void stopAnimation() {
timer.stop();
}
// Remove addNotify() and run()
}
答案 1 :(得分:0)
阅读和测试后,我只想这样做。它可以按预期工作,即使paintComponent在EDT之外也是如此。
public class GamePanel extends JPanel implements Runnable {
public static int WIDTH = 1024;
public static int HEIGHT = WIDTH / 16 * 9;
private int cordX = WIDTH / 2;
private Thread t1;
private boolean running = true;
public void addNotify() {
super.addNotify();
Dimension size = new Dimension (WIDTH, HEIGHT);
setPreferredSize(size);
t1 = new Thread(this);
t1.start();
}
public void paintComponent(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(0, 0, WIDTH, HEIGHT);
g.setColor(Color.BLACK);
g.fillOval(cordX, HEIGHT /2 , 20, 20);
}
public void run() {
while(running) {
cordX += 2;
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}