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

Java me 在画布之间切换时,j2me屏幕闪烁,java-me,midp,lcdui,Java Me,Midp,Lcdui,我正在用j2me编写一个手机游戏。在这个游戏中,我使用多个画布对象。 例如,游戏菜单是一个画布对象,而实际的游戏也是一个画布对象。 我注意到,在某些设备上,当我从一个画布切换到另一个画布时,例如从主菜单切换到游戏时,屏幕会瞬间“闪烁”。我用的是我自己的双缓冲画布 是否有办法避免这种情况?是否使用双缓冲?如果设备本身不支持双缓冲,则应定义一个屏幕外缓冲区(图像)并首先对其进行绘制,然后将最终结果绘制到真实屏幕。对你的每一张画布都这样做。以下是一个例子: public class MyScreen

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


是否有办法避免这种情况?

是否使用双缓冲?如果设备本身不支持双缓冲,则应定义一个屏幕外缓冲区(图像)并首先对其进行绘制,然后将最终结果绘制到真实屏幕。对你的每一张画布都这样做。以下是一个例子:

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()同步开关。闪烁可能是由于应用程序试图在画布切换仍在进行时绘制到屏幕上引起的。callSerially()应该在再次尝试调用run()之前等待重新绘制完成

但所有这些都完全取决于手机,因为许多设备没有实现callSerially(),更不用说遵循官方文档中列出的实现了。我所知道的唯一能正确使用CallSerialy()的设备是西门子手机

另一种可能的尝试是放置一个类似1000ms的Thread.sleep(),确保事先调用了setCurrent()方法。通过这种方式,设备可以在可显示设备尝试绘图之前进行更改


最有可能的问题是,这是一个设备问题,保证对闪烁的修复很简单-使用一个画布。但可能不是你想听的。:)

我想说,使用多张画布通常是糟糕的设计。在某些手机上,它甚至会崩溃。最好的方法是使用一个画布来跟踪应用程序的状态。然后在绘画方法中,你会

protected void paint(final Graphics g) {
  if(menu) {
    paintMenu(g);
  } else if (game) {
    paintGame(g);
  }
}
有更好的方法来处理屏幕对象的应用程序状态,这会使设计更简洁,但我想你已经想到了:)


/Jaanussim

如果您正在编写游戏,那么使用GameCanvas类可能是一个好主意。对于这样的目的来说,它要好得多,如果使用得当,它应该可以解决您的问题。

假设,为您的应用程序使用带有状态机代码的1个画布是一个好主意。然而,我唯一需要在其上测试应用程序的设备(MotoV3)在资源加载时崩溃,这仅仅是因为在1个GameCanvas中要加载的代码太多(没有尝试使用Canvas)。这是痛苦的,因为它是真实的,我还没有找到解决问题的办法。
如果你很幸运有很多设备要测试,那么这两种方法都是值得的,并且可以为每台设备制作游戏版本。

我使用双缓冲,使用与你类似的方法定义屏幕外缓冲。闪烁总是在新画布的主线程开始运行时发生。我按照您的建议,在代码中添加了一个长线程。sleep()。我发现闪烁实际上发生在画布的run()方法中的第一次重新绘制()之后。有什么想法吗?我最初用的是GameCanvas对象。我也观察到了同样的“闪烁”行为。这是因为有些手机甚至没有实现GameCavans的后缓冲。天哪,哇,我刚刚发现了它。。。基本上一开始我使用了一个introCanvas、一个loadingCanvas和一个GameOverNVAS,而在新版本(all-in-1 canvas/state machine)中,我们根本没有使用它们。事实证明,只需从src文件夹中清除这些文件即可解决应用程序错误问题:)。太神了