Логин:   Пароль:






Новости
Рассылки
Форум
Поиск


Java
- Апплеты
- Вопрос-ответ
- Классы
- Примеры
- Руководства
- Статьи
- IDE
- Словарь терминов
- Скачать

Мобильная Java
- Игры
- Примеры
- Статьи
- WAP, WML и пр.

JavaScript
- Вопрос-ответ
- Примеры
- Статьи

Веб-мастеринг
- HTML
- CSS
- SSI

Разминка для ума
Проекты
Книги
Ссылки
Программы
Юмор :)




Rambler's Top100
Rambler's Top100

Мобильная Java: СтатьиJ2ME. Реализация Игры и графического Меню с использованием одного Canvas класса

J2ME. Реализация Игры и графического Меню с использованием одного Canvas класса

Еще год назад подавляющее большинство игр для телефонов использовали меню на основе форм - базового интерфейса телефона. Эти менюшки смотрелись убого и явно выбивались из игрового дизайна. Сейчас требования к играм существенно возросли, и пользователи требуют интересных графических решений. В этой статье я хочу рассказать вам о методе, который позволит вам разбить программу на два класса - игру и меню, и использовать только один класс canvas.

Приведенный ниже метод с успехом применяется во всех наших играх. Он действительно работает.

Для начала давайте посмотрим как выглядит типичный canvas класс игры:

import javax.microedition.lcdui.*;

public class MyCanvas extends Canvas implements Runnable {

public MyCanvas(Midlet midlet) { // Конструктор
    }

public void run(){ 
     try {
       while (running) {
        //Главный игровой цикл
       }
     }
     catch(InterruptedException ie) { System.out.println(ie.toString()); }
}
protected void paint(Graphics g){ /* code */ }

synchronized void start() { /* code */ }

synchronized void stop() { /* code */ }

public void keyPressed(int keyCode) { /* code */ }
}

Это довольно простое и распространенное переопределение canvas. Вероятно что-то подобное Вы уже использовали в своих играх. Давайте разобьем этот файл на два различных canvas класса - один для экранов меню и один для игры.

Создадим два класса Menu.java и Game.java. Они осуществляют все те же функции, что и приведенный выше код. Заполним функции, необходимые для Canvas. Обратите внимание, и в ходе выполнения игры и в ходе работы с меню, программа выполняет одни и те же базовые функции, но с различным содержанием. Это позволяет нам оставить только один Canvas класс, и экспортировать различающиеся реализации извне.

public class Menu{
   boolean isActive;

   public static boolean isActive() { return isActive; }

   public static void destroy() { /* удаляет все ненужное из памяти */ }

   public static void initMenu() { /* инициализация первого меню*/ }

  private static void initRest(){ /* инициализация остальной части меню */ }

  public static void paint(Graphics g) { 
     isActive = true;

     drawMenuBackground(g);

     switch (menuType) {
         case 1: showMenuA(g); break;
         case 2: showMenuB(g); break; 
     }

   }

  public static void processKey(int keyCode, int GameActionKey) 
  { /* обработка клавиш */   }
} 

public class Game {

  boolean isActive;

  public static boolean isActive() { return isActive; }

  public static void destroy() { /* удаляем все лишнее */ }

  public static void initGame() { /* инициализация игры */ }

  public static void paint(Graphics g) { 
    // игровое действие
    isActive = true;
   }

   public static void processKey(int keyCode, int GameActionKey) 
   { /* Обработка клавиш*/ }
} 

Функция любого из этих классов может корректно заменить функции MyCanvas.

Теперь нам необходим код, который сообщит canvas-у какой из классов должен контролировать дисплей. Введем переменную типа boolean, которая будет индикатором текущего режима (ИГРА или МЕНЮ).

Вот часть кода MyCanvas, которую мы использовали в нашей первой игре MotorDuels: Outcast. Этот класс переопределяет Canvas. Если Вы ориентируетесь на Nokia, то необходимо переопределять FullCanvas, что позволит вам использовать DirectGraphics. Это означает, что Вы должны будете передавать dg наряду с g в Game.paint() и Menu.paint().

import javax.microedition.lcdui.*;

public class MyCanvas extends Canvas implements Runnable {


   private volatile Thread animationThread=null;

   private static Graphics graphics;
   private static boolean running;


   public static boolean inMenu = true;
   public static boolean doInit = true;

   private static final int SLEEP = 5; 


   public MyCanvas(MyGame mygame) {
      buffer=Image.createImage(MyGame.canvasWidth, MyGame.canvasHeight);
      graphics=buffer.getGraphics();
   }


   public void run(){ //main_game_loop
      try {
         while (running) {

            if (doInit){
               doInit=false;
               if (inMenu) Menu.initMenu();
               else Game.initGame();
            }

            if (inMenu) {
               if (!Menu.isActive()) {
                  doInit=true;
                  inMenu=false;
                  Menu.destroy();
                  Sounds.destroyMenu();
               }
            } else {
            if (!Game.isActive()) {
               inMenu = true;
               doInit = true;
               Game.destroy();
               }

            }

            repaint(0,0,MyGame.canvasWidth, MyGame.canvasHeight);
            serviceRepaints();
            Thread.sleep(SLEEP);
         }
      }
   catch(InterruptedException ie) { System.out.println(ie.toString()); }
}


protected void paint(Graphics g){



   if (inMenu) Menu.paint(g);
   else Game.paint(g); 

}


   synchronized void start()
   {
      running=true;
      animationThread=new Thread(this);
      animationThread.start();
   }

synchronized void stop() { running=false; }


public void keyPressed(int keyCode) {
   if (allowKeys) {
      if (inMenu) {
         Menu.processKey(keyCode, getGameAction(keyCode));
      }
      else {
         Game.processKey(keyCode, getGameAction(keyCode));
      }
   }

}

}

Как видите, наш класс не только проверяет какой из методов paint() должен использоваться, но и следит за своевременным завершением метода init(). Мы также разделяем обработку клавиш keypressed(), так что игра и меню используют собственные обработчики.

Стоит ли применять этот метод?

К недостаткам этого подхода можно отнести необходимость следить за правильностью размещения элементов меню на экране. Кроме того, графическое меню занимает намного больше места в jar архиве, чем реализованное на основе форм.

На мой взгляд, преимущества, которое дает этот подход, более значимы. Вы получаете красивое меню, органично сочетающееся с Вашей игрой и дополняющее игровую атмосферу. Кроме того, телефоны с каждом годом оснащаются все большим объем памяти.

Несомненно, современные разработчики игр должны снабжать свои продукты качественными меню. Требования к памяти в последнее время становятся менее жесткими, так что не стоит экономить на удобстве пользователя и атмосфере игры. Надеюсь, данная статья пригодится Вам.




Автор оригинальный статьи: civax
Перевод: aRix
www.mobilab.ru

Warning: mysql_connect() [function.mysql-connect]: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) in /pub/home/javaport/javaportal/books/show2b.php on line 11

Warning: mysql_db_query() [function.mysql-db-query]: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) in /pub/home/javaport/javaportal/books/show2b.php on line 19

Warning: mysql_db_query() [function.mysql-db-query]: A link to the server could not be established in /pub/home/javaport/javaportal/books/show2b.php on line 19

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /pub/home/javaport/javaportal/books/show2b.php on line 30
Узнай о чем ты на самом деле сейчас думаешь тут.


[an error occurred while processing this directive]



Warning: mysql_connect() [function.mysql-connect]: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) in /pub/home/javaport/javaportal/news/worldnews.php on line 91

Warning: mysql_db_query() [function.mysql-db-query]: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) in /pub/home/javaport/javaportal/news/worldnews.php on line 93

Warning: mysql_db_query() [function.mysql-db-query]: A link to the server could not be established in /pub/home/javaport/javaportal/news/worldnews.php on line 93

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /pub/home/javaport/javaportal/news/worldnews.php on line 95