Je suis à la recherche d'un moyen efficace de mettre en œuvre le rendu de jeux 2D.Comment rendre les graphiques Java dans un jeu 2D correctement et efficacement
Voici un exemple du type de système de rendu que mon jeu utilise pour le moment. (Je ne sais pas comment l'utiliser ou ce n'est pas assez flexible.)
J'utilise Canvas et ses BufferStrategies mais je ne suis pas sûr de leur efficacité. Toute aide est appréciée.
//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();
}
}
Pour le fps, parce que le rendu d'une image ne peut pas prendre exactement exactement le même temps, vous devez attendre en tenant compte du dernier temps de rendu – Tuco
c'est une idée assez intelligente, comment exactement est-ce que j'irais faire ça? –
même si la méthode setFps() est utilisée dans la boucle de rendu pour créer un délai de 16 millisecondes qui autorise 60 images par 1000 millisecondes (presque) ou 60 images par seconde –