Текст книги "Создание игр для мобильных телефонов"
Автор книги: Майкл Моррисон
Жанр: Зарубежная компьютерная литература, Зарубежная литература
сообщить о неприемлемом содержимом
Текущая страница: 23 (всего у книги 35 страниц)
Немного изменив графику, вы можете превратить High Seas 2 в совершенно другую игру. Например, вы могли бы изменить фоновое изображение на пустыню, где пески заменят воду, а горы – острова. Каждый спрайт игры должен так же измениться в соответствии с новой пустынной темой. Например, вы можете изменить корабль игрока на повозку, путешествующую по пустыням, похожую на те, что перемещались по Америке во времена освоения Запада. Затем, если вы будете придерживаться этой темы, вы должны будете заменить спрайт пирата спрайтом потерявшихся путешественников, которым нужна помощь. Осьминоги могу стать преступниками, а вражеский корабль – целой бандой преступников, мины могут превратиться во взрывчатку, заложенную бандитами, а бочки могут стать запасами продовольствия, оставленными другими путешественниками. И наконец, вы можете добавить нового плохого парня, например, гром-птицу – огромную птицу, державшую в ужасе весь запад Америки.
Ниже приведены действия, которые необходимо выполнить, чтобы превратить игру High Seas 2 в вестерн:
1. замените всю графику игры темой пустыни;
2. если хотите, переделайте карту, чтобы привнести в игру новый дух;
3. измените спрайт взрывчатки (мины) и спрайт ящика с провизией (бочка), чтобы для их создания использовался класс Sprite, а не DriftSprite (эти объекты не могут перемещаться);
4. добавьте новый спрайт гром-птицы, который будет являться объектом класса ChaseSprite. Убедитесь, что при инициализации вместо слоя-барьера передается значение null – это необходимо потому, что птица может беспрепятственно перемещаться по карте.
Странно, но это все, что необходимо сделать, чтобы полностью изменить игру High Seas 2. Очевидно, что придется переработать всю графику, но удивительно, насколько мало кодов необходимо для превращения High Seas 2 в совершенно новую игру.
Часть IV
Использование преимуществ работы в сети
Глава 14
Основы сетевых мобильных игр
Архив Аркад
Другой яркий представитель игр 1982 года – Pole Position – это одна из первых гоночных игр, которая стала очень популярной. Несмотря на то что игра была разработана Namco, за релиз в Америке игру лицензировала компания Atari. Pole Position была создана в двух версиях: как для игры стоя, так и сидя. В последнем случае были предусмотрены педаль газа и тормоза, в другой версии игры была только педаль газа. При переговорах с Namco компания Bally/Midway выбрала игру Mappy, а Atari взяла, что осталось. В результате небольших доработок в 1983 году игра Pole Position стала хитом и теперь считается классикой аркад.
В главе 13 вы узнали о том, как компьютер может противостоять человеку в игре. Несмотря на то что искусственный интеллект очень важен в играх и применяется широко, сложно недооценить и человеческий фактор в сетевых играх. В этой главе будут рассмотрены сетевые игры, их важность в сегодняшнем игровом мире. Поскольку мобильные телефоны разработаны для коммуникации между людьми, в вашем распоряжении есть среда для сетевых игр. Существует ряд свойственных для сетевых игр проблем, с которыми вам придется столкнуться на этапе проектирования и разработки. В этой главе рассматривается большинство этих проблем, а также методов их решения. Прочитав эту главу, вы будете готовы к созданию собственной сетевой игры с помощью J2ME.
В этой главе вы узнаете:
► об основах создания сетевых мобильных игр;
► о фундаментальных типах сетевых мобильных игр;
► о проблемах, свойственных сетевым играм, и методах их решения;
► как использовать MIDP API для создания беспроводных соединений;
► как создать программу, с помощью которой можно общаться, используя азбуку Морзе.
Основы сетевых игрЕсли вам когда-либо доводилось играть в сетевую игру со своими друзьями, то вы знаете, как это весело! В самом деле, игра с живым человеком намного интереснее игры против компьютера. Идея, что в игре предстоит соревноваться с человеком, может в корне изменить взгляд на игру. В сетевых играх есть множество способов заставить игроков соревноваться друг с другом или играть в команде. Вне зависимости от сценария, если в игре принимают участие живые люди, то игра становится намного интереснее, поскольку реакция соперников может быть оригинальной и нестандартной, что невозможно с компьютерными оппонентами. Теперь разработчикам, таким как вы и я, остается решить, как именно люди будут взаимодействовать в игре. А теперь взгляните на уникальность сетевой игры через мобильный телефон. Это именно то, чего мы ожидаем, когда слышим разговоры о «беспроводной революции», ведущиеся на протяжении последних нескольких лет.
Перед тем как перейти к разработке стратегии сетевой игры, важно познакомиться с фундаментальными типами таких игр. Разработка соединения сильно зависит от того, как происходит игра, что определяется типом игры. Мобильные сетевые игры можно разделить на две большие категории: пошаговые игры и игры, основанные на событиях. Большинство игр можно с легкостью отнести в одну из этих категорий.
Пошаговые игры – это игры, в которых действия – это шаги игрока. Классические шашки, шахматы, нарды – это хороший пример пошаговых игр, поскольку в них вы можете предпринимать действия, когда остальные игроки сделают ходы. Конечно, вы можете обдумывать свой ход в то время, пока другой игрок совершает свой, однако игра такова, что сделать вы его сможете в свою очередь.
Большинство пошаговых игр – это или настольные игры, или карты, или простые игры, в которые можно играть на бумаге, например, крестики-нолики. Несмотря на то что действия разворачиваются достаточно медленно, эти игры очень популярны и хорошо подходят для сетевой игры.
Если принять во внимание, что в пошаговых играх игроки ходят по очереди, то сетевое соединение значительно упрощается. В каждый момент времени играет лишь один игрок. Даже несмотря на то что в игре принимают участие несколько игроков, ход может сделать лишь один игрок. Другие игроки должны ждать своей очереди. В этом случае игру можно сделать так, чтобы все игроки находились в режиме ожидания до тех пор, пока не придет их очередь совершать ходы. В игре, в которой принимают участие лишь 2 игрока, например, как рассмотренной в главе 4, право хода переходит от одного игрока к другому.
Игры, основанные на событиях, – это такие игры, которые управляются входящими событиями, которые могут произойти в любой момент. Такие игры менее ограничены временем по сравнению с пошаговыми играми. В этих играх любой игрок может взаимодействовать с игрой в любой момент времени – это события игры. Развитие игры определяется событиями, а не шагами. На самом деле в играх, основанных на событиях, нет понятия «шаг». Под определение «игры, основанные на событиях», попадают все игры, в которых отсутствует понятие «шаг», и таких примеров очень много – от классических «стрелялок» до стратегических симуляторов, например, «Век империй» (Age of Empires). В сетевых версиях этих игр любой игрок может действовать независимо от других игроков, создавая или не создавая новые события.
Разработка сетевого соединения для игр, основанных на событиях, значительно сложнее, чем для пошаговых игр. Важно то, что игры, основанные на событиях, требуют значительно большей пропускной способности соединения, поскольку необходимо обновлять информацию. Можно сказать, что каждая созданная вами игра, основанная на событиях, будет уникальна, поскольку при разработке соединения вам придется реализовывать нестандартные подходы. Вспомните игры Doom 3 и Halo 2 и подумайте, сколько действий в них происходит, и, что еще более важно, насколько быстро они происходят. Любое изменение в игре, вносимое каждым из игроков, должно быть отражено для других игроков в том же виде.
В копилку Игрока
Поскольку пропускная способность соединения в играх, основанных на событиях, чрезвычайно важна, то вопрос разработки таких игр для мобильных телефонов очень сложен. С ростом скоростей мобильных сетей, разработка таких игр будет упрощаться, однако считается, что создание эффективного сетевого кода – это один из самых трудных аспектов разработки игр, и еще более трудный с точки зрения создания мобильных сетевых игр.
Игра, основанная на событиях, никогда не «разрешает» игроку делать все что угодно, как это происходит в пошаговых играх. Игра ждет, пока игрок сгенерирует какое-нибудь событие. Игроки могут создавать события так часто, как это требуется, независимо от других игроков. Так вы можете ждать за углом, пока другой игрок пробегает мимо с большой скоростью.
Сетевые игры. Проблемы и решенияТеперь вы знаете, с каким типом игр имеете дело, поэтому рассмотрим проблемы, с которыми вы можете столкнуться при разработке сетевых игр. Одна из главных проблем при разработке сетевых игр – это обеспечение синхронизации. Под синхронизацией понимается, сколько образов игры может быть запущено на различных телефонах одновременно. Помните, что каждый игрок запускает образ на своем телефоне, при этом вашей целью является обеспечение синхронности обмена данными, чтобы все игроки чувствовали себя частью игры. Все структуры информации, отвечающие за состояние игры, должны быть одинаковы для каждого из образов.
Чтобы лучше понять, о чем идет речь, рассмотрим, что может случиться, если синхронизация будет утеряна. Предположим, что два человека играют в сетевую игру, аналогичную популярной игре Diablo. Например, они бегут вместе. Пробегая мимо демона, более агрессивный игрок 1 начинает с ним сражаться. У игрока 2 мало энергии, и он решает отойти в сторону и понаблюдать. Когда игрок 1 заканчивает борьбу с демоном, игрок 2 должен быть уведомлен об этом. И не только с точки зрения удобства: все изменения в игре должны быть отражены и для прочих игроков.
Другая проблема, связанная с синхронизацией, – это использование случайных чисел. В начале игры многие объекты, например, сокровища и монстры, размещаются случайным образом. Иногда в играх используются случайные события, изменяющие игру от одного запуска к другому. В сетевых играх это создает большую проблему, если на каждом телефоне не используются те же случайные числа. Все пойдет насмарку, если каждый из образов игры будет генерировать объекты случайно относительно других образов. Дело в том, что, казалось бы, такие незначительные моменты, как генерирование случайных чисел, может создать массу проблем в сетевом окружении.
Теперь, когда вы понимаете, какие проблемы могут возникать, давайте перейдем к тому, как их можно решить. Существует множество подходов к разработке сетевых соединений, каждый из которых должен каким-то образом решать проблему синхронизации. Мы рассмотрим два основных типа синхронизации сетевых игр: синхронизация состояния и синхронизация ввода.
Синхронизация состояния – это метод соединения, посредством которого каждый образ сетевой игры обновляет состояние в соответствии с состояниями других образов. Этот метод синхронизации очень надежен, поскольку не происходит потеря информации: все, что касается состояния игры, отправляется другим образам. Например, в космическом симуляторе для двух игроков текущим состоянием игры будет скорости и координаты всех планет, астероидов, кораблей и пуль – эта информация и будет переправляться другому образу игры.
В копилку Игрока
Поскольку у мобильных телефонов пропускная способность сети ограничена, синхронизация состояния представляет большую сложность при реализации.
Звучит неплохо. Ну а что же будет в случае более сложной игры, например, ролевой приключенческой игры с целыми виртуальными мирами, в которых постоянно путешествуют игроки? Обмен информацией о состоянии всей игры кажется очень проблематичным, ввиду значительных объемов. И не забудьте об ограничениях скорости соединения, о которых вы узнали ранее. Вы не можете пересылать большие объемы информации между мобильными телефонами. Зная это, легко понять, что синхронизация состояний – это не лучшее сетевое решение. Хотя с точки зрения функциональности такой тип синхронизации очень хорош, с технической точки зрения он не всегда применим.
Синхронизация ввода – это метод соединения, при котором каждый из образов игры передает сообщения о входящих событиях другим образам игры. Используя синхронизацию ввода, каждый из игроков генерирует входные события, например, нажатия клавиш, а игра передает эти события другим играм. Если применить это к космическому симулятору, обсужденному ранее, то игра отправляет события нажатых игроком клавиш. Затем каждая запущенная игра обрабатывает эти события и вносит соответствующие изменения.
Но здесь должен быть подвох, да? Конечно, он есть! Синхронизация ввода работает хорошо до тех пор, пока изменения вносятся только игроками. Иначе говоря, в простых играх какие-либо проблемы вряд ли возникнут. В играх часто бывают случайные события, как, например, размещение фоновых объектов. Эти случайные события представляют проблему для синхронизации, поскольку они не зависят от игрока, а следовательно, их синхронизация представляет большую трудность.
Если вы разрабатываете игру, в которой все события определяются игроком, используйте синхронизацию ввода. В противном случае вы должны выбрать другой способ синхронизации. Вы можете придумать игру, в которой события генерируются только игроком? Бросьте это занятие! В итоге вы придете к пошаговым стратегиям, в которых все определяется лишь действиями игроков. Поэтому обычно синхронизация ввода применяется для пошаговых сетевых игр.
В копилку Игрока
Игра Connect 4, которую вы разработаете в следующей главе, – это хороший пример сетевой пошаговой игры, которая полностью зависит от действий игроков.
Теперь, когда я вкратце обрисовал проблемы разработки сетевых игр, можно перейти в реальность создания мобильных игр: в большинстве случаев вам придется использовать комбинацию типов синхронизации, описанных выше. Смешанное решение будет содержать как элементы синхронизации ввода, так и элементы синхронизации состояния. Используя пример с космическим симулятором, вы можете пересылать события нажатиями на клавиши, после чего использовать синхронизацию состояния, например, для пересылки данных, скажем, о начальных координатах случайных астероидов. По-прежнему нет необходимости пересылать данные о полном состоянии игры, пересылаются только случайные данные.
Если вы столкнетесь с игровым сценарием, который нельзя реализовать посредством одной из указанных методик, вы можете разработать собственную. Сетевые игры – это уникальная область программирования, в которой есть место новым подходам. Обычно приходится использовать комбинации различных подходов на основании полученных знаний и собственных идей.
Соединение через сеть с сокетамиНесмотря на то что существует множество различных сетей, при программировании сетевых игр в MIDP используется особый тип сетевого соединения, известный как сокет (socket). Сокет – это программный элемент для входящего или исходящего соединения. Иначе говоря, сокет – это коммуникационный канал, который позволяет вам передавать данные через определенный порт. В MIDP API есть класс сокета, который значительно упрощает программирование соединений. Сокеты MIDP разделены по типам: потоковые и датаграммные.
Потоковый сокет (соединенный сокет) – это сокет, через который данные могут передаваться непрерывно. Говоря «непрерывно», я не имею в виду, что данные передаются в каждый момент времени. Потоковый сокет – это определенное соединение, доступное в любой момент времени. Преимущество такого сокета – это то, что информацию можно отправить, не заботясь о том, когда она дойдет до получателя. Поскольку такое соединение постоянно «активно», то дата передается немедленно в момент отправления.
Другой тип сокетов, поддерживаемый Java, – это датаграммные сокеты. В отличие от потоковых сокетов, в которых соединение больше похоже на постоянное сетевое подключение, датаграммные сокеты больше похожи на коммутированное подключение, при котором соединение активно не всегда. Датаграммный сокет – это сокет, через который данные разделяются на пакеты и отправляются, при этом «активное» подключение к другому устройству не обязательно.
Вследствие различий средств соединения датаграммные сокеты не гарантируют отправление информации в определенный момент и даже в определенном порядке. Причина, по которой этот тип сокетов работает именно так, заключается в том, что им не требуется непосредственное соединение с другим компьютером – адрес устройства связывается с передаваемой информацией. Такой пакет передается в сеть, оставляя отправителю надежду, что он когда-либо дойдет до получателя. Получатель может принять отправленные данные в любой момент времени и в любом порядке. Поэтому датаграммы также содержат число, определяющее, в каком порядке должны быть расположены данные, чтобы их можно было собрать воедино. Принимающее устройство ожидает прихода всей последовательности, а затем объединяет принятые пакеты.
Вы можете подумать, что датаграммные сокеты – не идеальное средство для программирования сетевых игр, и в некоторых случаях это так. Однако не всем играм требуется «активное» соединение, обеспечиваемое потоковыми сокетами. В случае специфических мобильных игр чаще всего целесообразно использовать именно датаграммные сокеты в виду ограниченности пропускной способности сети.
Сетевое программирование и J2MEВ копилку Игрока
В этой книге рассматриваются только датаграммные сокеты для установления соединения. Программированию мобильных сетевых игр можно посвятить отдельную книгу, поэтому я ограничился описанием самых простых форм мобильных сетевых игр, использующих датаграммные сокеты.
Сетевое программирование в мидлетах выполняется с помощью MIDP API, которое носит название Generic Connection Framework или GCF. Цель GCF – обеспечить необходимый уровень абстракции для сетевых сервисов, которые помогают различным устройствам поддерживать специальные протоколы.
Хотя GCF структурирован иначе, он является подмножеством J2SE API. GCF описывает один фундаментальный класс, который называется Connector. Он используется для установления всех сетевых соединений мидлетом. Особые типы соединений моделируются интерфейсами, доступ к которым можно получить через класс Connector. Класс Connector и интерфейсы соединений находятся в пакете javax.microedition.io. Ниже приведено описание некоторых их интерфейсов:
► ContentConnection – потоковое соединение, которое обеспечивает доступ к данным из Web;
► DatagramConnetction – датаграммное соединение, используемое для реализации пакетно ориентированных соединений;
► StreamConnection – двунаправленное соединение с другими устройствами.
С точки зрения программирования мобильных игр, чаще всего вы будете использовать интерфейсы для реализации соединений в игре. Вне зависимости от типа соединения вы будете использовать класс Connector для установления нужных подключений. Все методы класса Connector являются статическими, в том числе и самый важный метод – open(). Наиболее часто используемый вариант этого метода выглядит так:
static Connection open(String name) throws IOException
Параметр, передаваемый в этот метод, – это строка соединения, которая определяет тип создаваемого подключения. Строка соединения описывается так:
Схема:Цель[;Параметры]
Параметр «Схема» – это название сетевого протокола, например, http или datagram. Параметр «Цель» – обычно адрес в сети, но может изменяться в соответствии с особыми типами протоколов. Последний параметр – это список параметров подключения. Ниже приведены строки соединений для различных типов подключений:
► HTTP – "http://www.stalefishlabs.com/"
► Socket – «socket://www.stalefishlabs:1800»
► Datagram – «datagram://:9000»
► File – «file:/stats.txt»
Помните, несмотря на то что приведенные примеры – это возможные строки соединения, только одна из них поддерживается реализацией MIDP – первая строка. Согласно спецификации MIDP поддерживается лишь HTTP-соединение. Если вы уверены, что другая реализация MIDP поддерживает какое-либо еще соединение, то вы можете использовать его. В противном случае вы должны создавать только HTTP-соединения, что, надо сказать, не очень хорошо для создания мобильных сетевых игр.
Метод open() возвращает объект типа Connection, который является базовым интерфейсом для всех интерфейсов соединений. Чтобы использовать определенный тип интерфейса соединения, необходимо преобразовать тип Connection к нужному. Следующий код иллюстрирует использование интерфейса DatagramConnection для создания датаграммного соединения:
DatagramConnection dc = (DatagramConnection)Connector.open(«datagram://:5555»);
Совет Разработчику
Число 5555 в примере, – это сетевой порт, используемый датаграммным подключением. Номер порта может быть любым, но больше 1024. Очень важно, чтобы клиент и сервер мидлета соединялись через один и тот же порт.
В следующих разделах мы более глубоко рассмотрим датаграммные соединения, как получать и отправлять данные.
Правообладателям!
Это произведение, предположительно, находится в статусе 'public domain'. Если это не так и размещение материала нарушает чьи-либо права, то сообщите нам об этом.