事件分配线程与逻辑线程分开,防止阻塞UI [英] Event Dispatch Thread divided from logic thread,prevent blocking UI
问题描述
我如何将逻辑与EDT分开,因为您可以看到逻辑和渲染与循环相关 以及如何以一种漂亮的方式分离代码,这让我很麻烦,试图找出方法.
how i can separate the logic from the EDT,because as you can see logic and render are related into loop and how i can separate code in a pretty way, i' m getting in trouble with this,trying to find out how to do.
有什么建议/帮助/建议吗?
Any suggestion/helps/advices?
主班
public class MainFrame {
private static MainFrame mainFrame = null;
private final JFrame frame;
private MainFrame() {
frame = new JFrame();
frame.setUndecorated(true);
frame.add(new GamePanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static final MainFrame getMainFrameInstance() {
if (mainFrame == null) {
mainFrame = new MainFrame();
}
return mainFrame;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {// set look and feel to nimbus
for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
MainFrame.getMainFrameInstance();
}
});
}
}
我在其上开始游戏循环的
gamePanel类
gamePanel class on which i start the game loop
public class MyPanel extends JPanel implements Runnable {
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) {
thread = new Thread(this);
thread.start();
}
}
private void initGraphic() {
image = new BufferedImage(WIDTH, HEIGHT, 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();
}
}
}
@Override
public void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
graphics = (Graphics2D) 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);
}
推荐答案
您的gamePanel不应进入无限循环.它应该初始化自身并定义一个 Swing timer .更一般而言,每当您定期执行某项操作时,您都不应尝试跟踪时间,而应定义应该在单个步骤中执行的操作并让计时器呼叫您.这样可以更好地利用系统资源,并且是一种好的工程实践.
Your gamePanel should not enter an infinite loop. It should initialize itself and define a method to be called periodically by a Swing timer. More generally, whenever you do something periodically, you should not try to keep track of time, but instead define what should be done during a single step and let a timer call you. This makes a much better use of system resources and is a good engineering practice.
这篇关于事件分配线程与逻辑线程分开,防止阻塞UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!