在画布之间切换时,j2me屏幕闪烁

时间:2008-09-15 20:08:48

标签: java-me midp lcdui

我正在使用j2me编写手机游戏。在这个游戏中,我使用多个Canvas对象。 例如,游戏菜单是Canvas对象,实际游戏也是Canvas对象。 我注意到,在某些设备上,当我从一个Canvas切换到另一个时,例如从主菜单到游戏,屏幕瞬间“闪烁”。我正在使用自己的双缓冲Canvas。

无论如何都要避免这种情况吗?

5 个答案:

答案 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)。这是真实的痛苦,而且我还没有找到问题的解决方案。 如果你很幸运能够测试大量的设备,那么实现这两种方法是值得的,并且几乎可以为每个设备制作游戏版本。