This is the smallest runnable SSCCE,of my project, that I could implement to show you.
I've read that calling the game logic from the Event Dispacth Thread is a bad practice, how can I separate them, because as you can see
update()
andrepaint()
are related into loop and how can I separate code in a pretty way, I'm getting in trouble with this, trying to find out how to do it.I've posted a similar question regarding and I got an answer,that says to use a Swing Timer,but i have huge task to make and as i read
Swing timer
isn't ideal for this scenario.This is the question:- Event Dispatch Thread divided from logic thread,prevent blocking UI
Main class
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class Main {
private static final Main mainFrame = new Main();
private final JFrame frame;
private Main() {
frame = new JFrame();
frame.setUndecorated(true);
frame.add(new MyPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static Main getMainFrameInstance() {
return mainFrame;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Main.getMainFrameInstance();
}
});
}
}
MyPanel Class
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
public class MyPanel extends JPanel implements Runnable,KeyListener,MouseListeners {
private static final long serialVersionUID = 1L;
// thread and loop
private Thread thread;
private boolean running;
private int FPS = 60;
private long targetTime = 1000 / FPS;
private long start;
private long elapsed;
private long wait;
// image
public BufferedImage image;
// foo
private Foo foo;
private Render render = Render.getRenderManagerInstance();
public MyPanel() {
setPreferredSize(new Dimension(700, 700));
setFocusable(true);
requestFocus();
}
public void addNotify() {
super.addNotify();
if (thread == null) {
addKeyListeners(this);
addMouseListener(this);
thread = new Thread(this);
thread.start();
}
}
private void initGraphic() {
image = new BufferedImage(700, 700, BufferedImage.TYPE_INT_RGB);
foo = new Foo();
running = true;
}
public void run() {
initGraphic();
// loop
while (running) {
start = System.nanoTime();
foo.update();
repaint();
elapsed = System.nanoTime() - start;
wait = (targetTime - elapsed / 1000000) - 8;
if (wait <= 0)
wait = 6;
try {
Thread.sleep(wait);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
graphics = image.getGraphics();
((Graphics2D) graphics).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
((Graphics2D) graphics).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
render.setRenderState((Graphics2D) graphics);
graphic.drawImage(image, 0, 0, this);
// clear graphics resources after use them
graphic2D.dispose();
}
public void keyPressed(KeyEvent keyEvent) {
//code not considerable
}
public void keyReleased(KeyEvent keyEvent) {
//code not considerable
}
public void mousePressed(MouseEvent mouseEvent) {
//code not considerable
}
public void mouseReleased(MouseEvent mouseEvent) {
//code not considerable
}
}