j2me мерцание экрана при переключении между холстами - PullRequest
2 голосов
/ 16 сентября 2008

Я пишу игру для мобильного телефона, используя j2me. В этой игре я использую несколько объектов Canvas. Например, игровое меню - это объект Canvas, а сама игра тоже является объектом Canvas. Я заметил, что на некоторых устройствах, когда я переключаюсь с одного Canvas на другой, например из главного меню в игру, экран на мгновение «мерцает». Я использую свой собственный двойной буфер Canvas.

Есть ли способ избежать этого?

Ответы [ 5 ]

6 голосов
/ 16 сентября 2008

Я бы сказал, что использование нескольких полотен - это плохой дизайн. На некоторых телефонах это даже будет сбой. Лучше всего было бы использовать один холст с отслеживанием состояния приложения. И тогда в методе краски у вас будет

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

Существуют более эффективные способы обработки состояния приложения с помощью экранных объектов, которые сделали бы дизайн чище, но я думаю, что вы поняли:)

/ JaanusSiim

0 голосов
/ 25 ноября 2008

Гипотетически, использование 1 холста с машинным кодом для вашего приложения - хорошая идея. Однако единственное устройство, на котором я должен тестировать приложения (MOTO v3), дает сбой во время загрузки ресурсов только потому, что в 1 GameCanvas слишком много кода / для загрузки (еще не пробовал с Canvas). Это так же больно, как и реально, и я не нашел решения проблемы. Если вам повезло иметь большое количество устройств для тестирования, стоит реализовать оба подхода и в значительной степени создать версии вашей игры для каждого устройства.

0 голосов
/ 17 сентября 2008

Было бы неплохо использовать класс GameCanvas, если вы пишете игру. Это намного лучше для этой цели, и при правильном использовании это должно решить вашу проблему.

0 голосов
/ 16 сентября 2008

Возможное исправление - синхронизация переключателя с помощью Display.callSerially (). Мерцание, вероятно, вызвано тем, что приложение пытается рисовать на экране, пока переключение Canvas все еще продолжается. callSerially () должен дождаться завершения перерисовки, прежде чем снова попытаться вызвать run ().

Но все это полностью зависит от телефона, так как многие устройства не поддерживают callSerially (), не говоря уже о реализации, указанной в официальной документации. Единственные устройства, которые, как мне известно, правильно работали с callSerially (), были телефоны Siemens.

Другой возможной попыткой было бы установить Thread.sleep () чего-то огромного, например, 1000 мс, чтобы убедиться, что вы предварительно вызвали свой метод setCurrent (). Таким образом, устройство может внести изменения до того, как отображаемые попытки нарисовать.

Наиболее вероятная проблема заключается в том, что это проблема устройства, а гарантированное исправление мерцания очень простое - используйте один Canvas. Вероятно, не то, что вы хотели услышать, хотя. :)

0 голосов
/ 16 сентября 2008

Вы используете двойную буферизацию? Если само устройство не поддерживает двойную буферизацию, вы должны определить внеэкранный буфер (изображение) и сначала нарисовать его, а затем нарисовать конечный результат на реальном экране. Сделайте это для каждого из ваших полотен. Вот пример:

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