Создание игр для мобильных телефонов
Шрифт:
Вы уже видели все строки этого кода по отдельности, но здесь они объединены в один фрагмент. Это действительно все, что необходимо, чтобы сформировать пакет игровых данных и отправить через датаграммное соединение с сетью.
Получение пакетов датаграммы
Получение пакета датаграммы похоже на отправление пакета, оно выполняется методом интерфейса DatagramConnection. Этот метод называется receive, в качестве параметра он принимает объект Datagram, точно так же, как send. Ниже приведен пример использования метода receive для получения датаграммы:dc.receive(dg);
Конечно, при этом пакет датаграммы должен быть определенного размера. Ниже приведен код, формирующий и принимающий пакеты датаграммы:
// Попытка получения пакета
Datagram dg = dc.newDatagram(64);
dc.recieve(dg);
// Убедиться, что датаграмма содержит информацию
if (dg.getLength > 0) {
String data = new String(dg.getData, 0, dg.getLength);
}Важно отметить, что в этом коде полученная датаграмма проверяется методом getLength. Такая проверка важна, поскольку необходимо знать, есть ли данные в датаграмме. Если данные есть, то датаграмма конвертируется в строку и сохраняется в переменной data. Затем эти данные можно обработать специальным кодом.
Создание примера Lighthouse
За много лет до появления мобильных телефонов, радиопередатчиков и приемников мореплаватели использовали более примитивное средство коммуникации. Я говорю о маяках, которые обычно устанавливались на самых высоких частях берега, на их верхушке зажигался свет, направлявший корабли. Несмотря на то что сейчас маяки используют современные средства связи, свет остается источником визуальной коммуникации. Поскольку мобильные телефоны – это современная форма связи, я думаю, что пример с маяком может послужить хорошим примером для создания сетевого мидлета.
Одним из способов коммуникации маяков с экипажами корабля была азбука Морзе – очень удобный способ передачи слов и букв последовательностями «точек» и «тире». Точка – это короткий визуальный или звуковой сигнал, например, вспышка света или металлический звук. Тире по длительности приблизительно равно трем точкам, что соответствует более длительному звуку или вспышке света. Последовательность точек и тире задает отдельные слова. Ниже приведены коды азбуки Морзе.A – . – J – . – – – S – . . . 1 – . – – – -
B – – . . . K – – . – T – – 2 – . . – – -
C – . – . L – . – . – U – . . – 3 – . . . – -
D – – . . M – – – V – . . . – 4 – . . . .
–
E – . N – – . W – . – – 5 – . . . . .
F – . O – – . X – – . . – 6 – – . . . .
G – – – . P – . – – . Y – . – . – 7 – – . . .
H – . . . . Q – – – . – Z – – – . . 8 – – – – . .
I – . . R – . – . 0 – – – – – – 9 – – – – – .Используя эти коды, вы можете составлять слова и предложения. После каждой буквы следует небольшая пауза, а в конце предложения – более продолжительная. Ниже приведен код слова «hello» в азбуке Морзе:
. . . . . . – . . . – . . – – -
В копилку Игрока
Популярное слово азбуки Морзе – это SOS, что, как большинство ошибочно полагает, означает «Спасите Наши Души» (от англ. Save Our Souls). На самом деле это вовсе не аббревиатура, а простое сочетание букв, но оно служит важным сигналом. Это слово кодируется не по правилам азбуки Морзе – без пауз: . . . – – – . . .
Но вернемся к примеру мидлета Lighthouse. Идея этого приложения состоит в том, чтобы имитировать маяк на мобильном телефоне и использовать азбуку Морзе для коммуникации с другим телефоном с помощью вспышек маяка. Это работает так: на экране каждого телефона изображен маяк, вы смотрите на маяк на телефоне другого человека, а он смотрит на маяк на вашем телефоне. Используя клавиши направлений влево и вправо вы посылаете тире и точки через беспроводную сеть, в результате маяк на телефоне другого человека будет мигать, передавая точки и тире.
Совет Разработчику
Еще более простая версия мидлета Lighthouse могла бы использовать лишь одну клавишу для отправки точек и тире, при этом пользователь должен был бы задерживать клавишу нажатой на определенное время. Это больше походило бы на настоящий телеграф, но пример бы стал менее интересным.
Мидлет Lighthouse – это высокотехничная симуляция устаревшей формы коммуникации. С точки зрения программирования этот пример очень важен, поскольку он демонстрирует, как установить соединение «клиент – сервер» между устройствами, а затем выполнять обмен сообщениями.
Разработка клиента и сервера
Мидлет Lighthouse использует все преимущества отношения «клиент – сервер» между двумя мобильными телефонами. Соединение между мидлетами – датаграммное, это означает, что обмен информацией будет производиться датаграммными пакетами. Поскольку при разработке мидлета Lighthouse используется концепция «клиент – сервер», необходимо знать, какой из телефонов инициирует соединение. Ниже перечислено, что происходит между телефоном-клиентом и телефоном-сервером в мидлете Lighthouse:
1. сервер начинает датаграммное соединение и ждет ответа клиента;
2. телефон-клиент открывает датаграммное соединение с телефоном-сервером;
3. когда соединение установлено, клиент и сервер обмениваются сообщениями;
4. клиент и сервер завершают соединение.
Интерес в разрабатываемом мидлете представляет то, что один из телефонов должен функционировать и как клиент, и как сервер в зависимости от контекста. Чтобы реализовать эту двойную функциональность, пользователь при запуске мидлета может определить, какую роль будет играть его телефон – клиента или сервера. После чего один телефон будет работать либо в режиме клиента, либо в режиме сервера. Зная, что для мидлета Lighthouse есть два режима функционирования, целесообразно разделить сетевой код мидлета на код клиента и код сервера.
В копилку Игрока
С точки зрения программирования сетевых игр пример Lighthouse является не настоящим примером приложения «клиент – сервер», а коммуникатором между двумя устройствами. В настоящих сетевых играх, основанных на концепции «клиент – сервер», есть отдельное серверное приложение, запущенное на сетевом сервере. Мидлеты, подключающиеся к серверу, – клиенты, а сервер управляет игрой. Мидлет Lighthouse является приложением «клиент – сервер» только лишь с той точки зрения, что одно устройство (сервер) ожидает подключения другого устройства (клиента).
Написание программного кода
Мидлет Lighthouse может работать в двух режимах – режиме клиента и режиме сервера. Режим определяется пользователем через интерфейс при запуске мидлета (вы это увидите чуть позже). Перед тем как вы перейдете к этому, важно разобрать код работы с сетью, который выполняет отправление и прием пакетов через беспроводное соединение.
Клиент и сервер мидлета Lighthouse
Код «клиент – сервер» в мидлете Lighthouse намного легче понять, если начать рассмотрение кода сервера. Все функции сервера содержатся в классе LHServer, который отвечает за ожидание датаграммного подключения клиента. Класс LHServer реализует интерфейс Runnable, что означает, что он запускается в отдельном потоке:
public class LHServer implements Runnable {
Это важно, поскольку класс запускает отдельный поток, отслеживающий соединение, и получает сообщения от клиента. Кроме сетевого соединения с клиентом, сервер также должен обмениваться информацией с холстом мидлета, который отображает маяк. Переменные класса LHServer говорят о некоторых его функциях:
private LHCanvas canvas;
private DatagramConnection dc;
private String address;
private Boolean connected;Холст хранится внутри класса LHServer в переменной canvas. Датаграммное соединение хранится в переменной dc – объекте класса DatagramConnection. Переменная address хранит адрес клиента, чтобы пакеты датаграммы могли быть направлены непосредственно получателю. И наконец, переменная connected отслеживает текущее состояние соединения с клиентом. Конструктор класса LHServer принимает единственный параметр – объект класса LHCanvas, конструктор выполняет ряд инициализаций:
public LHServer(LHCanvas c) {
canvas = c;
connected = false;
}Метод start также очень прост, он запускает поток:
public void start {
Thread t = new Thread(this);
t.start;
}Метод run – это метод, в котором реализуются основные функции сервера (листинг 14.1). Листинг 14.1. Метод run класса LHServer отвечает на сообщения, принятые от клиента
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 байта) должен быть достаточно большим, чтобы вместить наибольшее возможное сообщение, однако в игре Lighthouse сообщения не очень велики
dc.receive(dg);
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.");
connected = true;
// попробовать ответить на принятое сообщение
sendMessage("Server");
}
else {
// отправить данные
canvas.receiveMessage(data); //Сообщение должно содержать знаки азбуки Морзе, поэтому необходимо его передать холсту
}
}
}
}
catch (IOException ioe) {
System.err.println("The network port is already taken.");
}
catch (Exception e) {
}
}