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

Итак, продолжим.
Во-первых добавим поле к игроку с названием score. А также rt[4],rt2[4], где будет храниться время последнего запуска пули.
Во вторых еще два типа – bullet и flame
[blitz]
Type player
Field ent,id,name$
Field en#
Field ammo[4],ammo2[4]
Field dx#,dz#
Field mode,score
field rt[4],rt2[4]
End Type

Type bullet
Field ent,dam#,l#,id
End Type

Type flame
Field spr,l#,r#,dr#
End Type
[/blitz]

Далее загрузим космос и огонь, а также картинку для радара.
[blitz]
;s1=CreatePlane()
s2=CreatePlane()
;s3=CreatePlane()
s4=CreatePlane()
;st1=LoadTexture("media/stars1.bmp",3+256)
st2=LoadTexture("media/stars2.bmp",3+256)
;st3=LoadTexture("media/stars3.bmp",3+256)
st4=LoadTexture("media/stars4.bmp",3+256)
;EntityTexture s1,st1
EntityTexture s2,st2
;EntityTexture s3,st3
EntityTexture s4,st4
;PositionEntity s1,0,-200,0
PositionEntity s2,0,-100,0
;PositionEntity s3,0,-50,0
PositionEntity s4,0,-25,0
;ScaleTexture st1,32,32
ScaleTexture st2,32,32
;ScaleTexture st3,32,32
ScaleTexture st4,32,32


radar=LoadImage("media/radar.png")

Global flame[2]
flame[1]=LoadSprite("media/flame1.bmp")
flame[2]=LoadSprite("media/flame2.bmp")
[/blitz]
Вы можете раскоментировать некоторые строки, я их закоментил так как у меня виснуть начинает.
Насчет неба – это просто четыре (тут две) плейна, они находятся на разной высоте, поэтому создается эффект объемности окружения.

Для огня из сопла напишем следующие функции:
[blitz]
Function AddFlame(ent)
f.flame=New flame
f\spr=CopyEntity(flame[Rand(1,2)])
PositionEntity f\spr,EntityX(ent),0,EntityZ(ent)
RotateEntity f\spr,0,EntityYaw(ent),0
MoveEntity f\spr,0,0,-4
TurnEntity f\spr,0,Rnd(-19.0,19.0),0
f\l=50:f\r=Rnd(0,360):f\dr=Rnd(-5.0,5.0)
End Function

Function UpdateFlames()
For f.flame=Each flame
f\l=f\l-1
EntityAlpha f\spr,f\l/50.0
ScaleSprite f\spr,(50-f\l)/10+2,(50-f\l)/10+2
MoveEntity f\spr,0,0,-0.3
f\r=f\r+f\dr
RotateSprite f\spr,f\r
If f\l<0 Then FreeEntity f\spr:Delete f
Next
End Function
[/blitz]
Ну здесь вроде вопросов быть не должно, итак все предельно понятно. UpdateFlames() пропишем перед RenderWorld.
Надо еще выводить имена игроков на экран, над их кораблем, для этого вобъем следущие после RenderWorld:
[blitz]
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
[/blitz]
Здесь перебираем всех игроков, и если их id не совпадает с нашим (если это не наш корабль), выводим над ним текст с именем. Координаты текста определяются через проецирование камеры на объект.

Для отображения корабля на радаре нам надо функцию рисования треугольника.
[blitz]
Function DrawTris(x,y,a)
a=180+a
x1#=x+Sin(a)*6
y1#=y+Cos(a)*6
x2#=x+Sin(a-120)*2
y2#=y+Cos(a-120)*2
x3#=x+Sin(a+120)*2
y3#=y+Cos(a+120)*2
Line x1,y1,x2,y2
Line x1,y1,x3,y3
Line x2,y2,x3,y3
End Function
[/blitz]
Здесь чисто математика, мы определяем координаты вершин и рисуем лини между этими вершинами.
Там где выводили имена игроков, изменим:
[blitz]
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
sx=54+800-108+EntityX(p\ent)/10
sy=54-EntityZ(p\ent)/10
DrawTris(sx,sy,EntityYaw(p\ent))
Next
[/blitz]
Собсно новый фрагмент:
sx=800-54+EntityX(p\ent)/10
sy=54-EntityZ(p\ent)/10
DrawTris(sx,sy,EntityYaw(p\ent))
Здесь sx, sy это координата корабля на радаре, ессено эти значения зависят от координат корабля в мире, так как радар а на 100 на 100, а мир 1000 на 1000, мировые координаты надо поделить на 10, чтобы как-бы спроецировать мир на радар. 54 это центр радара, ну 50 это 100/2 и 4 это рамка. То есть мы от границы экрана справа, отнимаем 54 – это и будет центр по оси х, с sy проще, так как радар находится в самом верху, тут мы прибавляем к центру -EntityZ(p\ent)/10, т.е. В общем это было получено экспериментальным путем.

Дли снарядов, ракет и т.д. нам нужен еще один квад, уже пустой, на прошлый квад мы сразу наложили текстуру корабля, уже при создании, просто скопируем оттуда код, и уберем тексу нах.
[blitz]
Global quad2=CreateMesh()
s=CreateSurface(quad2)
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)
PositionEntity quad2,0,120,0
[/blitz]
Это можно поставить прям после создания первого квада.
Теперь создадим массив для текстур снарядов и загрузим одну.
[blitz]
global bulls[4]
bulls[1]=loadtexture("media/disrap.png")
textureblend bulls[1],3
[/blitz]
Кваду будем ставить режим наложения – аддитивный, так как это типа огонь.

Далее введем характиристики оружия:
[blitz]
Dim ft(4)
Dim ft2(4)
ft(1)=7
ft(2)=11
ft(3)=3
ft(4)=15
ft2(1)=35
ft2(2)=20
ft2(3)=40
ft2(4)=45
[/blitz]
Эти значения будут определять частоту огня, точнее задержку перед следующим выстрелом. Чем меньше задержка, тем скорострельнее оружие.

Для своего корабля (пока только для своего) инкреминтируем значения полей rt[1..4] и rt2[1..4], естественно сделаем это в цикле:
For i=1 To 4
myp\rt[i]=myp\rt[i]+1
myp\rt2[i]=myp\rt2[i]+1
Next
Далее при нажатии левой кнопки мыша будет стрельба.

[blitz]
If MouseDown(1)
If myp\rt[cw]>ft(cw) And myp\ammo[cw]>0
b.bullet=New bullet
b\ent=CopyEntity(quad2)
EntityBlend b\ent,3
EntityTexture b\ent,bulls[cw]
PositionEntity b\ent,EntityX(myent),0.01,EntityZ(myent)
RotateEntity b\ent,0,EntityYaw(myent)+Rnd(-1,1),0
b\l=100
b\dam=20
b\spd=3
b\id=myid
myp\rt[cw]=0
myp\ammo[cw]=myp\ammo[cw]-1
EndIf
EndIf
[/blitz]
Cw это current weapon, в этой переменной хранится значение текущего основного орудия.
Здесь проверяем можно ли стрелять, стрелять можно только если есть патроны myp\ammo[cw]>0 и орудие готово myp\rt[cw]>ft(cw), другими словами если оно уже перезарядилось.
Затем myp\rt[cw]=0 пусть опять перезаряжается и убираем одну пулю myp\ammo[cw]=myp\ammo[cw]-1.
Из того что внутри стоит разве что выделить то, что пуля «запоминает» индекс стрельца, это во первых чтоб игрока не поразила своя пуля, во вторых чтоб приписывать очко тому, чья пуля добьет противника.

Собственно обновление пуль:
[blitz]
For b.bullet=Each bullet
MoveEntity b\ent,0,0,b\spd
b\l=b\l-1
If b\l<0 Then FreeEntity b\ent:Delete b
Next
[/blitz]
Пока только так.
(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо HolyDel за это полезное сообщение:
Артем Валерьевич (30.08.2010), НубеГ (23.06.2008)