2011-12-22 71 views
2

我目前正在使用我设计的动画引擎,它需要Drawable类型的对象并将它们添加到列表中。绘制对象是具有一个方法的接口:在Java中动画的最佳方法是什么?

public void draw(Graphics2D g2d); 

延伸通过该列表动画管理迭代并调用每个对象上的拉伸()方法,传递从Swing组分得到Graphics2D对象。

这种方法起初看起来效果很好,但正如我担心的那样,它似乎无法处理多个对象。

只有两个Drawables注册,两个在屏幕上绘制图像,30-60秒后我看到有点闪烁。

有没有一种方法来优化这种方法?它目前调用AWT线程(invokeLater)来处理所有的任务。并发绘图并不是一个真正的选择,因为这几乎总是会导致Swing/AWT中的问题,很大程度上是由于图形不同步。

如果只是单纯的是动画的好方法,什么是当你有多个对象都需要用自己特定的变量咳嗽游戏咳嗽呈现的东西更好的方法?

任何帮助,将不胜感激。谢谢!

编辑:

我不能使用重绘()怎么一回事,因为我已经引擎调用AWT线程画的东西。如果我从AWT线程调用invokeLater,则图像永远不会因为某种原因而被绘制。

我还应该补充说我正在使用ticks和fps系统。 60次滴答@ 120 fps。

每个刻度更新游戏逻辑,而每帧渲染调用绘制帧管理器。

这是一个坏主意?我应该只使用FPS而不是蜱虫?

回答

5

我认为重写paintComponent(Graphics g)并定期调用JPanel上的repaint方法或使用定时器绘制的任何东西会更合适。你的问题可能是由于你试图绘制,然后Swing做自己的绘制。

public class Main { 
public static void main(String[] args) { 
    JFrame frame = new JFrame(); 
    JPanel panel = new JPanel() { 
     public void paintComponent(Graphics g) { 
      //draw here 
     } 
    }; 
    panel.setPreferredSize(800, 600); 
    frame.add(panel); 
    frame.pack(); 
    frame.setLocationRelativeTo(null); 
    frame.setVisible(true) 

    new Timer(16, new ActionListener() { 
     public void actionPerformed(ActionEvent event) { 
      panel.repaint(); 
     } 
    }).start(); 
} 
} 
+0

好的。我必须使用计时器吗?或者我可以只使用睡眠x毫秒并调用repaint()的线程? – bgroenks 2011-12-22 17:16:52

+0

你可以做任何你想做的,但计时器是相当不错的。我相信定时器是在AWT Event线程中管理的,所以它看起来像多线程。如果您在paintComponent方法内部放置了类似synchronized(this){wait();}的内容,那么您的整个GUI将停止响应。 – user615457 2011-12-22 19:41:46