我正在寻找一种实现2D游戏渲染的有效方法。
这是我的游戏目前使用什么样的渲染系统的示例。 (我要么不知道如何使用它,要么它不够灵活。)
我使用Canvas及其BufferStrategies,但我不确定它们的效率如何。 任何帮助表示赞赏。
//MY RENDERING SYSTEM EXPLAINED IN JAVA AND WITH ONLY ONE CLASS.
//DOES NOT INCLUDE TICKING JUST RENDERING, TICKING IS A DIFFERENT THREAD.
//(so they can run on different frames per second)
//main() method is at the very bottom.
/*
* @Author
* CodyOrr4
*/
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
public class Main implements Runnable {
public static Cache cache;
public static JFrame frame;
public static JPanel panel;
public static JViewport camera;
public static Canvas canvas;
public static BufferStrategy bufferStrategy;
public static Graphics graphics;
public static boolean rendering = false;
public static Thread renderingThread;
//turns this runnable into an object.
public Main() {
frame = new JFrame("Rendering System Example");
frame.setSize(new Dimension(800, 600));
frame.setDefaultCloseOperation(1);
frame.setVisible(true);
panel = new JPanel();
panel.setBackground(Color.DARK_GRAY);
canvas = new Canvas();
canvas.setBackground(Color.BLACK);
canvas.setPreferredSize(new Dimension(800, 600));
canvas.setMinimumSize(new Dimension(800, 600));
canvas.setMaximumSize(new Dimension(2000, 2000));
cache = new Cache();
panel.add(canvas);
frame.getContentPane().add(panel);
}
//used to run things that are not meant to be run in a loop;
private void init() {
cache.initCache(); //can now grab sprites (including names/ids) and other types within cache.
}
//renders everything (this method is used in a while() loop based on a boolean, within the run() method);
private void render(Graphics g) {
g.drawImage(cache.getSprite(0), 400, 300, 25, 25, null);
}
//runs the runnable
public void run() {
init();
while(rendering) {
setFps(16);//simply set fps now - iJustin *codys note on the setFps(fps); method* = not sure if its the same thing lol,
//but since ticking and rendering are separate threads in the main source (and contain separate init() methods) it seems like it would be good.
if(bufferStrategy == null) {
canvas.createBufferStrategy(3);//should only need a max of 3.
bufferStrategy = canvas.getBufferStrategy();
graphics = bufferStrategy.getDrawGraphics();
System.out.println("creating canvas components...");
}
//drawing with methods
render(graphics);
//drawing without methods
graphics.drawImage(cache.getSprite(0), 0, 0, 50, 50, null);
bufferStrategy.show();
graphics.dispose();
}
}
//starts the run method and creates a thread for this
public synchronized void start() {
renderingThread = new Thread(this);
renderingThread.setName("Game Rendering Thread");
renderingThread.start();
rendering = true;
}
//stops the while loop by setting the boolean to false and the thread is now null
public synchronized void stop() {
renderingThread = null;
rendering = false;
}
//@Author iJustin - sets fps of the rendering loop (while() loop within run() method)
@SuppressWarnings("static-access")
public void setFps(long fps) {
try {
renderingThread.sleep(fps);
}
catch(InterruptedException e) {
}
}
//main method obv.
public static void main(String[] args) {
Main gameExample = new Main();
gameExample.start();
}
}
答案 0 :(得分:0)
对于fps,您应该考虑最后一帧渲染时间的持续时间 它允许具有恒定的帧速率
为此,您可以为每一帧:
//a the start of rendering process
long startRendering=System.nanoTime();
... rendering here...
//duration of the frame rendering in ms :
long durationMs=TimeUnit.NANOSECONDS.toMillis(System.nanoTime()-startRendering);
// now waits
if (durationMs < fps)
{
renderingThread.sleep(fps - durationMs);
}
System.nanoTime允许以很高的准确度测量时间:如果你在两次System.nanoTime()调用之间取得差异,那么在调用之间经过的时间以纳秒为单位。 我觉得不使用System.currentTimeMillis不太准确