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

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

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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 22 23 24 25 26 27 28 29 30 ... 87
Перейти на страницу:

private Sprite[] roidSpace = new Sprite[3];

В методе start() выполняется инициализация спрайтов астероида следующим кодом:

Image img = Image.createImage(«/Roid.png»);

roidSprite[0] = new Sprite(img, 42, 35);

roidSprite[1] = new Sprite(img, 42, 35);

roidSprite[2] = new Sprite(img, 42, 35);

Как вы видите, изображение астероида (Roid.png) создается один раз, а затем передается каждому конструктору спрайта. Также при инициализации изменилось и начальное положение НЛО:

ufoSprite.setPosition((getWidth() – ufoSprite.getWidth()) / 2, (getHeight() – ufoSprite.getHeight()) / 2);

Хотя этот код может показаться странным, но он не делает ничего особенного, просто выводит спрайт в центре экрана, чтобы НЛО сразу не столкнулся с астероидом, который стартует из точки (0,0). В методе update() находятся наиболее интересные новые строки кода. Вся обработка пользовательского ввода сосредоточена в следующем фрагменте кода:

int keyState = getKeyStates();

if ((keyState & LEFT_PRESSED) != 0)

ufoXSpeed–;

else if ((keyState & RIGHT_PRESSED) != 0)

ufoXSpeed++;

if ((keyState & UP_PRESSED) != 0)

ufoYSpeed–;

else if ((keyState & DOWN_PRESSED) != 0)

ufoYSpeed++;

ufoXSpeed = Math.min(Math.max(ufoXSpeed, -8), 8); //Скорость НЛО устанавливается случайно из диапазона от -8 до 8

ufoYSpeed = Math.min(Math.max(ufoYSpeed, -8), 8);

Этот код просто проверяет нажатия четырех клавиш управления и в соответствии с этим изменяет скорость НЛО. Обратите внимание, что и в этом случае скорость ограничена 8 вне зависимости от того, сколько раз была нажата та или иная клавиша. После того как скорость изменена, НЛО обновляется следующим кодом:

ufoSprite.move(ufoXSpeed, ufoYSpeed); checkBounds(ufoSprite);

Известный метод move() перемещает спрайт, а метод checkBounds() проверяет, не вышел ли НЛО за границы экрана. Проверка не изменилась, но ее код оформлен отдельным методом. Это очень важно, поскольку вам необходимо выполнить аналогичную проверку и для астероидов. Для этого нецелесообразно копировать код, если можно использовать существующий. Обновление спрайтов астероидов производится в цикле, который выполняет несколько функций. Ниже приведено начало цикла:

for (int i = 0; i < 3; i++) {

Первое, что нужно выполнить в цикле, – это переместить астероиды и проверить, не вышли ли они за границы экрана:

roidSprite[i].move(i + 1, 1 – i); checkBounds(roidSprite[i]);

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

if (i == 1)

roidSprite[i].prevFrame();

else

roidSprite[i].nextFrame();

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

if (ufoSprite.collidesWith(roidSprite[i], true)) {

// воспроизвести предупреждающий звук

AlertType.ERROR.playSound(display);

// вернуть спрайт в исходное положение и обнулить скорости

ufoSprite.setPosition((getWidth() – ufoSprite.getWidth()) / 2, //Спрайт выводится в центре игрового экрана, его скорость равна 0

(getHeight() – ufoSprite.getHeight()) / 2);

ufoXSpeed = ufoYSpeed = 0;

for (int j = 0; j < 3; j++)

roidSprite[j].setPosition(0, 0);

// нет необходимости обновлять спрайты астероидов

break;

}

}

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

for (int i = 0; i < 3; i++) roidSprite[i].paint(g);

На этом весь новый код мидлета UFO 2 завершен. В листинге 6.1 приведен полный код нового класса UFOCanvas. Листинг 6.1. Класс UFOCanvas, выполняющий роль холста для мидлета UFO 2

import javax.microedition.lcdui.*;

import javax.microedition.lcdui.game.*;

import java.util.*;

import java.io.*;

public class UFOCanvas extends GameCanvas implements Runnable {

private Display display;

private boolean sleeping;

private long frameDelay;

private Random rand;

private Sprite ufoSprite;

private int ufoXSpeed, ufoYSpeed;

private Sprite[] roidSprite = new Sprite[3]; //В игре UFO 2 есть 3 спрайта астероида

public UFOCanvas(Display d) {

super(true);

display = d;

// установить частоту кадров (30 fps)

frameDelay = 33;

}

public void start() {

// установить холст как текущий экран

display.setCurrent(this);

// инициализировать генератор случайных чисел

rand = new Random();

// инициализировать спрайты НЛО и астероидов

ufoXSpeed = ufoYSpeed = 0;

try {

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

ufoSprite.setPosition((getWidth() – ufoSprite.getWidth()) / 2,

(getHeight() – ufoSprite.getHeight()) / 2);

Image img = Image.createImage("/Roid.png");

roidSprite[0] = new Sprite(img, 42, 35);

roidSprite[1] = new Sprite(img, 42, 35);

roidSprite[2] = new Sprite(img, 42, 35);

}

catch (IOException e) {

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

}

// запустить поток анимации

sleeping = false;

Thread t = new Thread(this);

t.start();

}

public void stop() {

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

sleeping = true;

}

public void run() {

Graphics g = getGraphics();

// игровой цикл

while (!sleeping) {

update();

draw(g);

try {

Thread.sleep(frameDelay);

}

catch (InterruptedException ie) {}

}

}

private void update() {

// обработка пользовательского ввода, изменение скорости НЛО

int keyState = getKeyStates();

if ((keyState & LEFT_PRESSED) != 0) //Клавиши со стрелками изменяют скорость НЛО по всем четырем направлениям

ufoXSpeed–;

else if ((keyState & RIGHT_PRESSED) != 0)

ufoXSpeed++;

if ((keyState & UP_PRESSED) != 0)

ufoYSpeed–;

else if ((keyState & DOWN_PRESSED) != 0)

ufoYSpeed++;

ufoXSpeed = Math.min(Math.max(ufoXSpeed, -8), 8);

ufoYSpeed = Math.min(Math.max(ufoYSpeed, -8), 8);

// переместить спрайт НЛО

ufoSprite.move(ufoXSpeed, ufoYSpeed);

checkBounds(ufoSprite);

// обновить спрайты астероидов

for (int i = 0; i < 3; i++) {

// переместить спрайты астероидов

roidSprite[i].move(i + 1, 1 – i);

checkBounds(roidSprite[i]); //Эта строка кода отвечает за отрисовку астероида при достижении границ экрана

// изменить отображаемый фрейм астероида

if (i == 1) //Индекс астероида определяет направление анимации

roidSprite[i].prevFrame();

else

roidSprite[i].nextFrame();

// проверить столкновение НЛО с астероидом

if (ufoSprite.collidesWith(roidSprite[i], true)) { //Поскольку второй параметр метода collidesWith() равен true, то выполняется пиксельное детектирование столкновения

// воспроизвести предупреждающий звук

AlertType.ERROR.playSound(display);

// восстановить исходные положения и скорости объектов

ufoSprite.setPosition((getWidth() – ufoSprite.getWidth()) / 2,

(getHeight() – ufoSprite.getHeight()) / 2);

ufoXSpeed = ufoYSpeed = 0;

for (int j = 0; j < 3; j++)

roidSprite[j].setPosition(0, 0);

// нет необходимости обновлять спрайты астероидов

break;

}

}

}

private void draw(Graphics g) {

// Clear the display

g.setColor(0x000000);

g.fillRect(0, 0, getWidth(), getHeight());

// нарисовать спрайт НЛО

ufoSprite.paint(g);

// нарисовать спрайты астероидов

for (int i = 0; i < 3; i++)

roidSprite[i].paint(g);

// отобразить содержимое буфера на экране

flushGraphics();

}

private void checkBounds(Sprite sprite) {

// проверить положение спрайта

if (sprite.getX() < -sprite.getWidth())

sprite.setPosition(getWidth(), sprite.getY());

else if (sprite.getX() > getWidth())

sprite.setPosition(-sprite.getWidth(), sprite.getY());

if (sprite.getY() < -sprite.getHeight())

sprite.setPosition(sprite.getX(), getHeight());

else if (sprite.getY() > getHeight())

sprite.setPosition(sprite.getX(), -sprite.getHeight());

}

}

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

Тестирование приложения

Тестировать мидлет UFO 2 намного интереснее, чем все предыдущие приложения, поскольку теперь вы можете управлять летающим объектом. На рис. 6.4 показан мидлет UFO 2.

Рис. 6.4. В мидлете UFO 2 вы можете управлять летающим объектом и сталкиваться с астероидами

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

Резюме

Эффективное взаимодействие игрока с приложением – это критический фактор при разработке игр. Разработчику очень важно тщательно проработать пользовательский ввод, чтобы он был максимально эффективным в условиях ограниченного пользовательского интерфейса мобильного устройства. В этой главе шла речь о том, как обрабатывать ввод с клавиатуры мобильного устройства – это удивительно просто. Вы также узнали, как детектировать столкновения спрайтов и использовать фреймовую анимацию. Хотя, несомненно, пример UFO 2, созданный в этой главе, можно улучшить, он сочетает в себе все элементы разработки мобильной игры.

В следующей главе вы непосредственно окунетесь в мир программирования мобильных игр и создадите первую мобильную игру Henway, которая во многом похожа на классическую аркаду Frogger.

Еще немного об играх

Пора сделать что-то действительно креативное! Я хочу, чтобы вы добавили еще один анимационный спрайт в мидлет UFO 2. Это может быть спутник, странный пришелец или комета, бороздящая космические просторы, – все, что захотите. Ниже приведено пошаговое описание, как это сделать:

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