Java Swing 图形性能问题

问题描述 投票:0回答:1

我正在尝试学习Java图形编程。

我编写了一个加载图像并将其绘制到屏幕上的程序。用户可以使用键盘移动图像。

问题是运动真的很不稳定,一点也不流畅。

该程序似乎没有使用太多的CPU或内存:

$ ps -p (pgrep java) -o %cpu,%mem,cmd
%CPU %MEM CMD
 5.5  0.3 java -jar app.jar

我该怎么做才能让它不那么不稳定?

详情

$ java --version
java 21.0.2 2024-01-16 LTS
Java(TM) SE Runtime Environment (build 21.0.2+13-LTS-58)
Java HotSpot(TM) 64-Bit Server VM (build 21.0.2+13-LTS-58, mixed mode, sharing)
$ mvn --version
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 21.0.2, vendor: Oracle Corporation, runtime: /usr/lib/jvm/jdk-21-oracle-x64
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "6.5.0-15-generic", arch: "amd64", family: "unix"
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;

class Character {
  int x, y;
  BufferedImage image;

  public Character(String sprite_sheet, int x, int y) {
    this.x = x;
    this.y = y;

    try {
      image = ImageIO.read(new File(sprite_sheet));
      image = image.getSubimage(0, 0, 16, 16);

      Image tmp = image.getScaledInstance(64, 64, Image.SCALE_SMOOTH);
      image = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB);
      image.getGraphics().drawImage(tmp, 0, 0, null);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  public void draw(Graphics g) {
    g.drawImage(image, x, y, null);
  }

  public void move(int dx, int dy) {
    x += dx;
    y += dy;
  }
}

class KeyboardState {
  boolean left, right, up, down;
}

class Game extends JPanel {
  Character character;
  KeyboardState keyboardState;
  int numPaints = 0;

  @Override
  public void paintComponent(Graphics g) {
    super.paintComponent(g);

    if (character != null) {
      character.draw(g);
    }

    numPaints++;
  }

  public void moveCharacter(int dx, int dy) {
    if (character != null) {
      character.move(dx, dy);
    }
  }

  public void update() {
    if (keyboardState.left) {
      character.move(-5, 0);
    }

    if (keyboardState.right) {
      character.move(5, 0);
    }

    if (keyboardState.up) {
      character.move(0, -5);
    }

    if (keyboardState.down) {
      character.move(0, 5);
    }

    repaint();
  }

  public void start() {
    Timer timer = new Timer(1000 / 30, new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        update();
      }
    });

    timer.start();
  }
}

public class Main {
  public static void main(String[] args) {
    JFrame frame = new JFrame("TODO");

    Game game = new Game();
    game.character = new Character(
        "sprite-sheet.png",
        100, 100);
    game.keyboardState = new KeyboardState();

    frame.addKeyListener(new KeyAdapter() {
      @Override
      public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        if (key == KeyEvent.VK_LEFT) {
          game.keyboardState.left = true;
        } else if (key == KeyEvent.VK_RIGHT) {
          game.keyboardState.right = true;
        } else if (key == KeyEvent.VK_UP) {
          game.keyboardState.up = true;
        } else if (key == KeyEvent.VK_DOWN) {
          game.keyboardState.down = true;
        } else if (key == KeyEvent.VK_ESCAPE) {
          System.out.println("Num paints: " + game.numPaints);
          System.exit(0);
        }
      }

      @Override
      public void keyReleased(KeyEvent e) {
        int key = e.getKeyCode();
        if (key == KeyEvent.VK_LEFT) {
          game.keyboardState.left = false;
        } else if (key == KeyEvent.VK_RIGHT) {
          game.keyboardState.right = false;
        } else if (key == KeyEvent.VK_UP) {
          game.keyboardState.up = false;
        } else if (key == KeyEvent.VK_DOWN) {
          game.keyboardState.down = false;
        }
      }
    });

    frame.add(game);
    frame.setSize(800, 600);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);

    game.start();
  }
}
java performance swing graphics
1个回答
0
投票

IMO,您可以简化逻辑以更快地移动游戏角色,而不是通过多个步骤和方法调用来更新角色的位置,这可能会导致响应速度变慢。例如

frame.addKeyListener(new KeyAdapter() {
      @Override
      public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        if (key == KeyEvent.VK_LEFT) {
          game.moveCharacter(-5, 0);
        } else if (key == KeyEvent.VK_RIGHT) {
          game.moveCharacter(5, 0);
        } else if (key == KeyEvent.VK_UP) {
          game.moveCharacter(0, -5);
        } else if (key == KeyEvent.VK_DOWN) {
          game.moveCharacter(0, 5);
        } else if (key == KeyEvent.VK_ESCAPE) {
          System.out.println("Num paints: " + game.numPaints);
          System.exit(0);
        }
      }
       ...
    });

您也可以使用 dy 或 dx(5 像素)。也许 1 像素会让它移动更平滑(但更慢)。

© www.soinside.com 2019 - 2024. All rights reserved.