Текст книги "Создание игр для мобильных телефонов"
![](/books_files/covers/thumbs_240/sozdanie-igr-dlya-mobilnyh-telefonov-45436.jpg)
Автор книги: Майкл Моррисон
Жанр: Зарубежная компьютерная литература, Зарубежная литература
сообщить о неприемлемом содержимом
Текущая страница: 25 (всего у книги 35 страниц) [доступный отрывок для чтения: 12 страниц]
Мидлет Lighthouse – это, вероятно, самое мудреное приложение, которое вы тестировали, поскольку оно требует наличия двух мобильных телефонов, или двух запущенных эмуляторов J2ME. Несмотря на то что я настоятельно рекомендую тестировать приложение на реальных устройствах, J2ME позволяет наглядно протестировать мидлет на двух расположенных рядом виртуальных телефонах. Чтобы протестировать мидлет Lighthouse, запустите два раза эмулятор J2ME. На одном из виртуальных телефонов выберите режим функционирования «сервер», а на другом – «клиент». На рис. 14.1 на виртуальном телефоне выбран режим сервера.
![](i_100.jpg)
Рис. 14.1. При запуске мидлета Lighthouse пользователь должен указать желаемый режим работы: клиент или сервер
После того как выбран режим сервера, пользователь видит сообщение о том, что сервер готов к работе и ожидает подключения клиента (рис. 14.2).
![](i_101.jpg)
Рис. 14.2. В режиме «сервера» мидлет ожидает подключения клиента
В другой части сетевого уравнения находится мидлет-клиент, запускаемый на другом телефоне. Когда между клиентом и сервером установлено соединение, строка статуса выводит информацию об этом.
На рис. 14.3 показано, как выглядит экран клиентского приложения после установления соединения.
![](i_102.jpg)
Рис. 14.3. В режиме клиента мидлет выводит сообщение об успешном установлении соединения
Когда соединение установлено, пользователи могу начать отправлять сообщения, используя азбуку Морзе, нажимая клавиши соответствующие точкам и тире. На рис. 14.4 показано, как клиент отправляет сообщение точка (dot) нажатием клавиши влево.
![](i_103.jpg)
Рис. 14.4. Игрок на клиентском устройстве отправляет сообщение
Как показано на рисунке, на экран выводится слово Dot (точка), означающее, что сообщение было отправлено. В это время сервер принимает это сообщение и появляется короткая вспышка света (рис. 14.5).
![](i_104.jpg)
Рис. 14.5. На серверном устройстве маяк зажигает огонь ненадолго, что соответствует точке
Пересылка сигналов азбуки Морзе продолжается до тех пор, пока клиент и сервер не завершат соединение. Хотя вы, вероятно, посчитаете, что с другим человеком проще поговорить по телефону, мидлет Lighthouse демонстрирует альтернативный способ коммуникации посредством беспроводной сети. Этот мидлет послужит основой для разработки специфических игровых соединений, речь о которых пойдет в следующей главе.
РезюмеЭта глава началась с рассказа о сетевом программировании в мобильных играх. Вы узнали, что MIDP API значительно упрощает сетевое программирование, предоставляя стандартные классы, которые выполняют большинство работы. Мы начали эту главу с изучения основ сетевых игр, после чего перешли к тому, как средствами MIDP API можно создать беспроводное соединение. Эта глава завершилась созданием мидлета, использующим мобильную сеть. Этот мидлет позволяет осуществить коммуникацию посредством азбуки Морзе и мигающих маяков.
В следующей главе продолжится разговор о сетевых беспроводных соединениях, вы создадите игру Connect 4.
ЭкскурсияМидлет Lighthouse, созданный в этой главе, познакомил вас с азбукой Морзе. Уверен, что вы вряд ли придумаете ситуацию, когда можно столкнуться с ней, однако это не такой уж и плохой способ коммуникации, если знать, как им пользоваться. В школе я использовал азбуку Морзе для переговоров с друзьями из класса перестуками по парте. Азбука Морзе позволяет общаться людям в полной тишине, используя лишь мигающие огни, или перестукиванием, если нельзя говорить. Цель моего повествования, чтобы вы занялись изучением азбуки Морзе, и в этом случае мидлет Lighthouse станет для вас куда более интересным приложением.
Глава 15
Connect 4: классическая игра по беспроводной сети
Архив Аркад
Я до сих пор отчетливо помню момент, когда впервые увидел аркаду Dragon's Lair (Логово Дракона). В то время аркада с мультипликационной графикой казалась чем-то невероятным. Dragon's Lair была создана компанией Cinematronics в 1983 году, в год выпуска игра произвела фурор благодаря великолепной графике и сюжету. Игроки поняли, что Dragon's Lair – это скорее игра, в которой игрок определяет ход игры, а не простая видеоигра. Игра предоставляла массу возможностей выбора, а следовательно, вариантов развития сюжета. Dragon's Lair по сей день является значительным моментом развития графики видеоигр, и очевидно, почему на разработку игры потребовалось 6 лет.
В предыдущей главе вы научились создавать беспроводные сетевые подключения в мидлете, который реализует концепцию клиент-сервер. В этой главе тема сетевых подключений будет продолжена. Вы пройдете через все этапы создания пошаговой сетевой игры. В игре Connect 4 вы бросаете шарики в вертикальные столбцы на игровом поле. Ваша цель положить 4 шарика в линию быстрее противника.
В этой главе вы:
► научитесь основам игры в Connect 4;
► разработаете сетевую версию игры Connect 4;
► создадите мобильную игру Connect 4, использующую датаграммное соединение;
► научитесь тестировать сетевые игры.
Обзор игры Connect 4Если вы ни разу не играли в Connect 4, давайте вкратце рассмотрим ее правила. Это очень простая игра, похожая на крестики-нолики; ваша цель – разместить в ряд, столбец или по диагонали 4 фишки. Игра происходит на поле размером 7х6 ячеек. Фишки – это цилиндры, похожие на шашки. На рис. 15.1 показана доска для игры в Connect 4.
![](i_105.png)
Рис. 15.1. Игровая доска Connect 4 имеет размер 7х6 ячеек
Особенность игры Connect 4 заключается в том, что доска располагается вертикально, а каждый столбец представляет отдельную секцию (между ячейками отсутствуют перегородки). В результате, вместо того чтобы выбирать положение для фигуры по вертикали, вы можете просто ставить фишки одну за другой. Это очень сильно влияет на стратегию игры. На рис. 15.2 показано игровое поле Connect 4 после нескольких ходов.
![](i_106.png)
Рис. 15.2. Столбцы в игре Connect 4 заполняются круглыми фигурками
![](i_107.png)
Рис. 15.3. Игра Connect 4 завершается, когда одному из игроков удается «соединить» четыре фигурки
Игра завершается, когда один из игроков выстраивает по горизонтали, вертикали или горизонтали четыре фишки. Здесь также, как и в крестиках-ноликах, возможна ничья, однако вероятность этого намного меньше из-за большего числа возможностей победить. На рис. 15.4 показана «победа» в Connect 4.
![](i_108.png)
Рис. 15.4. В положении (0,0) есть только три выигрышных комбинации
Разработка игрыВ копилку Игрока
С технической точки зрения, в игре Connect 4 вы можете выиграть всегда, вне зависимости от стратегии игрока, если делаете ход первым.
Создание игры Connect 4 будет не таким сложным занятием, если вы разобьете весь процесс на отдельные этапы, например, так:
► графика и пользовательский интерфейс;
► сетевое соединение.
► игровая логика;
В следующих разделах будут подробно рассмотрены все указанные этапы создания игры.
Как и в случае большинства игр, разработка Connect 4 начинается с разработки графики. Элементы игровой графики – это фигуры и доска. Кроме этого полезно выводить дополнительную информацию, например, информацию о статусе соединения, а также то, кому принадлежит ход. В любой момент времени строка статуса должна выводить сообщение «Waiting for player's move» (Ожидание хода игрока) или «Your turn» (Ваш ход).
Чтобы создать интуитивно понятный интерфейс в игре, полезно показывать, какая колонка выбрана в настоящий момент. Чтобы сделать ход, нужно выбрать колонку с помощью стрелок влево и вправо, и потом поставить фишку. Маркер колонки в игре Connect 4 – это графическая стрелка, цвет которой зависит от игрока (красная – для игрока серверного устройства, а синяя – для игрока клиентского устройства). Маркер колонки выводится непосредственно над выбранной колонкой, поэтому игрок всегда может знать, в какую колонку будет брошена фишка.
В копилку Игрока
На самом деле цветовое разделение указателей не является обязательным, поскольку эта информация игрокам не нужна. Однако с точки зрения тестирования игры, очень полезно окрасить указатели в разные цвета, чтобы понять, какое устройство является серверным, а какое клиентским.
Итак, в игре Connect 4 есть четыре основных графических элемента:
► доска;
► строка состояния;
► фишки;
► стрелка-маркер.
У вас уже есть опыт разработки игр с анимационными спрайтами, поэтому программирование интерфейса игры Connect 4 для вас не составит труда. Давайте перейдем к разработке логики игры.
Самое трудное препятствие в разработке логики игры Connect 4 – определение победившего игрока. Сначала это может показаться достаточно простой задачей: просто проверить наличие четырех фишек одного цвета в ряду, столбце или диагонали, так? Это и впрямь просто для человека, однако научить делать такую проверку компьютер – не такая уж и простая задача. Подумайте о том, как можно с помощью Java-кода проверить состояние игры Connect 4.
Одно из возможных решений – отслеживать всевозможные комбинации положений, приводящих к победе. Эти комбинации можно хранить в таблице, а затем использовать для определения, насколько близок каждый из игроков к победе. Хотя такой подход может показаться не столь очевидным, реализовать его не составит труда. На самом деле, в коде игры Connect 4 вы используете «силовой прием». Уверен, что есть более элегантные способы решения задачи, но таблица с выигрышными комбинациями – это очень простой и весьма эффективный метод с точки зрения производительности.
Как вы, несомненно, поняли, Connect 4 – это пошаговая игра. Это означает, что для ее реализации идеально подходит сетевое датаграммное соединение. Оказывается, игра Connect 4 может быть построена на тех же приемах, что и созданный в предыдущей главе мидлет Lighthouse. Но теперь нужно переправлять не символы азбуки Морзе (точек или тире), а номер столбца, в который производится ход. Единственное, что отличает игру Connect 4 от мидлета Lighthouse, – это необходимость отслеживания очередности ходов. Иначе говоря, вы не можете создать «свободное соединение», как это было в случае Lighthouse.
Подобно мидлету Lighthouse, игра Connect 4 работает в двух режимах: клиент и сервер. Режим работы определяется при первом запуске игры. Предполагается, что для игры клиент должен подсоединиться к серверу. После того как соединение клиент-сервер установлено, игроки поочередно выполняют ходы, отправляя сообщения. Проблема заключается в том, чтобы сохранить синхронизацию образов игры Connect 4. Решение этой проблемы – тщательное отслеживание очередности ходов и проверка получения игроком информации о ходе соперника.
Ниже приведены основные элементы работы сетевого соединения в игре Connect 4:
1. телефон-сервер открывает датаграммное соединение и ждет ответа клиента;
2. телефон-клиент открывает датаграммное соединение и подключается к серверу;
3. по установлению соединения игра начинается ходом клиента. Далее право первого хода будет принадлежать проигравшему;
4. клиент совершает ход и передает серверу информацию о выбранном столбце;
5. ход переходит к серверу;
6. игра длится до тех пор, пока один из игроков не одержит победу или не будет возможности для совершения новых ходов;
7. клиент и сервер завершают соединение.
Как вы видите, с точки зрения работы с сетью, игра Connect 4 – это более интересный вариант мидлета Lighthouse. Единственное значительное отличие – это управление ходами игроков и обмен информацией о выбранной колонке, а не символами азбуки Морзе. Как вы увидите дальше, код для работы с сетью игры Connect 4 во многом похож на код мидлета Lighthouse.
Разработка игрыПодобно тому, как процесс разработки игры Connect 4 был разбит на отдельные этапы, разработка программного кода так же может быть разделена. В следующих разделах вы увидите коды различных игровых компонентов.
Большая часть кода игры Connect 4 содержится в двух классах: C4 Client и C4Server. Неудивительно, что эти два класса представляют клиента и сервер, которые обмениваются игровыми сообщениями. Оба класса реализуют интерфейс Runnable. Это означает, что каждый из них выполняется в отдельном потоке. Поскольку сервер обычно запускается первым, давайте начнем разработку класса C4Server.
Ниже приведены переменные класса C4Server:
private C4Canvas canvas;
private DatagramConnection dc;
private String address;
private boolean connected;
Сервер должен иметь возможность обмениваться информацией о состоянии игры с игровым холстом, управляющим игрой. Поэтому важно, чтобы класс C4Server сохранял холст игры в переменной canvas. Переменная dc отслеживает датаграммное соединение, что очень важно для работы приложения. Переменная address сохраняет адрес клиента – он необходим для отправки датаграмм клиенту. И наконец, переменная connected отслеживает, установлено соединение или нет.
Конструктору класса C4Server требуется единственный параметр – объект класса C4Canvas:
public C4Server(C4Canvas c) {
canvas = c;
connected = false;
}
Конструктор C4Server() очень прост, и ничего не выполняет, кроме как инициализирует 2 переменные. Метод start(), который наследуется от интерфейса Runnable, также прост:
public void start() {
Thread t = new Thread(this);
t.start();
}
Здесь нет ничего непонятного – стандартный код запуска потока. Возможно, что в классе C4 Server есть лишь один более скучный метод – метод stop(), который вообще ничего не делает:
public void stop() {
}
Код класса C4Server в действительности не очень интересен, за исключением метода run(), код которого приведен в листинге 15.1.
Листинг 15.1. Метод run() класса C4 Server это сердце приложения Connect 4
public void run() {
try {
// соединиться с клиентом
canvas.setStatus("Waiting for peer client..."); //Сервер отображает начальное соединение, что говорит о том, что он пытается соединиться с клиентом
dc = null;
while (dc == null)
dc = (DatagramConnection)Connector.open("datagram://:5555"); //Номер порта сервера должен совпадать с номером порта клиента
while (true) {
// попытка получения датаграммного пакета
Datagram dg = dc.newDatagram(32); //Размер датаграммы (32 байта) должен быть достаточно большим, чтобы
dc.receive(dg); //вместить наибольшее возможное сообщение, однако в игре Lighthouse сообщения не очень велики
address = dg.getAddress();
// убедиться, что пакет содержит данные
if (dg.getLength() > 0) { //Ответить на сообщение клиента о соединении
String data = new String(dg.getData(), 0, dg.getLength());
if (data.equals("Client")) {
// сообщить пользователю об удачном соединении
canvas.setStatus("Connected to peer client.");
canvas.newGame();
connected = true;
// попытка ответить на принятое сообщение
sendMessage("Server");
}
else { //Сообщение содержит символы азбуки Морзе, поэтому его следует передать холсту
// отправить игровые данные по сети
canvas.receiveMessage(data);
}
}
}
}
catch (IOException ioe) {
System.err.println("The network port is already taken.");
}
catch (Exception e) {
}
}
Метод run() начинается с важной строки кода, которая устанавливает статус холста в состояние «Waiting for peer client…» (Ожидание соединения клиента). Метод setStatus() класса C4Canvas устанавливает сообщение, которое выводится в нижней части экрана. Когда вы устанавливаете статус, вы напрямую обмениваетесь информацией с пользователем. В этом случае передаваемая информация – это ожидание подключения клиента. После того как статус холста установлен, метод run() создает датаграммное соединение.
Оставшаяся часть метода run() – это бесконечный цикл, который постоянно пытается получить пакеты датаграммы и ответить на них. Если пакет получен, его адрес сохраняется и выполняется проверка длины. После этого проверяется равенство полученного сообщения значению Client – специальному сообщению, отправляемому клиентом при первом установлении соединения. Если соединение установлено, то статус изменяется и игра начинается. Также сервер отправляет сообщение клиенту, содержащее слово Server, оно означает, что соединение установлено успешно.
Если полученный пакет датаграммы не равен Client, то это, вероятно, фрагмент игровых данных. Игровые данные – это номер столбца, в который соперник поставил фишку. Однако сервер не должен заниматься обработкой этих данных, сервер должен передать эти данные холсту, для чего вызывается метод receiveMessage().
Последний метод класса C4Server осуществляет отправку сообщений клиенту (листинг 15.2).
Листинг 15.2. Метод sendMessage() класса C4Server отправляет строковое сообщение клиенту через датаграммное соединение
public void sendMessage(String message) {
// отправить сообщение
try {
// преобразовать строку в массив байтов
byte[] bytes = message.getBytes(); //Строковое сообщение должно быть преобразовано в массив байтов
// отправить сообщение
Datagram dg = null;
dg = dc.newDatagram(bytes, bytes.length, address); //Упаковка данных в датаграмму и отправка клиенту
dc.send(dg);
}
catch (Exception e) {
}
}
Метод sendMessage() упаковывает строку в массив байтов и отправляет клиенту как пакет датаграммы. В приведенном коде нет ничего удивительного, он очень похож на код отправки сообщения мидлета Lighthouse из главы 14.
Вторая половина сетевого уравнения Connect 4 – класс C4Client, который очень похож на класс C4Server. Ниже приведены переменные этого класса:
private C4Canvas canvas;
private DatagramConnection dc;
private boolean connected;
Эти переменные повторяют переменные класса C4 Server за исключением отсутствующей переменной address. Конструктор C4Client() также аналогичен конструктору C4Server():
public C4Client(C4Canvas c) {
canvas = c;
connected = false;
}
Этот код идентичен коду конструктора класса сервера за исключением названия. Классы клиента схожи не только этим фрагментом кода, а также кодом методов start() и stop():
public void start() {
Thread t = new Thread(this);
t.start();
}
public void stop() {
}
Итак, коды классов сервера и клиента во многом очень похожи, отличаются они лишь методом run(), код которого приведен в листинге 15.3.
Листинг 15.3. Метод run() класса C4Client – это сердце клиента игры Connect 4
public void run() {
try {
// соединиться с серверным устройством
canvas.setStatus("Connecting to peer server..."); //Клиент отображает начальное соединение, что говорит о том, что он пытается соединиться с сервером
dc = null;
while (dc == null)
dc = (DatagramConnection)Connector.open("datagram://localhost:5555"); //Номер порта клиента должен совпадать с номером порта сервера
while (true) {
// попробовать отправить датаграммный пакет
if (!connected) //Если соединение не установлено, отправить клиентское сообщение об установлении соединения серверу
sendMessage("Client");
// попробовать получить датаграммный пакет
Datagram dg = dc.newDatagram(32);
dc.receive(dg);
//проверить, что датаграмма содержит данные
if (dg.getLength() > 0) {
String data = new String(dg.getData(), 0, dg.getLength());
if (data.equals("Server")) { //Ответить на сообщение сервера о соединении
// сообщить пользователю об установлении соединения
canvas.setStatus("Connected to peer server.");
canvas.newGame();
connected = true;
}
else {
// отправить игровые данные по сети
canvas.receiveMessage(data); //Сообщение содержит символы азбуки Морзе, поэтому его следует передать холсту
}
}
}
}
catch (ConnectionNotFoundException cnfe) {
System.err.println("The network server is unavailable.");
}
catch (IOException ioe) {
}
}
Если подумать, то вы найдете этот код очень знакомым. Метод run() класса клиента структурирован точно так же, как и метод run() сервера, за исключением двух моментов. Во-первых, текст о статусе отличается от текста, выводимого на сервере, потому что клиент пытается установить соединение. Датаграммное соединение по-прежнему создается после определения статуса, но в данном случае URL другой, поскольку это клиентское устройство. Важно отметить, что номера портов на сервере и клиенте должны совпадать.
После того как клиент начал бесконечный цикл, сообщение Client немедленно отправляется серверу – сообщается об установлении соединения. После этого клиент переходит в режим «получения информации», так же, как и сервер. Клиент приступает к обработке входящих сообщений. Этими сообщениями могут быть либо Server (посылка сервера об удачном соединении), либо игровые данные о ходах соперника. Если получено специальное сообщение Server, то клиент изменяет статус холста и начинает новую игру. В противном случае клиент продолжает игру, обрабатывая определенным образом входящие сообщения.
В классе C4Server также метод sendMessage(), который очень похож на одноименный метод класса сервера. Код этого метода приведен в листинге 15.4.
Листинг 15.4. Метод sendMessage() класса C4Client отправляет строковое сообщение серверу датаграммным пакетом
public void sendMessage(String message) {
// отправить сообщение
try {
// преобразовать строку в массив байтов
byte[] bytes = message.getBytes();
// отправить сообщение
Datagram dg = null; //Упаковка данных в датаграмму и отправка серверу
dg = dc.newDatagram(bytes, bytes.length);
dc.send(dg);
}
catch (Exception e) {
}
}
При подробном рассмотрении кода видно, что клиентская версия sendMessage() не использует адреса для отправки датаграммы серверу. Это незначительное, но очень важное изменение.
Теперь, когда классы клиента и сервера созданы, самое время перейти к разработке класса игры Connect 4.
Правообладателям!
Данное произведение размещено по согласованию с ООО "ЛитРес" (20% исходного текста). Если размещение книги нарушает чьи-либо права, то сообщите об этом.Читателям!
Оплатили, но не знаете что делать дальше?