Вот GIF-изображение, показывающее, как окно быстро обновляется только при перемещении мыши. .

Почему окно так медленно обновляется? Почему мышь и клавиатура влияют на частоту обновления? Как, если возможно, обеспечить постоянное быстрое обновление?
Справочная информация
Я использую javax.swing.Timer для обновления состояния игры каждые 1/25 секунды, после чего он вызывает repaint() на игровой панели, чтобы перерисовать сцену.
Я понимаю, что Таймер не всегда может задерживать ровно 1/25 секунды.
Я также понимаю, что вызов repaint() просто запрашивает перерисовку окна как можно скорее и не перерисовывает Окно немедленно. < /p>
Моя видеокарта не поддерживает Opengl 2+ или аппаратную ускоренную 3D -графику, поэтому я не использую Libgdx или Jme для разработки игры. < / / p>
Информация о системе
- Операционная система: Linux Mint 19 Tara
- Версия JDK: OpenJDK 11.0.4
- Видеокарта: Intel Corporation 82945G/GZ
Этот пользователь Stack Overflow описывает ту же проблему, что и я, но автор, как сообщается, решил проблему, повторно вызвав repaint() для отдельного таймера. Я попробовал это, и это окно обновляется несколько быстрее, но даже в этом случае оно медленнее, чем мне хотелось бы. В этом случае покачивание мыши в окне все равно увеличивает частоту обновления. Таким образом, похоже, что этот пост на самом деле не решил проблему.
Другой пользователь Stack Overflow также столкнулся с проблемой, но он использует непрерывный цикл while вместо таймера. для их игрового цикла. Судя по всему, этот пользователь решил проблему, используя Thread.sleep() в цикле while. Однако мой код обеспечивает задержку с помощью таймера, поэтому я не знаю, как Thread.sleep() может решить мою проблему или даже где бы я его разместил.
Я прочитал «Рисование с помощью AWT и Swing», чтобы выяснить, не неправильно ли я понял концепцию перерисовки, но ничто в этом документе не проясняет для меня эту проблему. Я вызываю repaint() всякий раз, когда игра обновляется, и окно обновляется быстро только при вводе данных с помощью мыши или клавиатуры.
Я искал в Интернете уже несколько дней, пытаясь нашел ответ, но, кажется, ничего не помогает!
Код
import java.awt.Graphics;
import java.awt.Dimension;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
class Game {
public static final int screenWidth = 160;
public static final int screenHeight = 140;
/**
* Create and show the GUI.
*/
private static void createAndShowGUI() {
/* Create the GUI. */
JFrame frame = new JFrame("Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.getContentPane().add(new GamePanel());
frame.pack();
/* Show the GUI. */
frame.setVisible(true);
}
/**
* Run the game.
*
* @param args the list of command-line arguments
*/
public static void main(String[] args) {
/* Schedule the GUI to be created on the EDT. */
SwingUtilities.invokeLater(() -> createAndShowGUI());
}
}
/**
* A GamePanel widget updates and shows the game scene.
*/
class GamePanel extends JPanel {
private Square square;
/**
* Create a game panel and start its update-and-draw cycle
*/
public GamePanel() {
super();
/* Set the size of the game screen. */
setPreferredSize(
new Dimension(
Game.screenWidth,
Game.screenHeight));
/* Create the square in the game world. */
square = new Square(0, 0, 32, 32, Square.Direction.LEFT);
/* Update the scene every 40 milliseconds. */
Timer timer = new Timer(40, (e) -> updateScene());
timer.start();
}
/**
* Paint the game scene using a graphics context.
*
* @param g the graphics context
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
/* Clear the screen. */
g.setColor(Color.WHITE);
g.fillRect(0, 0, Game.screenWidth, Game.screenHeight);
/* Draw all objects in the scene. */
square.draw(g);
}
/**
* Update the game state.
*/
private void updateScene() {
/* Update all objects in the scene. */
square.update();
/* Request the scene to be repainted. */
repaint();
}
}
/**
* A Square is a game object which looks like a square.
*/
class Square {
public static enum Direction { LEFT, RIGHT };
private int x;
private int y;
private int width;
private int height;
private Direction direction;
/**
* Create a square game object.
*
* @param x the square's x position
* @param y the square's y position
* @param width the square's width (in pixels)
* @param height the square's height (in pixels)
* @param direction the square's direction of movement
*/
public Square(int x,
int y,
int width,
int height,
Direction direction) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.direction = direction;
}
/**
* Draw the square using a graphics context.
*
* @param g the graphics context
*/
public void draw(Graphics g) {
g.setColor(Color.RED);
g.fillRect(x, y, width, height);
g.setColor(Color.BLACK);
g.drawRect(x, y, width, height);
}
/**
* Update the square's state.
*
* The square slides horizontally
* until it reaches the edge of the screen,
* at which point it begins sliding in the
* opposite direction.
*
* This should be called once per frame.
*/
public void update() {
if (direction == Direction.LEFT) {
x--;
if (x = Game.screenWidth) {
direction = Direction.LEFT;
}
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/579 ... -the-mouse
Мобильная версия