在画布之间切换时,j2me屏幕闪烁
我正在使用j2me编写手机游戏。在这个游戏中,我使用了多个Canvas对象。
例如,游戏菜单是Canvas对象,实际游戏也是Canvas对象。
我注意到,在某些设备上,当我从一种Canvas切换到另一种Canvas(例如从主菜单切换到游戏)时,屏幕会瞬间"闪烁"。我正在使用自己的双缓冲Canvas。
反正有避免这种情况的方法吗?
解决方案
回答
我们是否使用双缓冲?如果设备本身不支持双重缓冲,则应定义一个屏幕外缓冲区(图像)并先对其进行绘制,然后将最终结果绘制至真实屏幕。对每个画布都执行此操作。这是一个例子:
public class MyScreen extends Canvas { private Image osb; private Graphics osg; //... public MyScreen() { // if device is not double buffered // use image as a offscreen buffer if (!isDoubleBuffered()) { osb = Image.createImage(screenWidth, screenHeight); osg = osb.getGraphics(); osg.setFont(defaultFont); } } protected void paint(Graphics graphics) { if (!isDoubleBuffered()) { // do your painting on off screen buffer first renderWorld(osg); // once done paint it at image on the real screen graphics.drawImage(osb, 0, 0, Tools.GRAPHICS_TOP_LEFT); } else { osg = graphics; renderWorld(graphics); } } }
回答
可能的解决方法是使用Display.callSerially()同步开关。闪烁可能是由于在画布切换仍在进行时,应用试图绘制到屏幕上引起的。在尝试再次调用run()之前,应将callSerially()等待重绘完成。
但是,所有这一切都完全取决于电话,因为许多设备没有实现callSerially(),所以不要紧跟官方文档中列出的实现。我知道可以与callSerially()正常使用的唯一设备是西门子电话。
另一种可能的尝试是将Thread.sleep()放入1000 ms之类的大文件,以确保事先调用了setCurrent()方法。这样,设备可能会设法在显示尝试绘制之前进行更改。
最可能的问题是这是设备问题,并且可以使用一个Canvas简单地解决闪烁问题。可能不是我们想听到的。 :)
回答
我会说,使用多个画布通常是不好的设计。在某些手机上,它甚至会崩溃。最好的方法实际上是使用一个画布跟踪应用程序的状态。然后在绘画方法中,我们将拥有
protected void paint(final Graphics g) { if(menu) { paintMenu(g); } else if (game) { paintGame(g); } }
有更好的方法来处理带有屏幕对象的应用程序状态,这将使设计更整洁,但我认为主意是:)
/贾纳斯·西姆(JaanusSiim)
回答
如果我们正在编写游戏,则最好使用GameCanvas类。为此目的,它要好得多,如果使用得当,它应该可以解决问题。
回答
假设,为应用程序使用1个画布和一个满意的机器代码是一个好主意。但是,我必须在(MOTO v3)上测试应用程序的唯一设备在资源加载时崩溃,原因是1个GameCanvas中加载的代码太多/无法加载(尚未尝试使用Canvas)。这是真实的痛苦,而且我还没有找到解决该问题的解决方案。
如果我们很幸运能够测试大量设备,那么既要实现这两种方法,又要为每台设备制作几乎所有版本的游戏,都是值得的。