Категории
Самые читаемые
onlinekniga.com » Компьютеры и Интернет » Программирование » Создание игр для мобильных телефонов - Майкл Моррисон

Создание игр для мобильных телефонов - Майкл Моррисон

Читать онлайн Создание игр для мобильных телефонов - Майкл Моррисон

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 18 19 20 21 22 23 24 25 26 ... 87
Перейти на страницу:

monsterSprite.move(-5, 10);

В этом примере спрайт перемещается на 5 пикселей влево и 10 пикселей вниз. Отрицательные смещения задают перемещения влево или вверх, а положительные – вправо или вниз. 3. поскольку c каждым объектом класса Sprite ассоциировано изображение, то метод paint() рисует изображение в заданном месте:

monsterSprite.paint(g).

В этом коде предполагается, что у вас есть объект класса Graphics с именем g, такой объект обязательно должен присутствовать в любой игре.

Вы познакомились с основами спрайтовой анимации в MIDP API. Нам осталось только рассмотреть класс GameCanvas, специально предназначенный для анимации благодаря двойной буферной анимации.

Создание плавной анимации с помощью класса GameCanvas

Если бы вы попытались использовать все, что узнали о программировании спрайтовой анимации, и создали бы мидлет с использованием обычного класса Canvas,TO в результате получили бы прерывистую анимацию. Такой эффект возникает вследствие того, что перед отображением картинки экран очищается. Иначе говоря, при каждом перемещении объекты анимации стираются и перерисовываются. Поскольку отображение и стирание происходит непосредственно на экране, возникает эффект прерывности анимации. Для наглядности представьте себе фильм, в котором между двумя последовательными кадрами отображается белый экран. Несмотря на то что иллюзия движения будет создаваться по-прежнему, между фреймами будет выводиться пустой экран.

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

Рис. 5.6. Анимация с двойной буферизацией устраняет эффект прерывистости, возникающей при использовании однобуферной анимации...

В копилку Игрока

Буфер – место в памяти, в котором можно создавать графику. В традиционной буферной анимации роль буфера выполняет экран, а при создании анимации с двойной буферизацией к экрану добавляется область памяти.

На рис. 5.6 показано, как используется буфер в памяти для выполнения всех необходимых действий. Это может показаться хитрым приемом программирования, однако все делается очень просто (благодаря MIDP 2.0 API).

Кроме стандартного класса Canvas в MIDP API существует класс GameCanvas, поддерживающий графику с двойной буферизацией. Чтобы воспользоваться преимуществами класса GameCanvas, образуйте игровой класс холста от класса GameCanvas, после чего вы сможете работать с этим объектом в обычном режиме. Однако теперь все построения будут производиться в буфере. Чтобы вывести результат на экран, воспользуйтесь методом flushGraphics().

Давайте посмотрим, как работает буфер в памяти класса GameCanvas. Когда вы делаете что-либо с объектом Graphics, ассоциированным с холстом, все построения выполняются в буфере, на экране изменения не будут видны. Вызов метода flushGraphic() позволяет отобразить все, что было построено в памяти, на экране. При этом содержимое буфера не изменяется и не стирается, а просто выводится на экран.

...

В копилку Игрока

Когда вы создаете объект класса GameCanvas, при инициализации буфер заполняется пикселями белого цвета.

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

Построение программы UFO

Хотя можно привести массу примеров написания программы с применением спрайтовой анимации, UFO (НЛО) – актуален всегда. Если вы когда-нибудь столкнетесь с тем, что в вашей игре чего-то не хватает, добавьте неопознанный летающий объект – это помогает всегда! В этом разделе вы научитесь использовать возможности MIDP для создания мидлета, в котором неопознанный летающий объект будет перемещаться по экрану. Пример UFO демонстрирует основы спрайтовой анимации, показывает, как применять эту методику на практике. По мере изучения материала книги вы будете знакомиться с новыми более интересными возможностями классов анимации MIDP.

Пример UFO использует спрайт НЛО, который хаотично перемещается по черному экрану. Спрайт НЛО – это изображение летающего объекта, в программе используются средства класса Sprite для изменения положения спрайта на экране. Вероятно, самый важный аспект программы UFO – это создание потока анимации, который обновляет и выводит спрайт НЛО через заданные промежутки времени. Поток анимации называется игровым циклом – это сердце и душа любой мобильной игры, в которой используется анимация.

Написание программного кода

Как и при написании большинства мидлетов, самое интересное начинается при создании специального класса холста, который в данном случае называется UFOCanvas. Ниже приведены члены-переменные класса UFOCanvas:

private Display display;

private boolean sleeping;

private long frameDelay;

private Random rand;

private Sprite ufoSprite;

private int ufoXSpeed, ufoYSpeed;

Переменная display уже знакома вам по предыдущим примерам, она используется для работы с дисплеем. Переменная sleeping определяет, запущен ли игровой цикл. Вы можете приостановить выполнение анимации, присвоив этой переменной значение true. Переменная frameDelay тесно связана с игровым циклом, поскольку она контролирует частоту его выполнения. Если быть более точным, то эта переменная содержит число миллисекунд между итерациями цикла. Вы можете с легкостью пересчитать это число в количество фреймов, для чего нужно на него разделить 1. Например, если величина framedelay равна 40 мс (или 0.04 с), то частота кадров будет равна 25. Аналогично, вы можете преобразовать частоту кадров во временной интервал между ними, для чего нужно поделить 1 на частоту и умножить на 1000. Например:

1/30 кадр/с = 0.333333 с = 33 мс

Член-переменная класса rand – это экземпляр стандартного генератора случайных чисел MIDP, он используется для создания произвольного движения объекта по экрану. Спрайт НЛО хранится в переменной ufoSprite, которая является объектом класса Sprite. Скорость спрайта хранится отдельно от самого спрайта – в переменной ufoSpeed.

...

Совет Разработчику

С практической точки зрения, обычно лучше создавать спрайты как отдельные классы, производные от класса Sprite. Однако поскольку спрайт НЛО достаточно прост, нет необходимости создавать для него отдельный класс. Большинство спрайтов, с которыми вы столкнетесь в книге, будут созданы как отдельные классы, производные от Sprite.

Чуть раньше я упомянул, что переменная frameDelay определяет частоту кадров анимации мидлета UFO. Эта переменная инициализируется в конструкторе мидлета:

frameDelay = 33;

Возвращаясь к указанному ранее уравнению, вы можете посчитать, что этот интервал времени соответствует частоте 30 кадров/с. Если вы вспомните, о чем говорилось в начале главы, то исходя из того, что современные мобильные телефоны поддерживают такую частоту, она обеспечивает плавную анимацию. Это тот случай, когда тестирование на реальном устройстве важно. Большая часть инициализирующего кода мидлета UFO расположена в методе start(). Ниже приведена часть кода, инициализирующего спрайт:

ufoXSpeed = ufoYSpeed = 3;

try {

ufoSprite = new Sprite(Image.createImage("/Saucer.png"));

ufoSprite.setPosition(0, 0);

}

catch (IOException e) {

System.err.println("Failed loading image!");

}

Компоненты X и Y скорости спрайта равны 3, поэтому спрайт будет перемещаться на три пикселя вниз и вправо за одну итерацию. Отрицательные значения компонента скорости говорят о том, что спрайт перемещается вверх и влево. Чтобы создать объект класса Sprite, передайте созданное изображение конструктору этого класса. Начальное положение спрайта равно (0,0) – верхний левый угол экрана. Поток анимации устанавливается также в методе start():

sleeping = false;

Thread t = new Thread(this);

t.start();

Сначала переменной sleeping присваивается значение false, это означает, что выполнение цикла разрешено. Затем создается объект класса Thread, которому передается холст с помощью параметра this. Поток вызывает метод start(), который запускает и приостанавливает выполнение игрового цикла. Важно предусмотреть средства остановки игрового цикла, для чего предусмотрен метод stop():

public void stop() {

// остановить анимацию

sleeping = true;

}

Как вы можете видеть, приостановить выполнение цикла очень легко, для этого достаточно присвоить переменной sleeping значение true. Игровой цикл расположен в методе run():

while (!sleeping) {

update();

draw(g);

try {

Thread.sleep(frameDelay);

}

catch (InterruptedException ie) {}

}

Игровой цикл – это цикл while, который выполняется до тех пор, пока значение переменной sleeping ложно. Внутри цикла вызывается метод update(), который обновляет анимацию, после чего вызывается метод draw(), обновляющий изображение. Статический метод sleep() класса Thread используется, чтобы установить задержку потока анимации, которая определяется переменной frameDelay. Эта часть кода управляет анимацией мидлета. Метод update() вызывается в цикле один раз, а следовательно, отвечает за обновление каждого фрейма анимации. Иначе говоря, метод update() вызывается 30 раз в секунду, поскольку частота смены кадров в мидлете UFO равна 30 кадров/с. В данном случае метод update() отвечает за случайное изменение скорости летающего объекта, а следовательно, и за изменение его положения. Приведенный ниже код изменяет скорость объекта:

1 ... 18 19 20 21 22 23 24 25 26 ... 87
Перейти на страницу:
На этой странице вы можете бесплатно читать книгу Создание игр для мобильных телефонов - Майкл Моррисон.
Комментарии