gpt4 book ai didi

java - 使用线程时 Swing GUI 卡住

转载 作者:行者123 更新时间:2023-11-30 05:38:44 33 4
gpt4 key购买 nike

我正在编写一款突破性游戏,除了一件小事外,一切都运行良好。

我有一个从线程和 RepainterThread 扩展的球对象,它可以实现 Runnable 或扩展 Thread,该线程调用 Paint 方法,该方法用砖 block 、桨和球重新渲染游戏场

我有一个连接所有事物的 Singelton GameController。

我有一个带有 isActive boolean 值的 GameState 来决定游戏是否应该暂停。

我开始游戏,我可以玩并且程序按其应有的方式运行。当球击中一切正常时,框架被绘制,球移动,砖 block 破裂。

然后我通过一个按钮暂停游戏,我将“Active”设置为 false。球按其应有的方式停止。然后我点击继续按钮,isActive 再次为 true。球对象再次开始运行,Repainter Thread 的运行方法也被触发,但 Swing Frame 完全卡住。

我尝试了各种方法,这些是我最接近的方法。

我花了几天时间,请帮忙

public class Ball extends MovingObject {

private double hSpeed; // Horizontal velocity
private double vSpeed; // Vertical velocity

public Ball() {
this.color = Color.MAGENTA;
this.height = GameSettings.ballSize;
this.width = GameSettings.ballSize;
this.position = new Point2D.Double(GameSettings.defaultBallX, GameSettings.defaultBallY);
this.hSpeed = GameSettings.ballHSpeed;
this.vSpeed = GameSettings.ballYSpeed;
}

public Ball(Ball ball) {
color = ball.color;
height = ball.height;
width = ball.width;
position = ball.position;
hSpeed = ball.hSpeed;
vSpeed = ball.vSpeed;
}

public double getHSpeed() {
return this.hSpeed;
}

public double getVSpeed() {
return this.vSpeed;
}


public void run() {

try {
while (GameController.getInstance().getGameState().isActive()) {
System.out.println("Ich run im Ball");
Thread.sleep(10);
this.meetingWall();
this.meetingBrick();
this.position.setLocation(this.getPosition().getX() + this.hSpeed,
this.getPosition().getY() + this.vSpeed);
if (this.meetingPaddle()) {
this.newDirection();
}
if (this.out()) {
GameController.getInstance().stopGame();
this.stopThread();
}

this.position = this.getPosition();

}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

public void stopThread() {
GameController.getInstance().getGameState().setActive(false);
}

public void startThreadAgain() {
this.run();
}

@Override
public synchronized void start() {
this.position.setLocation(GameSettings.defaultBallX, GameSettings.defaultBallY);
super.start();
}


class GamePanel extends JPanel {
private static final long serialVersionUID = 1L;
private final Color backgroundColor = Color.BLACK;
GameState gameState = GameController.getInstance().getGameState();

public GamePanel() {
super();

this.addKeyListener(new KeyListener() {
// Dieser KeyListener soll auf Inputs der Pfeiltasten nach links
// <- und rechts -> hoeren und eine entsprechende Bewegung des
// Schlaegers erwirken, aber nur, wenn das Spiel nicht
// pausiert/gestoppt ist.
public void keyPressed(KeyEvent keyEvent) {
if (gameState.isActive()) {// gameState.isActive()
if (keyEvent.getKeyCode() == KeyEvent.VK_RIGHT) {
gameState.getPaddle().setPositionRigth();
}

if (keyEvent.getKeyCode() == KeyEvent.VK_LEFT) {
gameState.getPaddle().setPositionLeft();
}
}

}

public void keyReleased(KeyEvent keyEvent) {
// TODO
}

public void keyTyped(KeyEvent arg0) {
}
});
}


public void paint(Graphics g) {
Graphics2D graphics2D = (Graphics2D) g;
graphics2D.setColor(this.backgroundColor);
graphics2D.fillRect(0, 0, this.getWidth(), this.getHeight());

for (int i = 0; i < gameState.getBricks().length; i++) {
for (int j = 0; j < gameState.getBricks()[i].length; j++) {
if ((gameState.getBricks()[i][j] != null)) {
graphics2D.setColor(gameState.getBricks()[i][j].getColor());

graphics2D.fillRect(
(i * GameSettings.brickWidth) + (i + 1) * (GameSettings.spaceAroundBrick + 1),
(j * GameSettings.brickHeight) + (j + 1) * GameSettings.spaceAroundBrick,
GameSettings.brickWidth, GameSettings.brickHeight);
}
scoreLabel.setText(this.gameState.getScore() + "");

gameState.getPaddle().draw(graphics2D);
gameState.getBall().draw(graphics2D);
}
}

}
}


// First Approach


private class RepainterThread implements Runnable {

public RepainterThread() {
System.out.println("RepainThreadCOntructor");
}

private void updateGUI() {
System.out.println("before invoke later");

System.out.println("repaint");
getGamePanel().requestFocus();
getGamePanel().repaint();

}

@Override
public void run() {
System.out.println("Repainter run");
System.out.println(GameController.getInstance().getGameState().isActive());

while (GameController.getInstance().getGameState().isActive()) {
System.out.println("inside while");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

updateGUI();

}

}

}

// Second Approach

private class RepainterThread implements Runnable {


public RepainterThread() {
System.out.println("RepainThreadCOntructor");
}

private void updateGUI(){

SwingUtilities.invokeLater(new Runnable() {
public void run() {
System.out.println("repaint");
getGamePanel().requestFocus();
getGamePanel().repaint();
}
});

}
@Override
public void run() {
System.out.println("Repainter run");
System.out.println(GameController.getInstance().getGameState().isActive());

while (GameController.getInstance().getGameState().isActive()) {
System.out.println("inside while");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

updateGUI();


}

}

}

框架不应再卡住

请帮忙

最佳答案

这是一种疯狂的猜测,但根据您的描述,程序正常工作,直到您暂停并取消暂停它,问题可能出在 startThreadAgain 方法上:

public void startThreadAgain() {
this.run();
}

您的代码不会显示您如何调用此方法,但该方法中您只需调用 this.run(),即您调用 run 方法作为常规的阻塞方法,但可能仍在 UI 线程中。相反,您应该调用 start() 来启动一个执行 run 方法的正确新线程。

public void startThreadAgain() {
super.start(); // not this start, otherwise it resets the ball's location
}

关于java - 使用线程时 Swing GUI 卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56125621/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com