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

Теперь собственно сетевой механизм. Это попробую описать подробно:
Во, первых все что связанно с сетью заключим в блок if netgame …… endif, чтоб небыло ошибок. Тогда имеем:
[blitz]
if netgame
sendnetmsg 1,PackMoveMessage(myp),myid,0,0

While RecvNetMsg()
Select NetMsgType()
Case 1:
p.player=FindPlayer(netmsgfrom)
if p<>null
UnPackMoveMessage(p,netmsgdata()
else
p.player=New player
p\id=netmsgfrom()
p\ent=CopyEntity(quad)
p\en=100
p\mode=1
p\ammo[1]=100
p\ammo2[1]=4
p\name=netplayername(p\id)
endif
case 100:
p.player=New player
p\id=netmsgfrom()
p\ent=CopyEntity(quad)
p\en=100
p\mode=1
p\ammo[1]=100
p\ammo2[1]=4
p\name=netplayername(p\id)
Default
DebugLog NetMsgType+":"+NEtmsgdata()
End Select
Wend

EndIf
[/blitz]

Первая строчка
sendnetmsg 1,PackMoveMessage(myp),myid,0,0
отправляет сообщение по сети, это сообщение имеет свой тип. В данном случае 1 – первый параметр.
Второй параметр само сообщение (строка)
Третий от кого – здесь стоит myid, посмотрите выше, этой переменной мы присвоили значение CreateNetPlayer – это сетевой идентификатор. То есть мы посылаем сообщение от себя.
Четвертый 0 – это кому отправляется сообщение, если 0 то сообщение отправляется всем игрокам, собственно что нам и надо, чтобы у всех игроков наш корабль отображался там, где он находится у нас.
Пятый 0- если здесь будет стоять 1 то будет проверяться достоверность сообщения, это приводит к примерно трехкратному замедлению выполнения команды, если будет стоять 0 то возможно сообщение будет принято не то что было послано (может быть потерян смысл). Так как позиция и поворот это не очень важно, то и пусть себе теряется .

Теперь пару слов о втором параметре PackMoveMessage(myp), здесь мы собираем всю инфу, которую хотим передать о игроке myp – собственно нашем игроке функцией PackMoveMessage (она была описана ранее).

Далее идет конструкция
While recvnetmsg()
Wend
Что обозначает пока есть сообщение, этот цикл будет крутиться до тех пор, пока есть принятое сообщение.
Далее стоит
Select NetMsgType
End select
Тут идет определение типа сообщения и соответственная раскодировка сообщения.
Например:
case 100:
p.player=New player
p\id=netmsgfrom()
p\ent=CopyEntity(quad)
p\en=100
p\mode=1
p\ammo[1]=100
p\ammo2[1]=4
p\name=netplayername(p\id)
такое сообщение (сообщение с таким типом) отсылается всем игрокам, когда новый игрок присоединился к игре.
Здесь мы создаем нового игрока, его id мы получаем из netmsgfrom(), т.е. от кого пришло сообщение, а имя игрока получаем из netplayername(p\id). Остальное вроде понятно.
Далее:
Case 1:
p.player=FindPlayer(netmsgfrom)
if p<>null
UnPackMoveMessage(p,netmsgdata()
else
p.player=New player
p\id=netmsgfrom()
p\ent=CopyEntity(quad)
p\en=100
p\mode=1
p\ammo[1]=100
p\ammo2[1]=4
p\name=netplayername(p\id)
endif
помните какое сообщение отсылается с типом 1? Правильно! Сообщение о позиции игрока. Это сообщение декодируется соответствующей функцией. Только сначала ищется игрок в списке от которого пришло сообщение. Если игрок найден то к нему применяется сообщение если не найден то он создается.

Ну пока все, приду из аццкого колледжа –продолжу.

Весь код
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

name$=Input("your name:")
Graphics3D 800,600,32,1
SetBuffer BackBuffer()
SeedRnd MilliSecs()
cam=CreateCamera()

Type player
	Field ent,id,name$
	Field en#
	Field ammo[4],ammo2[4]
	Field dx#,dz#
	Field mode
End Type

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)

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

RotateEntity cam,90,0,0

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
	
	For p.player=Each player
		If p\id<>myid
			CameraProject(cam,EntityX(p\ent),0,EntityZ(p\ent))
			x=ProjectedX()
			y=ProjectedY()
			If x>-100 And x<900 And y>-100 And y<700
				Text x,y-16,p\name,1
			EndIf
		EndIf
	Next
	Flip 0
	
	;update network
	If netgame
	SendNetMsg 1,PackMoveMessage(myp),myid,0,0
	
	While RecvNetMsg()
		Select NetMsgType()
			Case 1:
				p.player=FindPlayer(NetMsgFrom)
				If p<>Null
					UnPackMoveMessage(p.player,NetMsgData())
				Else
					p.player=New player
					p\id=NetMsgFrom()
					p\ent=CopyEntity(quad)
					p\en=100
					p\mode=1
					p\ammo[1]=100
					p\ammo2[1]=4
					p\name=NetPlayerName(p\id)				
				EndIf
			Case 100:
				p.player=New player
				p\id=NetMsgFrom()
				p\ent=CopyEntity(quad)
				p\en=100
				p\mode=1
				p\ammo[1]=100
				p\ammo2[1]=4
				p\name=NetPlayerName(p\id)
			Default
				DebugLog NetMsgType+":"+NetMsgData()
		End Select
	Wend
	
	EndIf
	
Wend

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
Пс. Пока они тока двигаться будут, просто писал где – то 2 часа вместе с этим тескстом, к ночи еще че-нить добавлю.
Пс. Я это еще не проверял, поэтому могут быть мелкие ошибки. Ваш покорный слуга HolyDel a.k.a. Олег Сапронов.
(Offline)
 
Ответить с цитированием