Показать сообщение отдельно
Старый 10.01.2007, 06:05   #1
HolyDel
 
Регистрация: 26.09.2006
Сообщений: 6,035
Написано 1,474 полезных сообщений
(для 2,707 пользователей)
Подмигивание Разработка сетевых игр

Итак, похоже тема создания сетевых игр на Blitz3D интересует многих, а русскоязычных материалов реально мало. Чтобы их стало немного больше, ваш покорный слуга HolyDel решил написать маааааленький тутор на эту тему. Так как писать сетевые крестики-нолики неохота, будем писать нечто более продвинутое, а именно космические войны, на кораблях. Корабли будут биллбоардами с натянутыми на них текстурами кораблей.
Начнем собственно с создания подключения:
[blitz]
is_host=StartNetGame()=2
[/blitz]
Переменной is_host присваивается значение условия StartNetGame()=2, т.е. is_host=1 если StartNetGame()=2 иначе is_host=0. Эта переменная будет показывать является ли этот компьютер сервером.
Далее запрашиваем имя, создаем графический режим, а также камеру:
[blitz]
Graphics3d 800,600,32,1
SetBuffer backbuffer()
cam=createcamera()
[/blitz]
Тут все просто. Далее опишем структуру сетевого игрока:
[blitz]
Type player
field ent,id,name$
field en#
field ammo[4],ammo2[4]
field dx#,dz#
field mode
End Type
[/blitz]
Ent – для указателя на объект, id – сетевой идентификатор игрока, name - имя игрока, совпадающие с сетевым именем игрока. En# - энергия игрока, ammo, ammo2 здесь будет храниться кол-во патронов первичного и вторичного оружия, dx, dz – скорость перемещения по оси x и оси z, mode для определения режима игрока - 1 игрок (человек) 2 – бот, 0 – ошибка какая-то.
Теперь создадим квад и наложим на него текстуру корабля:
[blitz]
Global quad=CreateMesh()
b=LoadBrush("media/rocket.bmp",5)
s=CreateSurface(quad,b)
v0=AddVertex(s,-4,0,4,0,0)
v1=AddVertex(s,4,0,4,1,0)
v2=AddVertex(s,4,0,-4,1,1)
v3=AddVertex(s,-4,0,-4,0,1)
AddTriangle(s,v0,v1,v2)
AddTriangle(s,v0,v2,v3)
[/blitz]

Теперь добавим сетевого игрока, одновременно с ним добавим игрока на машину как в трехмерный мир так и в список player где и будут находиться все игроки (в том числе и боты)
[blitz]
p.player=New player
If netgame Then myid=CreateNetPlayer(name$) Else myid=Rand(1,2054345431)
p\id=myid
myent=CopyEntity(quad)
p\ent=myent
p\en=100
p\mode=1
p\ammo[1]=100
p\ammo2[1]=4
myp.player=p.player
p\name=name
[/blitz]
Здесь вы наверняка заметили всякие myp, myid, myent это просто копии полей для ускоренного доступа к полям своего корабля.

Немного подумав, я решил переделать начало на такое:
[blitz]
i=Input("type 1 if net game any other for local game =>")
netgame=i=1
If netgame
sng=StartNetGame()
is_host=sng=2
netgame=sng>0
Else
is_host=1
EndIf
[/blitz]
Здесь переменной netgame присваивается 1 если игра сетевая. Это может понадобиться для локальной (не сетевой игры).

Чтоб камера «смотрела» вниз:
[blitz]
RotateEntity cam,90,0,0
[/blitz]

Основной цикл:
[blitz]
While Not KeyDown(1)
ang#=ATan2(400-MouseX(),300-MouseY())
RotateEntity myent,0,ang,0

If KeyDown(200)
myp\dx=myp\dx-Sin(ang)*0.0008
myp\dz=myp\dz+Cos(ang)*0.0008
EndIf
myp\dx=myp\dx*0.995
myp\dz=myp\dz*0.995
TranslateEntity myent,myp\dx,0,myp\dz
PositionEntity cam,EntityX(myent),32,EntityZ(myent)
RenderWorld
Oval MouseX()-3,MouseY()-3,5,5,0
Flip 0
Wend
[/blitz]
Здесь: определяется угол поворота корабля, и корабль поворачивается на этот угол. При нажатии на стрелку вверх, изменяются значения смещения корабля по оси x и z (Аля тригонометрия). Потом эти-же абсолютные значения уменьшаются (гасятся (Аля физика)). Потом объект перемещается на величину смещения, камера устанавливается над кораблем, мир рендерится, отображается импровизированный курсор, буферы меняются местами.
Напишем три функции, которые нам могут понадобиться:
[blitz]
function PackMoveMessage$(p.player)
return left(entityx(p\ent),6)+left(entityz(p\ent),6)+left (int(entityYaw(p\ent)),4)
End Function

Function UnPackMoveMessage(p.player,dat$)
positionentity p\ent,mid(dat,1,6),0,mid(dat,7,6)
rotateentity p\ent,0,mid(dat,13,4),0
End Function

function FindPlayer.player(id)
for p.player=each player
if p\id=id then return p
Next
return null
End Function
[/blitz]
Первая собирает сообщение о игроке, в сообщение включаются координаты по икс и зет, а также поворот по оси грек.
Вторая разбирает сообщение и устанавливает корабль игрока в эту точку и поворачивает на данный угол.
Третья ищет игрока по идентификатору.
(Offline)
 
Ответить с цитированием