Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Байта Обозначение Смысл






0 J Установленное состояние джойстика

1 data_x Байт Х-координаты джойстика

2 data_y Байт Y-координаты джойстика

3 buttons Байт состояния кнопок

4 (period) Конец передачи

Составить такой пакет чрезвычайно просто. Не сложно и заставить программу передавать его на другую машину с частотой, необходимой для сохранения синхронизации. В то же самое время, другая машина могла бы предоставить в распоряжение первой собственный пакет состояния джойстика.

Здесь есть один не вполне очевидный нюанс. Дело в том, что оба компьютера в равной мере думают друг о друге как об удаленном игроке. (Есть в этом что-то от фантастических романов, описывающих путешествия в параллельные миры и во времени, - частенько путаешься и начинает болеть голова.)

Это все, что я хотел сказать по поводу синхронизации состояния ввода/вывода. Мы еще продолжим разговор о сохранении режима синхронизации, но сейчас нам нужно обсудить такую малоизученную область, как временная синхронизация.

Временная синхронизация

Временная синхронизация означает привязку обеих машин к некоему общему таймеру, который может быть как внутренним, так и внешним. Как я уже говорил, необходимо, чтобы обе игры протекали в одном и том же темпе и каждое событие происходило на обоих компьютерах одновременно. Существует много путей для этого, но здесь приводятся только два из них:

§ Один путь состоит в обмене данными между компьютерами с определенный интервалом времени, который выбирается одинаковым для обеих машин. К примеру, машины производят обмен каждые 1/30 секунды. В результате система будет терять синхронизацию не более чем на 1/30 секунды.

§ Другой технический прием основан на ожидании посылающим компьютером подтверждения того, что сообщение принимающим ПК получено. Это показано на рисунке 14.9.

Первый компьютер передает свое состояние другому..Как только вторая машина подтвердит получение этого сообщения и передаст свое состояние, ПК1 может продолжать работу. И запомните, что с точки зрения второго ПК все должно происходить наоборот. То есть после соединения компьютеров один из них получит сообщение первым и тут же вернет его назад - сообщение начнет ходить взад и вперед.

 

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

Прекрасно, теперь вы просто эксперты по коммуникациям. Это было не так уж и сложно, не правда ли? Даже если вы и не стали специалистом, то, по крайней мере, должны неплохо разбираться в этом вопросе и у вас появилось несколько технических приемов для решения возможных проблем. Перед тем как мы приступим к игре Net-Tank, я хочу сказать пару слов о модеме.

Модем

Соединение через модем не так сложно, но описание работы с модемом добавило бы еще немало страниц, на которые у нас просто нет времени. Модем управляется по тем же принципам, что и последовательный порт, с которым он соединен. Единственное отличие состоит в том, что модем прослушивает последовательный порт, и если слышит специальную последовательность символов, то думает, что вы разговариваете с ним, и будет интерпретировать команды и выполнять их. Эти команды называются набором АТ-команд. Они поддерживают все функциоальные возможности, которые вам нужны для дозвона, ответа и осуществления телефонного соединения.

Как только соединение произошло, это стало прозрачно для вас. Вы можете забыть, что соединились через модем. Ну ладно, теперь пора разъединиться и перейти к игре.


Net Tank: танковый имитатор для двух игроков

Net-Tank — игра для одного или двух игроков. Я написал ее, чтобы показать как создаются игры для нескольких участников и осветить некоторые проблемы которые могут при этом возникнуть. Это самая примитивная игра (для её написания мне понадобилось всего три дня), имеющая один-единственный уровень. Более того, это двухмерная игра, в которой игрок смотрит на поле боя сверху вниз. Мы напишем полноценную трехмерную игру типа Wolfenstetn в девятнадцатой главе, а сейчас я хочу оставить программу достаточно простой чтобы акцентировать внимание не на алгоритмах игровой логики, а на коммуникационной части.

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

SNDLIB.C библиотека звуковых эффектов;

GRAPH1.С низкоуровневый двухмерный спрайт и графическая библиотека;

KEYLIB.C библиотека ввода с клавиатуры;

SERLIB.C коммуникационная библиотека.

Все файлы заголовков для этих библиотек имеют те же самые имена:

SNDLIB.H GRAPH1.H KEYLIB.H SERLIB.H

Все эти модули объединяются в одну обширную библиотеку с помощью менеджера LIB.EXE. Для создания этой библиотеки вам надо:

1. Скомпилировать каждый Си-модуль с помощью файла СО.ВАТ:

cl -AM -Zi -с -Fc -Gs -G2 %1.с

2. После компиляции создается одна большая библиотека с именем MYLIB.LIB. Чтобы сделать это, вызовите библиотечный менеджер путем ввода команды

lib mylib.lib

3. Программа скажет, что библиотека с таким именем отсутствует, и спросит вашего согласия на ее создание. Ответьте утвердительно;

4. Дрбавьте в командную строку все модули, входящие в библиотеку, как это укаэано:

operations: +SNDLIB +GRAPH1 +KEYLIB +SERLIB

5. Затем появятся еще два запроса. Ответьте на них нажатием клавиши Enter.

После этого у вас появится библиотека MYLIB.LIB, которую вы можете присоединять так же, как и любую другую библиотеку.

Для создания игры, вам необходимо создать два исполняемых модуля:

§ Один для игрока 1;

§ Другой для игрока 2.

Чтобы это сделать, вам надо:

1. Откомпилировать NET1.C и NET2.C (2 версии игры) следующим с помощью командного файла СС.ВАТ:

cl -AM -Zi -с -Fc -Gs -G2 %1.С

if errorlevel 1 goto с fail

link /ST: 16384 /CO %1/,,, graphics.lib+myiib.iib,,

: c_fail

Этот командный файл компилирует игру и объединяет ее с библиотекой, чтобы создать исполняемый модуль. Сделайте это, чтобы создать два файла:

NET1.EXE и NET2.EXE;

2. Поместите NET1.EXE, на ПК1 и NET2.EXE на ПК2. Соедините обе машины нуль-модемным кабелем через СОМ1;

3. Теперь можно начинать игру. Наберите NET1.EXE на ПК1 и NET2.EXE на ПК2. Машины соединятся и вы можете сразиться со своим приятелем на танковой дуэли.

Используйте следующие управляющие клавиши:

Стрелка вправо Повернуть направо

Стрелка влево Повернуть налев

Стрелка вверх Двигаться вперед

Стрелка вниз Двигаться назад

Esc Выход из игры

Пробел Стрельба

Т Подразнить партнера

Поиграйте в Net-Tank и попутно обратите внимание на следующие вещи:

§ Возникает ли эффект запаздывания при перемещениях?

§ Теряет ли игра синхронизацию?

§ Если да, то в какие моменты?

Также обратите внимание на звуковые эффекты. Для их создания я использовал собственный голос и условно-бесплатную программу Blaster Master Наконец, игру можно проводить при установленной программе-ускорителе клавиатуры. Если при нажатии клавиши танк слишком резво устремляется вперед, попробуйте уменьшить скорость реагирования клавиатуры, установив программу TURBOKEY.COM, которая имеется на дискете.

Анализ игры Net-Tank

Если вы обзовете Net-Tank пережитком каменного века, я полностью соглашусь с вами. Однако она содержит несколько интересных: технических; приемов, которые вы можете использовать (и которые в дальнейшем будут применены в Warlock'e). Вся игровая логика содержится в функции main() Си-программы, Я сделал это для того, чтобы легче было обозреть игру в целом. Исключение составляют только вызываемые функции, которые являются низкоуровневыми, но обычно их имена говорят о том, для чего они предназначены или что они делают (например, сложно не понять, что означает Draw_Sprite). Основная часть включает в себя пару сотен строк, и если вы поймете их смысл, вы в хорошей фopмe. Давайте разберем игру, рассматривая раздел за разделом.

Раздел 1: Инициализация

В этой части программы мы загружаем все файлы со звуковыми эффектами И графикой для игры. Элементы изображения для танков берутся из загруженный файлов и размещаются в предварительно выделенной под буфер области памяти. Net-Tank использует технику дублирующей буферизации для исключения мерцания изображения. Напомню, это означает, что изображение вначале формируется в оперативной памяти и в уже полностью подготовленном виде копируется в видеопамять. Кроме того, во время инициализации структуры данных, описывающие все игровые объекты, обнуляются или устанавливаются в исходное положение.

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

Раздел 2: Игровой цикл

Следующая часть начинается с главного цикла. Обратите внимание, что в игре имеется два цикла: внешний и внутренний. Внешний игровой цикл используется для инициализации некоторых переменных. Затем начинается внутренний цикл. Именно в нем и происходит основное действие.

Заметьте, что игра различает, когда она находится в состоянии соединения, а когда - нет.

Раздел 3: Удаление объектов

Как вы узнали из предыдущих глав, посвященных графике, прежде чем рисовать спрайты на новом месте, мы должны удалить их из прежней позиции. Эта часть программы убирает с игрового поля все движущиеся объекты путем восстановления ранее сохраненного фона под ними.

Раздел 4: Получение входных данных и передача состояния дистанционно управляемой системе

Здесь начинается самое приятное. Эта часть программы подразделена на два фрагмента:

§ Первый из них принимает входные данные от локального игрока;

§ Другой принимает входные данные от удаленного игрока.

Любопытно то, что оба фрагмента делают практически одно и то же. Разница только в том, что второй фрагмент обращает больше внимания на то, что поступает из последовательного порта, а первый в основном интересуется клавиатурой. Давайте остановимся и чуть-чуть поговорим о том, как происходит соединение. Как я говорил несколькими страницами раньше, для осуществления соединения применяются два основных метода:

§ Можно передавать состояние игры в целом;

§ Вы можете посылать статус устройств ввода и трактовать это как прием данных от другого джойстика или клавиатуры.

В Net-Tank я применил второй метод. Один раз в течение цикла второй машине передаются все манипуляции игрока с клавиатурой. В это же время другой компьютер интерпретирует полученные по сети данные как действия со своей собственной клавиатурой.

Помните, чтобы этот технический прием работал, обе игры должны быть полностью детерминированы. Никаких случайностей быть не должно. В Net-Tank я полностью следовал этому правилу всюду, кроме фрагмента, изображающего взрыв. Обычно этого не сложно избежать, но иногда, после уничтожения одного из танков, игры теряют синхронизацию.

Раздел 5: Перемещение объектов

Следующая часть программы занимается перемещением объектов. Мы просто используем информацию, поступающую от локального и дистанционного ввода для передвижения и разворота танков. Интересен способ перемещения танков. Они могут двигаться в 16 различных направлениях, угол между которыми составляет 22.5 градуса. Вообще-то, чтобы переместить танк в выбранном направлении нам потребовалось бы, прежде всего, найти угол, а затем вычислить его синус и косинус для нахождения параметров передвижения.

Однако в нашей игре синусы и косинусы вычислены заранее. Это позволяет присвоить каждому из направлений свой номер (который будет совпадать с номером текущего кадра, изображающего танк) и использовать его как индекс в таблице, содержащей значения соответствующих передвижений по осям координат.

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

Во всяком случае, как только танки двинутся, сразу же можно открывать огонь.

Раздел 6: Распознавание столкновений

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

Что касается столкновений танков друг с другом, то пока позволим им это делать беспрепятственно (предлагаю вам доработать программу в этой части самостоятельно). Кроме этого нам нужно позаботиться о том, чтобы танки не могли проходить сквозь стены. Если вы помните, игровое поле представляет собой матрицу элементов, имеющую определенную размерность. В Net-Tank размер игрового поля составляет 20х11 ячеек, каждая из которых имеет площадь 16х16 пикселей. Следовательно, чтобы увидеть, не столкнулся ли танк со стенкой, то есть попал в занятую ячейку, необходимо:

§ Разделить обе координаты танка на 16;

§ Округлить результат до целого;

§ Использовать полученное значение как индекс ячейки игрового поля, чтобы увидеть, есть ли там блок. Если столкновение произошло, вернуть танк в прежнюю позицию.

Раздел 7: Рисование объектов

Теперь мы готовы нарисовать все объекты. Чтобы сделать это, мы должны сохранить фон в тех местах, где мы планируем разместить объекты. После этого их можно нарисовать. На этом этапе игровой экран полностью построен в дублирующем бу4эере и теперь можно посмотреть, что же у нас получилось.

Раздел 8: Дублирующий буфер

В Net-Tank используется техника дублирующей буферизации для исключения мерцания изображения. В этой части игры крайне быстрый цикл ассемблера копирует дублирующий буфер на экран. Однако мы перемещаем только первые 176 строк из буфера,.так как нижняя часть экрана неизменна и ее не надо перерисовывать.

Раздел 9: Всякая всячина

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

Раздел 10: Опять и снова к опять...

Условный переход к секции 1.

Итог

Мы не только научились работать последовательным портом, но и создали полную библиотеку, которая может быть использована в будущем с небольшими модификациями.

Мы также научились соединять в сеть два компьютера и узнали о факторах которые надо при этом учитывать. Наконец, у нас появилась полная (вернее почти полная) сетевая игра.


 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.