Điều bạn muốn làm là tạo thành phần canvas với BufferStrategy và hiển thị, mã bên dưới sẽ cho bạn biết cách hoạt động, tôi đã trích xuất mã từ Engine tự viết của mình qua here.
Hiệu suất chỉ phụ thuộc vào nội dung bạn muốn vẽ, trò chơi của tôi chủ yếu sử dụng hình ảnh. Với khoảng 1500 người trong số họ tôi vẫn còn trên 200 FPS ở 480x480. Và chỉ với 100 hình ảnh tôi đang nhấn 6k FPS khi vô hiệu hóa khung giới hạn.
Một trò chơi nhỏ (cái này có khoảng 120 hình ảnh cùng một lúc vào màn hình) Tôi đã tạo có thể được tìm thấy here (có phương pháp dưới đây cũng hoạt động tốt như một applet.)
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import java.awt.Transparency;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class Test extends Thread {
private boolean isRunning = true;
private Canvas canvas;
private BufferStrategy strategy;
private BufferedImage background;
private Graphics2D backgroundGraphics;
private Graphics2D graphics;
private JFrame frame;
private int width = 320;
private int height = 240;
private int scale = 1;
private GraphicsConfiguration config =
GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice()
.getDefaultConfiguration();
// create a hardware accelerated image
public final BufferedImage create(final int width, final int height,
final boolean alpha) {
return config.createCompatibleImage(width, height, alpha
? Transparency.TRANSLUCENT : Transparency.OPAQUE);
}
// Setup
public Test() {
// JFrame
frame = new JFrame();
frame.addWindowListener(new FrameClose());
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.setSize(width * scale, height * scale);
frame.setVisible(true);
// Canvas
canvas = new Canvas(config);
canvas.setSize(width * scale, height * scale);
frame.add(canvas, 0);
// Background & Buffer
background = create(width, height, false);
canvas.createBufferStrategy(2);
do {
strategy = canvas.getBufferStrategy();
} while (strategy == null);
start();
}
private class FrameClose extends WindowAdapter {
@Override
public void windowClosing(final WindowEvent e) {
isRunning = false;
}
}
// Screen and buffer stuff
private Graphics2D getBuffer() {
if (graphics == null) {
try {
graphics = (Graphics2D) strategy.getDrawGraphics();
} catch (IllegalStateException e) {
return null;
}
}
return graphics;
}
private boolean updateScreen() {
graphics.dispose();
graphics = null;
try {
strategy.show();
Toolkit.getDefaultToolkit().sync();
return (!strategy.contentsLost());
} catch (NullPointerException e) {
return true;
} catch (IllegalStateException e) {
return true;
}
}
public void run() {
backgroundGraphics = (Graphics2D) background.getGraphics();
long fpsWait = (long) (1.0/30 * 1000);
main: while (isRunning) {
long renderStart = System.nanoTime();
updateGame();
// Update Graphics
do {
Graphics2D bg = getBuffer();
if (!isRunning) {
break main;
}
renderGame(backgroundGraphics); // this calls your draw method
// thingy
if (scale != 1) {
bg.drawImage(background, 0, 0, width * scale, height
* scale, 0, 0, width, height, null);
} else {
bg.drawImage(background, 0, 0, null);
}
bg.dispose();
} while (!updateScreen());
// Better do some FPS limiting here
long renderTime = (System.nanoTime() - renderStart)/1000000;
try {
Thread.sleep(Math.max(0, fpsWait - renderTime));
} catch (InterruptedException e) {
Thread.interrupted();
break;
}
renderTime = (System.nanoTime() - renderStart)/1000000;
}
frame.dispose();
}
public void updateGame() {
// update game logic here
}
public void renderGame(Graphics2D g) {
g.setColor(Color.BLACK);
g.fillRect(0, 0, width, height);
}
public static void main(final String args[]) {
new Test();
}
}
Nguồn
2009-12-26 16:14:58
Cảm ơn !!! Điều này là rất intresting. FPS cũng hạn chế. Trò chơi bạn đã thực hiện là VERY NICE! –
Thú vị, là strategy.show() an toàn để gọi từ bên ngoài EDT? – Pool
Thử nghiệm ngắn với chuỗi thứ hai cho biết có, nó an toàn. Đối với try/catch, đó là chỉ có bởi vì Toolkit.getDefaultToolkit(). Sync() CÓ THỂ ném một ngoại lệ trong trường hợp hiếm hoi. –