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



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



Анимация в игровом процессе строится на основе последовательной цепочки рисунков. Как вы уже знаете, отдельно взятый рисунок из анимационной последовательности в 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 и посмотрите работу этого примера. На экране телефона матрос с помощью семафорной азбуки передает слово «анимация».

Назад Начало Вперед



Книжный магазин