Программирование мобильных телефонов

         

Анимация в игровом процессе




Анимация в игровом процессе строится на основе последовательной цепочки рисунков. Как вы уже знаете, отдельно взятый рисунок из анимационной последовательности в Java 2 ME называется фреймом. Для того чтобы осуществить плавную анимацию в игре, необходимо выполнить ряд сменяющих друг друга рисунков. Посмотрите на рис. 8.3, где изображен матрос с флажками.



Рис. 8.3. Анимационная последовательность


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

Анимация повсеместно используется в компьютерных и мобильных играх. Вы наверно замечали, что при перемещении в игре персонажа, он производит ряд повторяющихся движений, создавая видимость игрового цикла. Такие элементарные движения следствие перехода" по имеющимся фреймам исходного изображения. Для этих целей в Java 2 ME имеются специальные методы класса Sprite.

Метод nextFrame () позволяет осуществить переход по всем имеющимся фреймам исходного изображения. Как только достигается последний фрейм, то автоматически происходит переход к первому фрейму с последующим переходом по всей имеющейся последовательности, что обеспечивает цикличность анимации.

Давайте рассмотрим пример использующий анимационную последовательность, изображенную на рис. 8.3. В этом примере на экран выводится изображение матроса и осуществляется цикличный переход По всем имеющимся фреймам, создавая эффект движения матроса, который с помощью семафорной азбуки передает слово «анимация».



В листинге 8.3, а так же на компакт-диске в папке \Code\Listing8_3\src дается код примера иллюстрирующего работу анимационной последовательности.

/** Листинг 8.3 класс MainGame */ import javax.microedition.lcdui.*; import javax.microedition.midlet. * ; public class MainGame extends MIDlet implements CornmandListener { // команда выхода private Command exitMidlet = new Command(«Выход», Command.EXIT, 0); // объект класса  MyGameCanvas private MyGameCanvas mr; public void startApp() { // обрабатываем исключительную ситуацию try{ // инициализируем объект класса MyGameCanvas mr = new MyGameCanvas(); // запускаем поток mr .start(); // добавляем команду выхода mr.addCommand(exitMidlet); mr:setCommandListener{this); /7 отражаем текущий дисплей Display.getDisplay(this).setCurrent(mr); }catch (Java.io.lOException zxz) {}; } public void pauseApp() {} public void destroyApp(boolean unconditional) { // останавливаем потоку if(mr != null) mr.stop(); } public void commandAction(Command c, Displayable d) { if (с == exitMidlet) { destroyApp(false); notifyDestroyedO ;  } } } /** файл MyGameCanvas.java класс MyGameCanvas  */ import java.io. import javax.microedition.Icdui.*;  import javax.microedition.Icdui.game.*; public class MyGameCanvas extends GameCanvas implements Runnable { // создаем объект класса MySprite private Matros matros; // создаем объект класса LayerManager private LayerManager lm; // логическая переменная boolean z; public MyGameCanvas() throws IOException { // обращаемся к конструктору суперкласса Canvas super(true); // загружаем изображение Image im = Image.createlmage(«/matros.png»); // инициализируем объект matros matros = new Matros(im, 94, 100); // выбираем позицию matros.setPosition(30, 30); // инициализируем менеджер уровней 1m = new LayerManager(); // добавляем объект матроса к уровню lm.append(matros); } public void start() { { z= true; // создаем и згшускаем поток Thread t = new Thread(this); t.start () ; } // останавливаем поток public void stop() { z = false; } public void run() { // получаем графический контекст  Graphics g = getGraphics(); while (z) { // рисуем графические элементы init(g) // останавливаем цикл try { Thread.sleep(250); } catch (Java.lang.InterruptedException zxz) {}; }  } private void init(Graphics g)  { // белый цвет фона g.setColor(0xffffff); // перерисовываем экран g.fillRect(0, 0, getWidth(),getHeight()); // рисуем уровень в точке 0,0 lm.paint(g, 0 , 0) ; // рисуем анимацию matros.Animation(); // двойная буферизация iluGhGraphics(); } } /* * файл Matros.Java класс Matros * / import- javax .rnicroedition. Icdui .* ; import javax.microedition.lcdui.game.*; public class Matros extends Sprite { // конструктор public Matros(Image image, int fw, int fh) { // обращаемся к конструктору суперкласса super(image, fw, fh) ; } // метод осуществляющий анимацию public void Animation!) { // вызываем следующий фрейм nextFrame(); } }

В листинге 8.3 нам интересно несколько моментов. В классе Matros, являющимся подклассом класса Sprite, создается метод Animation (), который выглядит следующим образом:

public void Animation()  { nextFrame(); }

Метод Animation () осуществляет тот самый последовательный переход по имеющимся фреймам исходного изображения. В классе MyGameCanvas происходит создание объекта класса Matros:

private Matros matros;

Затем в конструкторе класса MyGameCanvas загружается изображение матроса и инициализируется объект matros.

Image im = Image.createlmage(«/matros.png»); matros = new Matros(im, 94, 100);

Размер одного фрейма с матросом равен 94x100 пикселей, поэтому указывается размер именно одного фрейма. По умолчанию загружается самый первый фрейм изображения, но можно использовать метод setFrame () для установки необходимого фрейма из анимационной последовательности. В методе Graphics () класса MyGameCanvas происходит вызов метода Animation ():

matros.Animation();

Это в итоге приводит к цикличному перебору всех имеющихся фреймов. Откомпилируйте код из листинга 8.3 и посмотрите работу этого примера. На экране телефона матрос с помощью семафорной азбуки передает слово «анимация».



Содержание раздела