我正在使用j2me编写手机游戏。在这个游戏中,我使用多个Canvas对象。 例如,游戏菜单是Canvas对象,实际游戏也是Canvas对象。 我注意到,在某些设备上,当我从一个Canvas切换到另一个时,例如从主菜单到游戏,屏幕瞬间“闪烁”。我正在使用自己的双缓冲Canvas。
无论如何都要避免这种情况吗?
答案 0 :(得分:6)
我想说,使用多幅画布通常是糟糕的设计。在某些手机上它甚至会崩溃。最好的方法是使用一个带有跟踪应用程序状态的画布。然后在绘画方法中你会有
protected void paint(final Graphics g) {
if(menu) {
paintMenu(g);
} else if (game) {
paintGame(g);
}
}
有更好的方法来处理屏幕对象的应用程序状态,这会使设计更清晰,但我认为你有这个想法:)
/ JaanusSiim
答案 1 :(得分:0)
你使用双缓冲吗?如果设备本身不支持双缓冲,则应首先定义屏幕外缓冲区(Image)并先绘制,然后将最终结果绘制到真实屏幕。为每幅画布做这件事。这是一个例子:
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);
}
}
}
答案 2 :(得分:0)
可能的解决方法是使用Display.callSerially()同步交换机。闪烁可能是由于应用程序在Canvas的切换仍在进行时尝试绘制到屏幕而引起的。 callSerially()应该在尝试再次调用run()之前等待重绘完成。
但所有这些完全取决于手机,因为很多设备都没有实现callSerially(),更不用说遵循官方文档中列出的实现了。我所知道的与callSerially()正常工作的唯一设备是西门子手机。
另一种可能的尝试是将Thread.sleep()放入大小为1000毫秒的东西,确保您事先调用了setCurrent()方法。这样,设备可能会在可显示的尝试绘制之前设法进行更改。
最可能的问题是它是一个设备问题,并且保证修复闪烁很简单 - 使用一个Canvas。可能不是你想听到的。 :)
答案 3 :(得分:0)
如果您正在编写游戏,那么使用GameCanvas类可能是个好主意。对于这样的目的来说要好得多,如果使用得当它可以解决你的问题。
答案 4 :(得分:0)
假设,为您的应用程序使用带有状态机代码的1个画布是个好主意。然而,我需要测试应用程序的唯一设备(MOTO v3)在资源加载时崩溃只是因为在GameCanvas中没有加载太多代码(没有尝试使用Canvas)。这是真实的痛苦,而且我还没有找到问题的解决方案。 如果你很幸运能够测试大量的设备,那么实现这两种方法是值得的,并且几乎可以为每个设备制作游戏版本。