Я пишу игру с прорывом, и все работает нормально, кроме одной мелочи.
У меня есть объект ball, который выходит из потока и RepainterThread, который может реализовывать Runnable или расширяет Thread, который вызывает метод рисования, которыйперерисовывает игровое поле с кирпичами, веслом и мячомдолжно быть приостановлено или нет.
Я запускаю игру, и я могу играть, и программа ведет себя так, как должна.Рамка вытягивается, мяч сдвигает кирпичи, когда мяч попадает во все хорошо.
Затем я приостанавливаю игру с помощью кнопки, для которой я установил Актив на ложь.Мяч останавливается как надо.Затем я нажимаю кнопку продолжения, и isActive снова становится верным.Объект ball снова начинает работать, и метод запуска 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();
}
}
}
Рамка больше не должна зависать
, пожалуйста, помогите