Четверг, 02.05.2024, 17:57
Приветствую Вас Гость
Главная | Основы создания сетевых игр с помощью DirectPlay - Форум | Регистрация | Вход
Меню сайта
Наш опрос
Где вы планируете встретить новый год?
1. Дома
2. Не дома
Всего ответов: 8
Форма входа
Друзья сайта
Статистика
Форум
[ Новые сообщения · Участники · Правила форума · Поиск ]
  • Страница 1 из 1
  • 1
Форум » Программирование » Blitz3D » Основы создания сетевых игр с помощью DirectPlay
Основы создания сетевых игр с помощью DirectPlay
TadeusDate: Воскресенье, 08.07.2007, 19:03 | Message # 1
Аццкий Магичег
Группа: Пользователи
Сообщений: 169
Статус: Offline
Итак, вы решили, что достаточно круты для создания сетевой игры? Значит, вы пришли по адрессу. В этом руководстве я постараюсь подробно описать, как сделать сие чудо. Что собой представляет сетевая игра? Есть как минимум два компьютера - сервер и клиент. Сервер - это тот, кто создает игру, а клиент, соответственно, тот, кто к ней подключается. Причем, на одном компьютере можно запустить несколько игровых сеансов, но вот скорость, с которой они будут работать - это уже вопрос отдельный. Далее, каждый компьютер имеет свой адресс, именуемый IP-адрессом. IP-адресс выглядит, например, вот так: "77.122.56.45". Чтобы подключится к серверу, клиент должен ввести его IP-адресс, однако тут есть один маленький нюанс, который может сильно подпортить жизнь. Это, так называемые, прокси. Прокси - это когда один компьютер имеет доступ в Интернет через другой компьютер. И подключенных к Интернету таким способом может быть хоть вся локальная сеть. Однако, они все имеют один IP-адресс.IP-адресс сервера. Видите проблему? Если сеанс создан на подключенным таким образом компьютером, к нему подключится нельзя. Впрочем, этот компьютер может подключатся к другим в сети. Но, к сожалению, к Blitz'у это не относится. И в первом и во втором случае он банально выдает ошибку. Я до сих пор ищу решение этой проблемы внутренними средствами. А вот внешние есть - например, спец. библиотеки, написанные на других языках.Например, K-Net Lib. Мы же будем использовать средства Blitz'а именуемое DirectPlay. Но не беспокойтесь - даже, если у вас Интернет через прокси(кстати, Интернет может быть через прокси провайдера), то вы сможете опробовать игру даже в оффлайне.

Дело в том, что есть очень полезные специальные адресса. Один из них, именуемый "loopback" всегда подразумевает под собой IP-адресс машини, на котором запущена игра. Этот IP-адресс - "127.0.0.1". Запомните его, потому что он понадобится вам очень часто.

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

NetGame=StartNetGame()

Что же делает эта команда? Она вызывает диалоговое окно, в котором вы выбираем тип подключения, вводим IP-адресс сервера и, конечно, выбираем нужный нам сеанс. Некоторых сбивает это столку, впрочем я обьясню. Сначала выбираете тип соединения в верхнем списке. Для локальной сети и интернета рекомендую пункт с TCP/IP. Затем при выборе последнего выскакивает окно с просьбой ввести IP сервера. Если вы сервер - оставляйте пустым, если клиент - введите адресс сервера. В остальных случаях придется вводить параметры СОМ-порта, либо номер телефона для модемного соединения. Если мы клиент - в нижнем поле вводим имя сеанса и нажимаем кнопочку "Create New game" и смело идем в игру. Если же мы клиент - то двойным кликом щелкаем на нужном сеансе. Как видите, все довольно просто.

Эта функция возвращает 0 - подключение/создание сеанса не удалось, 1 - удачно подключились, 2- удачно создали сеанс. Прервать сеанс можно прервать командой StopNetGame. Разрывается сеанс только на локальной машине! Причем, если сервер выходил из игры, то сервером становится другой игрок. И второму отправляется системное сообщение типа 102. Впрочем, о типах сообщений попозже.

Есть еще две функции, заменающие ее. Это HostNetGame и JoinNetGame. Первая запускает сеанс(нужно указать имя) и возвращает 2 при удаче, 0 - при неудаче. Вторая подключается к сеансу(нужно указать имя и ИП) им возвращает 1 при удаче и 0 - при неудаче.

Далее, одна из самых важных команд - СreateNetPlayer. В скобках надо указать имя игрока. Обычно указывается имя, введенное с клавиатуры. Внимание! Это создает локального игрока! И только локального. Когда кто-то другой создает своего игрока, то остальным отправляется сообщение с типом 100. Поэтому надо добавлять имена, ИДы, а также всю остальную информацию о игроках в типы. Рекомендуется именно в типы, так как в таком случае не будет ограничений по количеству игроков. Функция возвращает ИД, созданного игрока. Запишите его в секцию про своего альтер эго.

Дальше - DeleteNetPlayer. Удаляет локального игрока по ИДу. Может встать вопрос - а почему собственно, может быть несколько игроков на одном ПК? А в некоторых играх может быть так, что несколько игроков играют вот так за одним компьютером.

RecvNetMsg. Без нее вы не сможете получать никаких сообщений. Она возвращает True, если пришло сообщение и False, если нет.

NetMsgType . Возвращает тип сообщения. О, вот мы и добрались до типов. Итак, повторим, и скажу про новые. 100- новый игрок(приходит от пришедшего игрока), 101 - игрок ушел(приходит от ушедшего игрока),102 - теперь мы сервер, 200 - сеанс накрылся медным тазом. Сообщения в диапазоне 1-99 - пользовательские. Некоторые могут спросить - а зачем много типов сообщений? А для того, чтобы не путать сообщения с 3Д-координатами, и сообщения чата.

NetMsgFrom. Возвращает ИД игрока, пославшего последнее сообщение.

NetMsgTo. Возвращает ИД игрока, которому слали сообщение.

NetMsgData. Возвращает содержание сообщения. ВНИМАНИЕ! Обьединяйте данные в одну строку! Во-первых, вы избежите жутких тормозов, а во-вторых сократите траффик.

NetPlayerName. Возвращает имя игрока по его ИДу.

NetPlayerLocal. Возвращает True, если указанный ИД игрока совпадает с нашим и False, если иначе

SendNetMsg. Первый параметр - тип сообщения, второй - содержание, третее - наш ИД, четвертое - ИД получателя(0 если всем), пятое(необязятельный параметр) - приоритет сообщений. Правда, если приоритет высокий, то скорость посылки сообщения низкая. Рекомендуется для чата.

Вот мы и разобрали что есть что. Если вам нужны более точные сведения, то посмотрите справку, или мой перевод ее на Boolean.name->Blitz3D->Переводы->Перевод раздела DirectPlay. И хотя там довольно много ошибок и неточностей, он понятен.

Далее, сделаем небольшую игру про кубики. Итак.

Type Player
Field name$,id,ent
End Type

Создаем тип игрока, который будет содержать его имя, ИД и ссылку на кубик.

Global cam
Global myent
Global myid
Global myname$

Инициализируем глобальные переменные: для камеры, ссылка на свой кубик, ссылка на свой ИД, ссылка на свое имя

Graphics3D 800,600,32,2
SetBuffer BackBuffer()

jng=JoinNetGame("World Arena","127.0.0.1")
If Not jng Then HostNetGame("World Arena")

Инициализируем графику и создаем игру. Заметьте - мы сначала пробуем подключится к сеансу на своем компьютере, а если его нет - создаем. Это очень удобно для тестирования и отладки. Я надеюсь, вы не забыли loopback?

p.Player=New Player
p\name=Input("Enter your name:")
p\id=CreateNetPlayer(p\name)
p\ent=CreateCube()
myname=p\name
myid=p\id
myent=p\ent

Создаем игрока. Также даем значения ссылкам на будущие. Рекомендую вам также так делать.

cam=CreateCamera()
PositionEntity cam,0,2,-5

Создаем и располагаем камеру - трудно не догадаться smile

While Not KeyHit(1)
UpdatePlayer()
UpdateNetwork()
RenderWorld
Flip
Wend

Цикл - серце игры smile Далее, приведу функции.

Function UpdatePlayer()
If KeyDown(17) MoveEntity myent,0,0,.1
If KeyDown(31) MoveEntity myent,0,0,-.1
If KeyDown(30) TurnEntity myent,0,1,0
If KeyDown(32) TurnEntity myent,0,-1,0
SendNetMsg 2,PackMsg$(myent),myid,0
End Function

Function UpdateNetwork()
While RecvNetMsg()
Select NetMsgType()
Case 100
p.Player=New Player
p\id=NetMsgFrom()
p\name=NetPlayerName(p\id)
p\ent=CreateCube()
Case 101
p.Player=FindPlayer(NetMsgFrom())
FreeEntity p\ent
Delete p
Case 2
p.Player=FindPlayer(NetMsgFrom())
UnpackMsg(p\ent,NetMsgData$())
End Select
Wend
End Function

Function FindPlayer.Player( id )
For p.Player=Each Player
If p\id=id Then Return p
Next
End Function

Function PackMsg$(ent)
Return EntityX(ent)+"|"+EntityZ(ent)+"|"+EntityYaw(ent)
End Function

Function UnpackMsg(ent,dat$)
xp=Instr(dat$,"|")
x=Float(Left(dat$,xp))
dat$=Right(dat$,Len(dat$)-xp)
zp=Instr(dat$,"|")
z=Float(Left(dat$,z p))
dat$=Right(dat$,Len(dat$)-zp)
yaw=Float(Left(dat$,Len(dat$)))
PositionEntity ent,x,0,z
RotateEntity ent,0,yaw,0
End Function

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

Как видите, создавать сетевые игры - это не так сложно как, возможно, кажется на первый взгляд. А может быть когда-нибуть вы сделаете супер-пупер ММОРПГ? smile В любом случае желаю удачи.

С Уважением, Волошин Леонид аka Tadeus(Progger_Leo)

Сообщение отредактировал Tadeus - Воскресенье, 08.07.2007, 22:22
 
PibambaDate: Среда, 12.09.2007, 12:30 | Message # 2
Рядовой
Группа: Пользователи
Сообщений: 1
Статус: Offline
Привет! У меня Блитц ругается на строку z=Float(Left(dat$,z p)), пишет Expecting ')', я удаляю пробел между z и p и тогда всё пашет но не полностью, компилирую два раза да бы создать серв и клиента, потом на секунд пять эти приложения виснут и в обоих появляется ссобщение Энтер ё нэйм, я ввожу в каждом ник и в одиночестве скольЖу кубикоМ хотя по идее они должны быть в "одном мире" но так как коннект не получился оба приложения стали серверами sad
 
TadeusDate: Суббота, 20.10.2007, 21:10 | Message # 3
Аццкий Магичег
Группа: Пользователи
Сообщений: 169
Статус: Offline
Так, ошибка с типом флоат понятна. Сейчас исправлю.

А насчет сервера и клиента. Гхм, незнаю. Посмотрю еще.

Добавлено (Сегодня, 21:10)
---------------------------------------------
Переглядывая форум, зашел в эту тему и понял причину smile Запусти сначала один раз, введи имя и зайди в игру, затем запусти второе - введи имя и готово happy

 
Форум » Программирование » Blitz3D » Основы создания сетевых игр с помощью DirectPlay
  • Страница 1 из 1
  • 1
Поиск:
Copyright JohnK© 2024