我正在尝试学习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();
}
}
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 像素会让它移动更平滑(但更慢)。