Чтение онлайн

ЖАНРЫ

Создание игр для мобильных телефонов
Шрифт:

private int speed; private TiledLayer barrier;

Переменная speed определяет скорость спрайта, которая измеряется в пикселях за игровой цикл. Скорости 1 или 2 хорошо подходят для того, чтобы заставить спрайты дрейфовать. Большие значения создадут иллюзию того, что спрайты передвигаются самостоятельно.

Переменная barrier – это замощенный слой, который играет роль барьера для спрайта. Эта переменная необходима, если предположить, что в большинстве игр будет использоваться слой, ограничивающий перемещения спрайтов. Этот слой может быть лабиринтом, посадочной площадкой или просто землей, но большинство игр используют такие слои. Слой-барьер, ассоциированный с дрейфующим спрайтом, не имеет ничего общего с возможностью дрейфовать, однако он необходим для детектирования столкновений со спрайтом в методе update.

Обе переменные класса DriftSprite инициализируются в конструкторе DriftSprite, код которого представлен в листинге 12.1.

Листинг 12.1. Конструктор DriftSprite инициализирует переменные скорости и слоя-барьера

public DriftSprite(Image image, int frameWidth, int frameHeight, int driftSpeed,

TiledLayer barrierLayer) {

super(image, frameWidth, frameHeight);

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

rand = new Random;

// установить скорость

speed = driftSpeed;

// установить замощенный слой-барьер

barrier = barrierLayer;

}

Конструктор DriftSprite вызывает родительский конструктор Sprite, создающий основной спрайт, а затем инициализирует специальные переменные класса DriftSprite.

Метод update – это интересная часть кода класса DriftSprite. В листинге 12.2 приведен код этого метода.

Листинг 12.2. Метод update класса DriftSprite перемещает Sprite в произвольном направлении и определяет столкновение со слоем-барьером

public void update {

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

int xPos = getX;

int yPos = getY;

// переместить спрайт случайным образом, чтобы создать иллюзию дрейфа

switch (Math.abs(rand.nextInt % 4)) {

// переместить влево

case 0:

move(-speed, 0);

break;

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

case 1:

move(speed, 0);

break;

// переместить вверх

case 2:

move(0, -speed);

break;

// переместить вниз

case 3:

move(0, speed);

break;

}

// проверить столкновение со слоем-барьером

if ((barrier != null) && collidesWith(barrier, true)) { //Если в новом положении детектировано столкновение, то необходимо вернуть спрайт в предыдущее положение

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

setPosition(xPos, yPos);

}

// перейти к следующему фрейму анимации спрайта

nextFrame;

}

Метод update начинается с того, что сохраняется положение спрайта, поскольку эта информация может понадобиться позже, если произойдет столкновение спрайта со слоем-барьером. Затем спрайт случайным образом перемещается в одном из четырех возможных направлений: вверх, влево, вправо или вниз. Фрагмент кода в конце метода update проверяет столкновение спрайта со слоем-барьером, чтобы убедиться, что значение barrier отлично от null. Этот код позволяет ограничивать перемещение спрайтов. Если определено столкновение, то спрайт возвращается в положение, предшествующее смещенному.

...

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

Если значение переменной barrier равно null, то спрайт будет ограничен в методе update. Иначе говоря, вы можете создать свободно перемещающиеся спрайты, для чего конструктору DriftSpriteдостаточно передать значение null. Если бы вы захотели добавить в игру High Seas птицу или летающего противника, вероятно, вы бы поступили именно так, ведь для такого объекта земля – не помеха.

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

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

Объявление переменных класса

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

private LayerManager layers;

private int xView, yView;

private TiledLayer waterLayer;

private TiledLayer landLayer;

private int waterDelay;

private int[] waterTile = { 1, 3 }; //В слое воды используются два различных анимационных изображения

private Image infoBar;

private Sprite playerSprite;

private DriftSprite[] pirateSprite = new DriftSprite[2];

private DriftSprite[] barrelSprite = new DriftSprite[2];

private DriftSprite[] mineSprite = new DriftSprite[5];

private DriftSprite[] squidSprite = new DriftSprite[5];

private Player musicPlayer;

private Player rescuePlayer;

private Player minePlayer;

private Player gameoverPlayer;

private boolean gameOver;

private int energy, piratesSaved;

Первые несколько переменных используются для хранения менеджера слоев, положения окна вида, слоя воды и слоя суши. Переменные waterDelay и waterTile контролируют анимацию воды в замощенном слое водного слоя. Поскольку в игре два различных анимационных элемента воды, переменная waterTile – это массив целых чисел, состоящий из двух элементов.

Переменная infoBar хранит растровое изображение, используемое как фон информационной строки, в которой отображается энергия корабля и число спасенных пиратов. Затем создаются несколько спрайтов: пиратский корабль, два пирата и пара бочек, пять мин и пять осьминогов. Интересно заметить, что в игре больше не будут создаваться какие-либо спрайты. Позже вы узнаете, как повторно использовать спрайты, чтобы создать иллюзию того, что их число увеличилось.

Звуковые эффекты и музыка в игре воспроизводятся с помощью объектов класса Player. И наконец, состояние игры отражается переменными energy и piratesSaved.

Разработка метода start

Метод start в игре High Seas выполняет инициализацию всех переменных класса. Например, следующий код создает изображение для информационной строки, а также замощенные слои воды и суши:

try {

infoBar = Image.createImage("/InfoBar.png");

waterLayer = new TiledLayer(24, 24, Image.createImage("/Water.png"), 32, 32);

landLayer = new TiledLayer(24, 24, Image.createImage("/Land.png"), 32, 32);

}

catch (IOException e) {

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

}

Если вы вспомните, то в водном слое используются два анимационных элемента, имитирующих движение воды. Ниже приведен код, создающий эти элементы:

waterLayer.createAnimatedTile(1); waterLayer.createAnimatedTile(3);

Два анимационных элемента имеют различные индексы (1 и 3), это важно, поскольку элементы при создании анимации будут отображать различные картинки. Если использовались одинаковые инициализирующие значения, то вы не увидите никакой разницы. Также в этой главе вы разработали водный слой, результатом которого является массив целых чисел waterMap, содержащий карту слоя. Ниже приведен код, инициализирующий замощенный слой значениями из этого массива:

for (int i = 0; i < waterMap.length; i++) {

int column = i % 24;

int row = (i – column) / 24;

waterLayer.setCell(column, row, waterMap[i]);

}

Чтобы завершить инициализацию водного слоя, необходимо установить начальное значение для переменной waterDelay, которая используется как счетчик, регулирующий скорость анимации:

waterDelay = 0;

Подобно водному слою, слой суши описывается картой индексов landMap, содержание которой вы видели ранее. Следующий код выполняет инициализацию слоя суши:

for (int i = 0; i < landMap.length; i++) {

int column = i % 24;

int row = (i – column) / 24;

landLayer.setCell(column, row, landMap[i]);

}

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

try {

playerSprite = new Sprite(Image.createImage("/PlayerShip.png"), 43, 45);

int sequence2[] = { 0, 0, 0, 1, 1, 1 };

int sequence4[] = { 0, 0, 1, 1, 2, 2, 3, 3 };

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

pirateSprite[i] = new DriftSprite(Image.createImage("/Pirate.png"), //Четвертый и пятый параметры конструктора DriftSprite – это скорость спрайта и слой-барьер соответственно

29, 29, 2, landLayer);

pirateSprite[i].setFrameSequence(sequence2);

placeSprite(pirateSprite[i], landLayer);

barrelSprite[i] = new DriftSprite(Image.createImage("/Barrel.png"),

24, 22, 1, landLayer);

barrelSprite[i].setFrameSequence(sequence4);

placeSprite(barrelSprite[i], landLayer); //Метод placeSprite случайным образом размещает спрайт на карте

}

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

mineSprite[i] = new DriftSprite(Image.createImage("/Mine.png"),

27, 23, 1, landLayer);

mineSprite[i].setFrameSequence(sequence2);

placeSprite(mineSprite[i], landLayer);

squidSprite[i] = new DriftSprite(Image.createImage("/Squid.png"),

24, 35, 3, landLayer);

squidSprite[i].setFrameSequence(sequence2);

placeSprite(squidSprite[i], landLayer);

}

}

catch (IOException e) {

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

}

Спрайт игрока создается в тот момент, когда размер фрейма передается конструктору. Остальные спрайты – это объекты класса DriftSprite, они имеют различные скорости. Например, спрайты пиратов имеют скорость 2, а спрайты мин и бочек перемещаются со скоростью 1. Смысл в том, что пираты могут плавать, поэтому они должны перемещаться быстрее бочек и мин, которые на самом деле просто дрейфуют. Аналогично, спрайты осьминогов имеют скорость 3. Важно отметить, что переменная landLayer выполняет функции барьера для всех спрайтов.

Поделиться с друзьями: