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

发布于 2024-07-05 08:23:55 字数 194 浏览 10 评论 0原文

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

有什么办法可以避免这种情况吗?

I'm writing a mobile phone game using j2me. In this game, I am using multiple Canvas objects.
For example, the game menu is a Canvas object, and the actual game is a Canvas object too.
I've noticed that, on some devices, when I switch from one Canvas to another, e.g from the main menu to the game, the screen momentarily "flickers". I'm using my own double buffered Canvas.

Is there anyway to avoid this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

国粹 2024-07-12 08:23:57

可能的修复方法是使用 Display.callSerially() 同步开关。 闪烁可能是由于应用程序在画布切换仍在进行时尝试绘制到屏幕而引起的。 callSerially() 应该等待重绘完成,然后再尝试再次调用 run() 。

但这一切完全取决于手机,因为许多设备没有实现 callSerially(),更不用说遵循官方文档中列出的实现了。 我所知道的唯一可以与 callSerially() 一起正常工作的设备是西门子电话。

另一种可能的尝试是放置一个像 1000 毫秒这样巨大的 Thread.sleep() ,确保您事先调用了 setCurrent() 方法。 这样,设备可能会在可显示对象尝试绘制之前设法进行更改。

最有可能的问题是,这是一个设备问题,并且有保证的闪烁修复方法很简单 - 使用一个 Canvas。 但可能不是你想听到的。 :)

A possible fix is by synchronising the switch using Display.callSerially(). The flicker is probably caused by the app attempting to draw to the screen while the switch of the Canvas is still ongoing. callSerially() is supposed to wait for the repaint to finish before attempting to call run() again.

But all this is entirely dependent on the phone since many devices do not implement callSerially(), never mind follow the implementation listed in the official documentation. The only devices I've known to work correctly with callSerially() were Siemens phones.

Another possible attempt would be to put a Thread.sleep() of something huge like 1000 ms, making sure that you've called your setCurrent() method beforehand. This way, the device might manage to make the change before the displayable attempts to draw.

The most likely problem is that it is a device issue and the guaranteed fix to the flicker is simple - use one Canvas. Probably not what you wanted to hear though. :)

绝情姑娘 2024-07-12 08:23:57

你使用双缓冲吗? 如果设备本身不支持双缓冲,您应该定义一个离屏缓冲区(图像)并首先对其进行绘制,然后将最终结果绘制到真实屏幕上。 对每个画布都执行此操作。 这是一个例子:

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);
      }
   }
}

Do you use double buffering? If the device itself does not support double buffering you should define a off screen buffer (Image) and paint to it first and then paint the end result to the real screen. Do this for each of your canvases. Here is an example:

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);
      }
   }
}
南街女流氓 2024-07-12 08:23:57

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

It might be a good idea to use GameCanvas class if you are writing a game. It is much better for such purpose and when used properly it should solve your problem.

离线来电— 2024-07-12 08:23:57

假设,为您的应用程序使用 1 个带有 sate 机器代码的画布是一个好主意。 然而,我必须在(MOTO v3)上测试应用程序的唯一设备在资源加载时崩溃,只是因为 1 GameCanvas 中需要加载太多代码(尚未尝试使用 Canvas )。 这既痛苦又真实,而且我还没有找到解决问题的方法。
如果您很幸运有大量设备可供测试,则值得实施这两种方法并为每个设备制作游戏版本。

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.

千柳 2024-07-12 08:23:56

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

protected void paint(final Graphics g) {
  if(menu) {
    paintMenu(g);
  } else if (game) {
    paintGame(g);
  }
}

更好的方法来使用屏幕对象处理应用程序状态,这将使设计更清晰,但我认为您已经明白了:)

/JaanusSiim

I would say, that using multiple canvases is generally bad design. On some phones it will even crash. The best way would really be using one canvas with tracking state of the application. And then in paint method you would have

protected void paint(final Graphics g) {
  if(menu) {
    paintMenu(g);
  } else if (game) {
    paintGame(g);
  }
}

There are better ways to handle application state with screen objects, that would make the design cleaner, but I think you got the idea :)

/JaanusSiim

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文