Создание игр для мобильных телефонов - Майкл Моррисон
Шрифт:
Интервал:
Закладка:
0, 2, 2, 2, 2, 5, 15, 15, 15, 15, 15, 15, 6, 2, 2, 0,
0, 2, 2, 2, 2, 7, 10, 1, 1, 1, 1, 1, 16, 2, 2, 0,
0, 2, 2, 2, 2, 2, 14, 1, 1, 1, 1, 1, 16, 2, 2, 0,
0, 2, 2, 2, 2, 2, 7, 10, 1, 1, 1, 1, 16, 2, 2, 0,
0, 2, 2, 2, 2, 2, 2, 14, 1, 1, 1, 1, 16, 2, 2, 0,
0, 2, 2, 2, 2, 2, 2, 14, 1, 9, 10, 1, 16, 2, 2, 0,
0, 2, 2, 5, 15, 6, 2, 14, 1, 11, 12, 1, 16, 2, 2, 0,
0, 2, 2, 14, 1, 16, 2, 7, 13, 13, 13, 13, 8, 2, 2, 0,
0, 2, 2, 7, 13, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0,
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0,
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0К сожалению, этот код не имеет особого смысла, если не посмотреть на изображение, ассоциированное с этим замощенным слоем. На рис. 11.3 показаны элементы слоя, которые используются для построения фонового слоя.
Рис. 11.3. Фоновый замощенный слой можно визуально представить, если вместо индексов подставить соответствующие изображенияЕсли вы индексам поставите в соответствие изображения, то вам нетрудно будет представить карту, показанную на рис. 11.2; помните, что ячейкам с индексом 0 соответствуют прозрачные области замощенного слоя, а следовательно, в этих областях не будет ничего выводиться. Карту слоя-барьера вы увидите в следующем разделе и поймете, почему края фонового слоя прозрачны. Карта преград
Слой-барьер разработан таким образом, что он выводится поверх фонового слоя. Это означает, что графика слоя-барьера выводится поверх графики фонового слоя. Более того, мидлет Wanderer 2 разработан так, что этот слой ограничивает перемещение спрайта персонажа. Иначе говоря, пустые ячейки слоя барьера означают те области карты, по которым герой может передвигаться.
На рис. 11.4 показан слой-барьер, черные области соответствуют тем областям, в которых персонаж может свободно перемещаться.
Рис. 11.4. В слое-барьере для ограничения передвижений спрайта героя используются вода, скалы и фрагменты лабиринтаБольшая часть слоя-барьера прозрачна – персонаж может свободно перемещаться. Даже фрагмент лабиринта содержит значительные прозрачные области, означающие свободу передвижения героя. Ниже приведен код карты слоя, показанного на рис. 11.4:
-1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1,
–1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1,
–1, 21, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 22, 1,
–1, 18, 0, 5, 5, 5, 5, 8, 0, 0, 8, 0, 0, 0, 20, -1,
–1, 18, 0, 0, 0, 0, 0, 0, 0, 16, 8, 0, 0, 0, 20, 1,
–1, 18, 7, 7, 7, 11, 7, 8, 0, 0, 10, 5, 0, 0, 20, -1,
–1, 18, 0, 11, 0, 0, 11, 7, 7, 12, 0, 0, 0, 0, 20, -1,
–1, 18, 0, 7, 7, 7, 0, 11, 12, 8, 0, 0, 0, 0, 20, 1,
–1, 18, 0, 11, 12, 0, 15, 10, 0, 8, 0, 0, 0, 0, 20, 1,
–1, 18, 0, 0, 13, 0, 10, 5, 5, 9, 0, 0, 0, 0, 20, -1,
–1, 18, 7, 10, 5, 9, 0, 0, 0, 0, 0, 0, 0, 0, 20, 1,
–1, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, -1,
–1, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 1,
–1, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 1,
–1, 23, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 24, -1,
–1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1Этот код карты сложно понять, не имея представления о том, какие изображения стоят за индексами. На рис. 11.5 показаны изображения, из которых создается замощенный слой-барьер.
Рис. 11.5. Можно представить, как выглядит слой-барьер, если расположить элементы в нужном порядкеВозвращаясь к коду карты, сложно не заметить, что в карте присутствуют элементы с отрицательными индексами. Если вы вспомните, о чем шла речь чуть раньше в этой главе, отрицательные индексы используются для обозначения анимационных элементов слоя. В нашем примере элементы с индексом -1 означают анимационный элемент с изображением воды. Обратите внимание, что одни элементы в замощенном слое-барьере имеют индекс -1, а другие – статические, с индексом 1. Это делает анимацию более реалистичной, потому что не все элементы должны изменяться одновременно.
Более подробно с созданием анимации элементов слоя вы познакомитесь в следующем разделе. А перед тем как вы перейдете к ней, посмотрите на то, как выглядят фоновый слой и слой-барьер вместе (рис. 11.6).
Рис. 11.6. Пример Wanderer 2 состоит из двух слоев – фона и лабиринтаРисунок 11.6 должен прояснить все, что касается пустых элементов слоев. Пустые элементы фонового слоя оказываются под элементами слоя-барьера, в то время как сквозь пустые элементы слоя-преграды видны трава и песок фонового слоя. Слои – это сущность примера Wanderer 2, это отражается в коде, который будет приведен далее.
Написание программного кода
В примере Wanderer 2 необходимо ввести ряд переменных для управления дополнительным слоем, менеджером слоев, окном вида, а также текущим изображением воды. Ниже приведены наиболее важные переменные мидлета Wanderer 2:
private LayerManager layers;
private int xView, yView; //Важно отслеживать положение окна вида менеджера слоев
private TiledLayer backgroundLayer;
private TiledLayer barrierLayer;
private int waterDelay, waterTile;
private Sprite personSprite;Первая переменная – это менеджер слоев, в ней нет ничего удивительного. Переменные xView и yView хранят координаты положения окна вида – текущей видимой области слоев. Если вы вспомните, о чем шла речь ранее, окно вида используется для отображения видимой области слоев, при этом отпадает необходимость перемещать сами слои, как это было сделано в примере Wanderer.
Переменные waterDelay и waterTile помогают создавать анимационные элементы с изображением воды. Первая из этих переменных задает скорость анимации, а вторая содержит номер выводимого на экран изображения.
Два слоя создаются как объекты класса TiledLayer. Следующий код задает одинаковые размеры слоев:try {
backgroundLayer = new TiledLayer(16, 16, //Фоновый слой и слой-преграда имеют одинаковый размер
Image.createImage("/Background.png"), 48, 48);
barrierLayer = new TiledLayer(16, 16,
Image.createImage("/Barrier.png"), 48, 48);
}
catch (IOException e) {
System.err.println("Failed loading images!");
}Код, создающий фоновый слой и инициализирующий холст, расположен в методе start() класса WCanvas. Так, фоновый слой задается массивом целых чисел (картой):
int[] backgroundMap = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //Нули в коде – это пустые ячейки, которые будут покрыты слоем-барьером
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0,
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0,
0, 2, 2, 2, 2, 5, 15, 15, 15, 15, 15, 15, 6, 2, 2, 0,
0, 2, 2, 2, 2, 7, 10, 1, 1, 1, 1, 1, 16, 2, 2, 0,
0, 2, 2, 2, 2, 2, 14, 1, 1, 1, 1, 1, 16, 2, 2, 0,
0, 2, 2, 2, 2, 2, 7, 10, 1, 1, 1, 1, 16, 2, 2, 0,
0, 2, 2, 2, 2, 2, 2, 14, 1, 1, 1, 1, 16, 2, 2, 0,
0, 2, 2, 2, 2, 2, 2, 14, 1, 9, 10, 1, 16, 2, 2, 0,
0, 2, 2, 5, 15, 6, 2, 14, 1, 11, 12, 1, 16, 2, 2, 0,
0, 2, 2, 14, 1, 16, 2, 7, 13, 13, 13, 13, 8, 2, 2, 0,
0, 2, 2, 7, 13, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0,
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0,
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};Такой массив должен быть вам знаком. Почти такой же код вы видели, когда познакомились с описанием фонового слоя. Следующий код инициализирует замощенный слой в соответствии с его картой:
for (int i = 0; i < backgroundMap.length; i++) {
int column = i % 16;
int row = (i – column) / 16;
backgroundLayer.setCell(column, row, backgroundMap[i]);
}Наиболее важный элемент этого кода – это число 16, которое определяет число строк и столбцов в замощенном слое. Аналогично выполняется инициализация слоя-барьера. Ниже приведен код карты этого слоя, который также задан в виде массива целых чисел:
barrierLayer.createAnimatedTile(1);
int[] barrierMap = {
–1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, //Ячейки с индексом -1 будут содержать анимационные изображения воды
–1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1,
1, 21, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 22, 1,
1, 18, 0, 5, 5, 5, 5, 8, 0, 0, 8, 0, 0, 0, 20, -1,
1, 18, 0, 0, 0, 0, 0, 0, 0, 16, 8, 0, 0, 0, 20, 1,
–1, 18, 7, 7, 7, 11, 7, 8, 0, 0, 10, 5, 0, 0, 20, -1,
1, 18, 0, 11, 0, 0, 11, 7, 7, 12, 0, 0, 0, 0, 20, -1,
–1, 18, 0, 7, 7, 7, 0, 11, 12, 8, 0, 0, 0, 0, 20, 1,
1, 18, 0, 11, 12, 0, 15, 10, 0, 8, 0, 0, 0, 0, 20, 1,
1, 18, 0, 0, 13, 0, 10, 5, 5, 9, 0, 0, 0, 0, 20, -1,
–1, 18, 7, 10, 5, 9, 0, 0, 0, 0, 0, 0, 0, 0, 20, 1,
–1, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, -1,
1, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 1,
1, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 1,
–1, 23, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 24, -1,
–1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1
};Эта карта инициализирует слой в следующем фрагменте кода:
for (int i = 0; i < barrierMap.length; i++) {
int column = i % 16;
int row = (i – column) / 16;
barrierLayer.setCell(column, row, barrierMap[i]);
}После того как слои созданы и инициализированы, можно переходить к созданию менеджера слоев. Помните, что менеджер слоев еще и управляет спрайтом героя, а также окном вида на спрайт и замощенные слои. Ниже приведен код, создающий и инициализирующий менеджер слоев и окно вида:
layers = new LayerManager();
layers.append(personSprite); //Порядок добавления слоев очень важен, поскольку он определяет их Z-порядок
layers.append(barrierLayer);
layers.append(backgroundLayer);
xView = (backgroundLayer.getWidth() – getWidth()) / 2;
yView = (backgroundLayer.getHeight() – getHeight()) / 2;
layers.setViewWindow(xView, yView, getWidth(), getHeight());
personSprite.setPosition(xView + (getWidth() -
personSprite.getWidth()) / 2,
yView + (getHeight() – personSprite.getHeight()) / 2);Метод менеджера слоев append() добавляет слой. Важно отметить, что слои добавляются сверху вниз. Иначе говоря, последний слой будет помещен под предыдущими. Поэтому сначала добавляется спрайт персонажа, а затем – слой-барьер и фоновый слой. Затем задаются положение и размер окна вида. Его размер равен размеру холста, а его положение хранится в переменных xView и yView и инициализируется координатами центра слоев. Спрайт героя размещается в центре экрана. Ранее вы узнали, что определенные элементы замощенного слоя – анимационные. Для создания анимации необходимы две переменные. Вот как они инициализируются:
waterDelay = 0; waterTile = 1;
Переменная waterDelay – это просто счетчик, поэтому она инициализируется значением 0. Переменная waterTile содержит номер первого изображения анимационного элемента замощенного слоя, в данном случае -1 (рис. 11.5). Переменные для создания анимации воды используются в методе update(), в котором также реализована большая часть логики мидлета. В листинге 11.1 приведен код метода update(). Листинг 11.1. Метод update() класса WCanvas перемещает окно вида в соответствии с нажатиями клавиш
private void update() {