О сайте
  Новости сайта
  Почитать
  Утилиты
 
  Help Blitz3D
 
   

 

 

 

 

 

 

 

 

 

Основы создания сетевых игр с использованием DirectPlay

Автор: Tadeus (Progger_Leo)
e-mail или ICQ 420^069^087

Итак, Вы решили, что достаточно круты для создания сетевой игры? Значит, Вы пришли по адресу. В этом руководстве я постараюсь подробно описать, как сделать сие чудо. Что собой представляет сетевая игра? Есть как минимум два компьютера - сервер и клиент. Сервер - это тот, кто создает игру, а клиент, соответственно, тот, кто к ней подключается. Причем, на одном компьютере можно запустить несколько игровых сеансов, но вот скорость, с которой они будут работать - это уже вопрос отдельный. Далее, каждый компьютер имеет свой адрес, именуемый 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 - при неудаче. Вторая подключается к сеансу (нужно указать имя и IP) и возвращает 1 при удаче и 0 - при неудаче.

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

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

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

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

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

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

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

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

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

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

Вот мы и разобрали, что есть что.

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

Type Player

Field name$,id,ent

End Type

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

Graphics3D 800,600,32,2

SetBuffer BackBuffer()

jng=JoinNetGame("World Arena","127.0.0.1")

If Not jng Then HostNetGame("World Arena")

Инициализируем графику и создаем игру. Заметьте - мы сначала пробуем подключитmся к сеансу на своем компьютере, а если его нет - создаем. Это очень удобно для тестирования и отладки. Я надеюсь, вы не забыли 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

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

While Not KeyHit(1)

UpdatePlayer()
UpdateNetwork()
RenderWorld
Flip

Wend

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

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$,zp))
dat$= Right(dat$,Len(dat$)-zp)
yaw= Float(Left(dat$,Len(dat$)))
PositionEntity ent,x,0,z
RotateEntity ent,0,yaw,0

End Function

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

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

 

     
     
     
Hosted by uCoz