我正在使用 j2me 编写手机游戏。在这个游戏中,我使用了多个 Canvas 对象。例如,游戏菜单是一个 Canvas 对象,而实际游戏也是一个 Canvas 对象。我注意到,在某些设备上,当我从一个画布切换到另一个画布时,例如从主菜单切换到游戏,屏幕会瞬间“闪烁”。我正在使用我自己的双缓冲画布。
有没有办法避免这种情况?
我想说,使用多个画布通常是不好的设计。在某些手机上,它甚至会崩溃。最好的方法是使用一个跟踪应用程序状态的画布。然后在绘画方法中,您将拥有
protected void paint(final Graphics g) {
if(menu) {
paintMenu(g);
} else if (game) {
paintGame(g);
}
}
有更好的方法来处理屏幕对象的应用程序状态,这会使设计更简洁,但我认为你明白了 :)
/亚努斯西姆
你使用双缓冲吗?如果设备本身不支持双缓冲,您应该定义一个屏幕外缓冲区(图像)并首先对其进行绘制,然后将最终结果绘制到真实屏幕。为您的每个画布执行此操作。这是一个例子:
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);
}
}
}
Hypothetically, using 1 canvas with a sate machine code for your application is a good idea. However the only device I have to test applications on (MOTO v3) crashes at resources loading time just because there's too much code/to be loaded in 1 GameCanvas ( haven't tried with Canvas ). It's as painful as it is real and atm I haven't found a solution to the problem. If you're lucky to have a good number of devices to test on, it is worth having both approaches implemented and pretty much make versions of your game for each device.
如果您正在编写游戏,使用 GameCanvas 类可能是个好主意。对于这样的目的,它要好得多,如果使用得当,它应该可以解决您的问题。
一种可能的解决方法是使用 Display.callSerially() 同步开关。闪烁可能是由于应用程序在 Canvas 的切换仍在进行时尝试绘制到屏幕造成的。callSerially() 应该等待重绘完成,然后再尝试再次调用 run()。
但这一切都完全取决于手机,因为许多设备没有实现 callSerially(),更不用说遵循官方文档中列出的实现了。我所知道的与 callSerially() 一起正常工作的唯一设备是西门子手机。
另一种可能的尝试是放置一个像 1000 毫秒这样巨大的 Thread.sleep(),确保您事先调用了 setCurrent() 方法。这样,设备可能会在可视组件尝试绘制之前进行更改。
最可能的问题是它是一个设备问题,并且保证对闪烁的修复很简单 - 使用一个 Canvas。可能不是你想听到的。:)