[英]Low FPS in Swing Application
您好,我正在使用 Java 和 Swing GUI 的原始 Snake 構建一個相對較小的 2D 游戲。 盡管我的應用程序目前非常小,但我的 FPS 計數在 ~7 到 ~10 FPS 的范圍內非常低。 所有顯示在屏幕上的都是 4 個 10x10 PNG,所以考慮到我希望實現的內容,這有點令人擔憂。
下面給出了我的主要 class 的代碼,下面給出了我用來顯示 FPS 的方法。
public class Board extends JPanel implements ActionListener {
private final int BOARD_WIDTH = 300;
private final int BOARD_HEIGHT = 300;
private final int SEGMENT_SIZE = 10;
private final int MAX_PARTS = (BOARD_WIDTH / SEGMENT_SIZE) * (BOARD_HEIGHT * SEGMENT_SIZE);
private final int DELAY = 140;
private final int RAND_POS = 29;
private final int x[] = new int[MAX_PARTS];
private final int y[] = new int[MAX_PARTS];
private int bodyLen;
private int appleX;
private int appleY;
private boolean rightDirection = true;
private boolean leftDirection = false;
private boolean upDirection = false;
private boolean downDirection = false;
private boolean inGame = true;
private Timer timer;
private Image body;
private Image head;
private Image apple;
private FPSCounter fpscount;
public Board() {
initBoard();
}
private void initBoard() {
fpscount = new FPSCounter();
fpscount.start();
addKeyListener(new TAdapter());
setBackground(Color.black);
setFocusable(true);
setPreferredSize(new Dimension(BOARD_WIDTH, BOARD_HEIGHT));
loadImages();
initGame();
}
private void loadImages() {
ImageIcon app = new ImageIcon("src/main/resources/Apple.png");
apple = app.getImage();
ImageIcon bod = new ImageIcon("src/main/resources/Body.png");
body = bod.getImage();
}
private void initGame() {
bodyLen = 3;
for(int i = 0; i < bodyLen; i++) {
x[i] = 50 - i * 10;
y[i] = 50;
}
getApple();
timer = new Timer(DELAY, this);
timer.start();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
fpscount.frame(); //added line (step 4).
g.drawString("" + fpscount.get(), 5, 22); //added line (step 5).
}
private void doDrawing(Graphics g) {
if (inGame) {
g.drawImage(apple, appleX, appleY, this);
for(int i = 0; i < bodyLen; i++) {
g.drawImage(body, x[i], y[i], this);
}
Toolkit.getDefaultToolkit().sync();
}
}
private void getApple() {
int r = (int) (Math.random() * RAND_POS);
appleX = r * SEGMENT_SIZE;
r = (int) (Math.random() * RAND_POS);
appleY = r * SEGMENT_SIZE;
}
@Override
public void actionPerformed(ActionEvent e) {
if(inGame) {
move();
}
repaint();
}
private void move() {
for(int i = bodyLen; i > 0; i--) {
x[i] = x[i - 1];
y[i] = y[i - 1];
}
if(leftDirection) {
x[0] -= SEGMENT_SIZE;
}
if(rightDirection) {
x[0] += SEGMENT_SIZE;
}
if(upDirection) {
y[0] -= SEGMENT_SIZE;
}
if(downDirection) {
y[0] += SEGMENT_SIZE;
}
}
private class TAdapter extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if((key == KeyEvent.VK_RIGHT) && (!leftDirection)) {
rightDirection = true;
upDirection = false;
downDirection = false;
leftDirection = false;
}
if((key == KeyEvent.VK_LEFT) && (!rightDirection)) {
leftDirection = true;
upDirection = false;
downDirection = false;
rightDirection = false;
}
if((key == KeyEvent.VK_UP) && (!downDirection)) {
upDirection = true;
rightDirection = false;
leftDirection = false;
downDirection = false;
}
if((key == KeyEvent.VK_DOWN) && (!upDirection)) {
downDirection = true;
leftDirection = false;
rightDirection = false;
upDirection = false;
}
}
}
}
FPS計數器 Class
private final Timer resetTimer;
private int current, last;
public FPSCounter() {
resetTimer = new Timer(1000, this);
}
public synchronized void start() {
resetTimer.start();
current = 0;
last = -1;
}
public synchronized void stop() {
resetTimer.stop();
current = -1;
}
public synchronized void frame() {
current++;
}
@Override
public void actionPerformed(ActionEvent e) {
last = current;
current = 0;
}
public synchronized int get() {
return last;
}
}
也許只是我的 FPS 計數器 class 關閉了,但您可以提供任何可能解決此問題的信息將不勝感激。
private final int DELAY = 140;
你的延遲是140。
所以你的每秒幀數將是 1000 / 140 = 7.14。
通常人們的目標是幀速率為 60。因此您應該使用 1000 / 60 = 16 的延遲。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.