Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ВІРТУАЛЬНА 3D ЕКСКУРСІЯ МІСТОМ.docx
Скачиваний:
12
Добавлен:
27.10.2018
Размер:
1 Мб
Скачать
☆

Розділ 3 опис алгоритму та обґрунтування проектних рішень

Як уже зазначалося, для реалізації програми використовувалась мова програмування Blitz3D. Клієнтська програма реалізована у вигляді стандартного windows-вікна. Розміри вікна можна вказувати в cfg-файлі. Спочатку, після запуску програми відображається процес підключення до серверу. Користувачу виводиться повідомлення про успішне або неуспішне підключення.

Після підключення, користувач з’являється у інтерактивному міському середовищі. Навколо користувача будинки, хмарочоси, магазини. Користувач може переміщуватись по місту, заходити у кімнати підходити до інших користувачів і писати їм текстові повідомлення.

Алгоритм переміщення по місту має досить складну будову. Уся локація розбивається на менші шматки, коли користувач підходить до кінця такого фрагмента, це може буди дорога, будинок чи магазин, завантажується новий фрагмент попереду користувача, і вивантажується позаду. Таким чином можна переміщуватися по місту безкінечно довго.

Всі дії користувача відправляються на сервер, обробляються і відсилаються всім користувачам. На основі цих змін, програма змінює положення користувачів в місті, відображає текстові повідомлення та інше.

3.1 Клієнтська програма

Код клієнтської програми досить великий. Є дуже велика. Є дуже велика кількість різноманітних функцій, більшість з яких є допоміжними і ніяк не стосуються клієнт/серверної взаємодії. В даному розділі розглянемо основні функції, за допомогою яких працює чат.

При запуску програми, із зовнішнього файлу завантажуються спеціальні дані, включаючи дані для авторизації на сервері. За це відповідає наступна функція. Якщо файл не знайдено, то вона ініціалізує параметри по замовчуванню.

Function cfg()

Local fileName$ = "default.cfg"

If cmdLine<>""

fileName$ = cmdLine + ".cfg"

EndIf

wf=ReadFile(fileName)

If wf<>0

wig=ReadLine(wf)

hei=ReadLine(wf)

ip$=ReadLine(wf)

login$=ReadLine(wf)

password$=ReadLine(wf)

CloseFile wf

Else

wig#=640

hei#=480

ip$="127.0.0.1"

login$="klient"

password$="12345"

EndIf

End Function

Після завантаження та ініціалізації, виконується функція AllConnect(). Вона слугує для підключення до серверу. Головним в цьому процесі є перевірка імені та паролю користувача. Ці функції дуже схожі між собою, тому розглянемо лише функцію перевірки пароля користувача. Після виконання, функція повертає результат підключення до серверу.

Function Passw()

KNL_SendInteger(102)

KNL_SendString(password$)

KNL_UpdateNetwork(0,2,5000,2+4)

conna=0

tcon=MilliSecs()

While conna<>1

If MilliSecs()-tcon>5000

conna=1

conn=0

passout=2

EndIf

If KNL_CheckMessages()<>0

If KNL_GetMessageID()=KNL_MSG_Receive

If KNL_GetInteger(0)=102

passout = KNL_GetInteger(1)

mainID = KNL_GetInteger(2)

conna=1

conn=-1

KNL_ClearMessage()

Exit

EndIf

EndIf

KNL_ClearMessage()

EndIf

Wend

Return passout

End Function

Після підключення викликаються функції для створення користувача CreatePlayer(), створення інтерактивної локації levelO(), завантаження об’єктів локації CreateObject(). Потім посилається запит на розміщення користувача в чаті:

Function AddPlayer()

KNL_SendInteger(103)

KNL_SendInteger(LocationX)

KNL_SendInteger(LocationZ)

KNL_SendFloat(EntityX(heromodel,1))

KNL_SendFloat(EntityY(heromodel,1))

KNL_SendFloat(EntityZ(heromodel,1))

KNL_SendFloat(EntityYaw(heromodel,1))

KNL_UpdateNetwork(0,2,5000,2+4)

End Function

Далі йде головний цикл програми. В якому відбувається обробка всіх даних. Спочатку відбувається обробка користувача:

Function UpdatePlayer()

MouseLook()

Walk()

Jump()

animation()

Rotate_camera()

Mode()

End Function

Ця функція виконує по черзі управління мишкою, управляння переміщенням, управляння підплигуванням, управляння анімацією користувача, поворотом камери, а також відслідковую переключення ігрових режимів. Далі відбувається обробка неба UpdateSky(), та ігрової локації UpdateLevel(). Далі, якщо користувач підключений до серверу, то відбувається відправка даних про розміщення користувача в інтерактивному просторі:

Function Send_Pos()

If MilliSecs()-time_pos>100

time_pos=MilliSecs()

x#=EntityX(HeroModel,1)

y#=EntityY(HeroModel,1)

z#=EntityZ(HeroModel,1)

yaw#=EntityYaw(HeroModel,1)

If Abs(x-xold)>0.2 Or Abs(y-yold)>0.2Or Abs(z-zold)>0.2

Or Abs(yaw-yawold)>1

xold=x

yold=y

zold=z

yawold=yaw

KNL_SendInteger(1)

KNL_SendFloat (x)

KNL_SendFloat (y)

KNL_SendFloat (z)

KNL_SendFloat (Yaw)

KNL_SendInteger(LocationX)

KNL_SendInteger(LocationZ)

KNL_UpdateNetwork(0,0,500,8)

EndIf

EndIf

End Function

Далі виконується головна функція, що обробляє повідомлення, тобто мережні пакети від серверу. Функція досить об’ємна, тому повний її код розглядати не будемо, а розглянемо лише головні обробники мережевих пакетів.

Обробник нового чат-повідомлення:

Case 99

PlayerID =KNL_GetInteger(1)

For Player.Players = Each Players

If Player\ID = PlayerID

From$ = Player\Name$

Exit

EndIf

Next

Chat$ = KNL_GetString(2)

AddChat(From$,1,Chat$)

Обробник створення гравця на локації:

Case 100 ; (добавить)

ID=KNL_GetInteger(1)

Name$=KNL_GetString(2)

model$=KNL_GetString(3)

skin$=KNL_GetString(4)

Location_X=KNL_GetInteger(5)

Location_Z=KNL_GetInteger(6)

x#=KNL_GetFloat(7)

y#=KNL_GetFloat(8)

z#=KNL_GetFloat(9)

yaw#=KNL_GetFloat(10)

idleb=KNL_GetInteger(11)

If mainID<>ID

CreateBot(ID,Name$,model$,skin$,Location_X,Location_Z, x,y,z,yaw,idleb)

EndIf

Обробник пакету видалення гравця з локації:

Case 200 ; (удалить)

ID=KNL_GetInteger(1)

DestroyBot(ID)

Обробник переміщення гравців на локації:

Case 1 ; (позиция)

ID=KNL_GetInteger(1)

x#=KNL_GetFloat(2)

y#=KNL_GetFloat(3)

z#=KNL_GetFloat(4)

yaw#=KNL_GetFloat(5)

loc_x=KNL_GetInteger(6)

loc_z=KNL_GetInteger(7)

PositionBot(ID,x,y,z,yaw,loc_x,loc_z)

Також є функція, яка виводить повідомлення якщо відбулися якість збої на сервері. Після цього зв’язок із сервером припиняється:

Function Send_Out()

If MilliSecs()-timePlayerOut>5000

KNL_SendInteger(900)

KNL_UpdateNetwork(0,0,500,8)

If MilliSecs()-timeServerOut>10000

connectYes=0

Text 200,200,"Сервер не работает !!"

Flip

WaitKey

EndIf

EndIf

End Function

Після завершення роботи програми викликаються стандартні функції, для коректного завершення та звільнення використаних системних ресурсів:

KNL_Shutdown()

End