Ръководство: Създаване на Мрежови Игри GameMaker
Ръководство: Създаване на Мрежови Игри.
Ниво:Напреднали

Да играеш срещу компютър е забавно. Но да играеш срещу други хора може да бъде дори по-забавно. Освен това е относително лесно да направиш подобна игра, тъй като не трябва да имплементираш изкуствен интелект на компютърния опонент. Разбира се възможно е двама играчи да седят пред един монитор и да използват различни клавиши или входни устройства, но е много по-интересно когато всеки играч седи зад собствения си компютър..Или още по-добре, един от играчите седи от другата страна на океяна. За тази цел Game Maker има мрежова поддръжка. Това ръководство разяснява как да я използвате. Но трябва да предупредя, че създаването на ефективна мрежова игра не е лено. То изисква да сте опитен потребител на Game Maker. Трябва да разбирате използването на известно количество код. Затова нека това да не е първата игра, която разработвате.
В това ръководство ще създадем проста ping-pong игра за двама и малка програма за чат. Акцентът не е върху добрата графика или свеж геймплей, а само върху мрежовите аспекти. Можете да го използвате като основа за по-забавни игри. Ще разгледаме следните въпроси:
•Създаване на връзка към друг компютър
•Създаване или присъединяване към игрова сесия
•Поддържане на играта синхронизирана
Последната част е най-трудната част от всяка мрежова игра. Проблема е как да се осигури, че и двамата играчи виждат абсолютно едно и също състояние на играта. например, в ping-pong играта, и двамата играчи трябва да виждат топката на едно и също място. Game Maker предоставя средствата за да се направи това, но вие ще трбва сами да проектирате връзката за всяка игра, която правите
.
Създаване на връзка
Стандартния начин, по който всяка мрежова игра работи е следния. Всеки играч стартира копие на играта. Те обаче ги стартират в различни режими. Един играч стартира неговата или нейната игра в качеството на сървър. Останалите стартират играта като клиенти. Сървърът трябва да стартира играта първи и да създаде игрова сесия. Тогава останалите могат да се присъединят към тази сесия. Играчите трябва да изберат начина за комуникация между компютрите. В локална мрежа, най-лесно е да се използва IPX връзка (виж нататък за повече информация). Ако всички играчи са свързани към Интернет, обикновено се използва
TCP/IP. При този протокол клиентите трябва да знаят IP адреса на сървъра. Така че играчът, стартирал играта като сървър трябва да даде своя IP адрес на останалите (например като им изпрати E-mail). Можете да разберете своя IP адрес използвайки програма, наречена winipcfg.exe, намираща се в директорията на Windows. Можете също така да използвате функцията на Game Maker mplay_ipaddress() за целта. По старомоден начин за свързване е използването на връзка между модеми (в който случай клиента трябва да знае телефонния номер на сървъра и да го предостави) или използвайки сериен кабел.
Моля обърнете внимание, че връзката се осъществява по-трудно, когато хората ползват firewall и рутъри. Те се грижат за блокирнето на съобщенията и конвертирането на IP адреси. Ако имате проблем със съзфаването на връзка, това може да е причината. Най-добре първо опитайте с някоя комерсиална игра дали може да бъде осъществена връзка.
И така, за да комуникират два компютъра те имат нужда от някакъв свързващ протокол. Както при повечето игри, Game Maker предлага четири различни типа на връзка: IPX, TCP/IP, модем или серийна. IPX връзката (за да бъдем по-точни, това е протокол) работи почти напълно невидимо. Може да бъде използвана за да се играе с други хора в локална мрежа. На компютъра на играча трябва да е инсталиран протокола, за да се използва (ако не работи, проверете докуемнтацията на Windows. Или от елемента Network в Control Panel на Windows прибавете IPX протокола). TCP/IP е Интернет протокола. Може да се използва за да играете с други хора където и да било в Интернет, стига да знаете техните IP адреси. В локална мрежа можете да го използвате без да предоставяте адреси. Връзката между модеми се осъществява през модем. Трябва да предоставите някои настройки на модема (инициализационен низ и телефонен номер) за да я използвате. Накрая, когато използате връзка през серийния порт (директна връзка между компютри) трябва да предоставите някои настройки на портовете. Съществуват четири GML функции, които могат да се използват за инициализация на връзка:
•mplay_init_ipx() инициализира IPX връзка.
•mplay_init_tcpip(addr) инициализира TCP/IP връзка. addr е низ, съдържащ уеб или IP адрес, например 'www.gameplay.com' или '123.123.123.12', възможно следван от номер на порта (например. ':12'). Само когато се присъединявате към сесия (виж по-нататък) е необходимо да предосавите адрес. Човека, който създава сесията няма нужда да предоставя адрес (тъй като
адреса на собствения му компютър е този, който е необходим) При локална мрежа адреси не са необходими, но въпреки това функцията трябва да бъде извикана. •mplay_init_modem(initstr,phonenr)инициализира връзка през модем. initstr е инициализацинния низ на модема (може да е празен). phonenr е низ, съдържащ телефонния номер, на който да бъде набран (например '0201234567'). Само когато се присъединявате към сесия (виж нататък) е необходимо да предоставите телефонен номер.
•mplay_init_serial(portno,baudrate,stopbits,parity,flow)инициализира връзка през серийния порт. Стандартното извикване е mplay_init_serial(1,57600,0,0,4). Извикайте го с 0 за първи аргумент за да отворите диалогов прозорец, в който потребителя да промени настойките.
Вашата игра трябва да извика една от тези функции веднъж и само веднъж. Всички функции съобщават дали са били успешни. Те са неуспешни ако конкретния протокол не е инсталиран или поддържан от машината.
И така, първото ниво в нашата игра трябва да показва четирите възможности и да позволява на потребителя да избере една от тях (или да позволява само протоколите, които искате. Последните два могат да са твърде бавни за вашата игра). Ще извикваме инициализационната функция в събитието Моuse и ако е успещма. Ще преминаваме на следващото ниво. В противен случай ще извеждаме съобщение за грешка. Така че в събитието Mouse на IPX бутона поставяме следния код::
{
if (mplay_init_ipx())
room_goto_next()
else
show_message('Failed to initialize IPX connection.')
}
Когато играта приключва, или когато играта вече не и е необходимо да използва мрежова връзка, трябва да извикате следната функция за да я прекратите:
•mplay_end()прекъсва текущата връзка. Връща дали е била изпълнена успешно.
Трябва също така да извиквате тази процедура преди да направите нова, различна връзка.

Игрови сесии
Когато се свържете към мрежата, възможно е да има множество игри в същата амрежа. Това се нарива сесии. Тези различни сесии могат да отговарят на различни игри или на една и съща игра.
Играта трябва да да се идентифицира в мрежата. За щастие, Game Maker прави това за вас.
Единственото нещо, което трябва да знаете, че когато променяте game id в опциите на играта, мрежовия идентификатор се променя. По този начин можете да се уверите, че хора със стара версия на играта няма да играят срещу хора с по-нови версии.
Ако искате да започнете нова игра в мрежа, трябва да създадете нова сесия. За тези цел можете да използвате следната функция:
•mplay_session_create(sesname,playnumb,playername)създава нова сесия в текущата връзка. sesname е низ, указващ името на сесията. playnumb е число, указващо максималното количество играчи, позволени в тази сесия (използвайте 0 за произволно количество). playname е името на играча. Връща дали е успешна.
В много случаи името на играча не се използва и може да е празен низ. Освен това, името на сесията е важно само ако искате да дадете на потребителите възможността да изберат сесията, към която искат да се присъединят. И така, един екземпляр на играта трябва да създаде сесия. Останалите трябва да се писъединят към тази сесия.. Това е малко по-сложно. Първо трябва да проверите какви сесии са достъпни и след това да изберете една, към която да се свържете. Същестуват три функции, предназначени за тази цел.
•mplay_session_find()търси всички сесии, които все още приемат играчи, и връща количеството на намерените сесии..
•mplay_session_name(numb)връща името на сесия с номер numb (0 е първата сесия). Тази функция може да бъде извикана само след извикването на предишната функция..
•mplay_session_join(numb,playername) присъединява играча към сесия с номер numb (0 е първата сесия). playername е името на играча. Връща дали е успеша.
Това, което обикновено трябва да направите, е да извикате mplay_session_find()за да намерите всички съществуващи сесии. След това или кратно извиквате mplay_session_name() за да покажете сесиите на играча и да му дадете възможността да избере, или незабавно го присъединявате към първата сесия (Забележете че намирането на сесиите отнема доста време, затова не извиквайте тази функция във всеки кадър)
Играчът може да прекрати сесия, използвайки следната функция:
•mplay_session_end()прекратява сесията за дадения играч.
Хубаво е първо да предупредите другите играчи, но това не е строго необходимо.
И така, в нашата игра, второто ниво дава на потребителя два варианта: или да създаде нова сесия или да се присъедини към съществуваща такава.. За първия избор трябва да изпълним следния код в събитието Mouse:
{
if (mplay_session_create('',2,''))
{
global.master = true;
room_goto_next();
}
else
show_message('Failed to create a session.')
}
Забележете, че присвоихме на глобалната променлива master стойност true. Причината е, че в играта трябва да направим разлика между главния играч (наречен master - господар, по-нататък ще го наричам просто сървър) и втория играч (наречен slave - роб, по-нататък ще го наричам клиент). Господаря ще е отговорен за по-голямата част от геймплея докато робът просто ще го следва.
Втория вариант е да се писъедини към същестуваща сесия. Тук кода изглежда така:
{
if (mplay_session_find() > 0)
{
if (mplay_session_join(0,''))
{
global.master = false;
room_goto_next();
}
else
show_message('Failed to join a session.')
}
else
show_message('No session available to join.')
}
В нашата игра просто се присъединяваме към първата свободна сесия. Тъй като определихме максимално количество от двама играчи, зне е възможно други играчи да се присъединят към сесията
.
Работа с играчите
След като господарят веднъж е създал сесия, той трябва да изчака друг играч да се присъедини. Съществуват три процедури, които имат отношение към играчите:
•mplay_player_find() намира всички играчи в текущата сесия и връща тяхното количество.
•mplay_player_name(numb)връща името на играча с номер numb (0 е първия играч,
койо винаги е играчът, извикал функцията). Тази функция може да бъде извикана само след извикването на предишната функция.
•mplay_player_id(numb)връща уникален идентификационен номер на играча с номер numb (0 е първия играч, койо винаги е играчът, извикал функцията). Тази функция може да бъде извикана само след извикването на първата функция. Уникалния иденвификационен номер се използва за изпращане и получаване на съобщения до и от отделни играчи.
В третото ниво просто чакаме за втори играч. Затова слагамя някой обект там и в събитието Step добавяме:
{
if (mplay_player_find() > 1)
room_goto_next();
}
(Фактически клиентът не трябва да идва на това ниво)

Синхронизиране на действията
След като сме осъществили връзка, създали сесия и имаме двама играчи в нея, истинската игра може да започне. Но това означава че трябва да запознаем наистина да мислим за връзката. Основния проблем във всяка мрежова игра е синхронизацията. Как да осигурим и двамата играчи да виждат игралния свят по абсолютно еднакъв начин? Това е решаващо. Когато единия играч вижда топката в нашата игра на разлчни място от другия, странни неща могат да се получат (в най-лошия случай, за единия играч топката е ударена, докато за другия е пропусната). Игрите лесно излизат от синхронизация, което създава бъркотия в повечето игри.
Което е по-лошо, трябва да синхронизираме с ограничено количество съобщения. Ако например се играе през модем, връзката може да е бавна. Така че трябва да намалите количеството съобщения колкото се може повече. Освен това може да има забавяне докато информация пристигне до другата страна. Накрая, възможно е дори информацията да се загуби и никога да не стигне до другата страна. Как най-добре да решат всички тези проблеми зависи от типа на играта, която създавате. В походови игри вероятно ще използвате съвършенно различен метод отколкото в скоростни екшъни. Game Maker предлага два метода за комуникация: поделена дата и съобщения. Поделената дата е най-лесния метод за използване. Изпращането на съобщение е по-гъвкаво, но изисква да разбирате по-добре как работи връзката.

Синхронизация чрез поделена информация
Синхронизацията чрез поделена връзка е може би най-лесния начин да синхронизирате играта. Цялата връзка е скрита от вас. Съществува набор от 10 000 стойности, които са общи за всички играчи. Всеки играч може да записва и да чете стойности. Game Maker осигурява всеки играч да вижда едни и същи стойности. Свойността може да бъде число или низ. Има само две функции за целта:
•mplay_data_write(ind,val)записва стойността val (низ или число) на позиция ind (ind
трябва да е между 0 и 10000).
•mplay_data_read(ind)връща стойността, зашисана на позиция ind (ind трябва да е между 0 и 10000).
Първоначално всички стойности са 0.
За да използвате този метод трябва да определите коя стойност за какво се използва и кой може да я променя. За предпочитане е само един екземпляр на играта да записва стойността.
В нащия случай има 4 важни стойности: y-координатата на ракетата на сървъра, y-координатата на ракетата на клиента, x и y координатите на топкатаl. Така че използваме позиция 1 за да съхраняваме y-координатата на ракетата на сървъра, позиция 2 за да съхраняваме y-координатата на ракетата на клиента и т.н.. Ясно е че сървъра записва стойността за неговата ракета и клиента - за своята. Определяме също така, че сървъра ще е отговорен за стойностите, свързани с топката. Клиентът просто изрисува при всеки кадър топката в съответната позиция.
Как прилагаме всичко това? Преди всичко, ракетата на сървъра (която е лявата) трябва да се контролира само от сървъра. Това означава че за двата клавиша - стрелка нагоре и стрелка надолу, които го контролират, трябва да се уверим, че позицията му се променя само ако сме сървър. Така че кода за събитието на стрелката нагоре ще изглежда така:
{
if (!global.master) exit;
if (y > 104) y -= 6;
mplay_data_write(1,y);
}
За ракетата на клиента пишем подобен код. Сега трябва да осигурим че и сървъра, и клиента слагат ракетата на другия в коректната позиция. Това се осъществява в събитието Step. Ако е пуснат клиент, в събитието Step на ракетата на сървъра трябва да определим нейната позиция. Затова използваме следния код:
{
if (global.master) exit;
y = mplay_data_read(1);
}
Аналогично за ракетата на клиента.
Накрая, за топката преди всичко трябва да се уверим, че тя отскача когато удря стените и ракетите. Фактически това трябва да се направи само за сървъра. За да предадете позицията на топката на клиента, добавете следния код в събитието Step:
{
if (global.master)
{
mplay_data_write(3,x);
mplay_data_write(4,y);
}
else
{
x = mplay_data_read(3);
y = mplay_data_read(4);
}
}
С това основната синхронизация е направена. Остава контролирането на началото на играта, точките и т.н. Отново, всичко това е най-добре да се остави под контрола на сървъра. Така че сървъра определя кога играчът губи, променя точките (за които можем да използваме допълнителна позиция за да ги предадем на другия), и създава нова топка. Можете да проверите приложената игра pong1.gmd за повече детайли.
Обърнете внимание че със схемата за синхронизация, описана по-рано, двете игри все още могат да са доста несинхронизирани. Това обикновено не е проблем. Можете да го избегнете чрез създаването на накакъв синхронизационен обектм който използва определени стойности за да се увери, че и двете страни на играта са готови преди каквото и да е било да се е изрисувало на екрана. Това трябва да се използва внимателно, тъй като може да предизвика проблеми, като т.нар. deadlock при който и двете страни изчакват другатаr.
Имайте предвид, че когато играчът се присъединява към играта по-късно, променените поделени стойности не се изпращат на новия играч (това би отнело прекалено много време). Така че само новите промени след момента на присъединяване се изпращат на новия играч.

Съобщения
Втория метод за синхронизация, който се поддържа от Game Maker е изпращането и получаването на съобщение. Играчът може да изпрати съобщение на един или на всички други играчи. Играчите могат да проверяд дали е пристигнало съобщение и съответно да предприемат някакво действие. Съобщенията могат да се изпращат в гарантиран режим, в който можете да сте сигурни, че пристигат (но това може да е бавно) или в негарантиран режим, който е по-бърз. Като за начало ще използваме съобщения за да добавим някои звукови ефекти към играта. Трябва ми звук, когато топката удря ракета, когато удря стента и когато играчът печели точка. Само сървърът може да установява наличието на подобни събития. Така че сървърът трябва да реши, че звукът трябва да бъде въпроизведен. Това е лесно да се направи за неговата собствена игра. Той може просто да възпроизведе звука. Но той трябва също така да каже да клиента да възпроизведе звука. Можем да използваме поделена информация за да направим това, но така е прекалено сложно. Чрез използването на съобщение е много по-лесно. Сървърът просто изпраща съобщение на клиента да възпроизведе звука. Клиентът чака да получи съобщение и възпроизвежда необходимия звук, когато това е поискано от него.
Съществуват следните функции за работа със съобщения:
•mplay_message_send(player,id,val)изпраща съобщение на определения играч (чрез идентикатор или име; използвайте 0 за да изпратите съобщението на всички играчи). id е целочислен идентификатор на съобщението и val е неговата стойност (число или низ). Съобщението се изпраща в негарантиран режим.
•mplay_message_send_guaranteed(player,id,val) изпраща съобщение на определения играч (чрез идентикатор или име; използвайте 0 за да изпратите съобщението на всички играчи). id е целочислен идентификатор на съобщението и val е неговата стойност (число или низ). Съобщението се изпраща в гарантиран режим.
•mplay_message_receive(player) получава следващото съпбщение от опашката на съобщенията, идваща от определения играч (чрез идентификатор или име) Използвайте 0 за да получите съобщенията от който и да било играч. Функцията връща дали наистина е имало ново съобщение. Ако е имало, можете да използвате следните функции, за да получите съдържанието на съобшението:
•mplay_message_id() Връща идентификатора на последното получено съобщение.
•mplay_message_value() Връща стойността на посленото получено съобщение.
•mplay_message_player() Връща идентификатора на играча, който е изпратил последното получено съобщение.
•mplay_message_name()Връща името на играча, който е изпратил последното получено съобщение.
•mplay_message_count(player) Връща количеството съобщение, изпратени от играча player които чакат на опашката на съобщенията (използвайте 0 за да получите количеството на всички съобщения).
Тук е мястото да направим няколко забележки. Преди всичко, ако искате да изпратите съобщение на отделен играч, трябва да знаете неговия уникален идентификационен номер.
Както беше споменато по-рано, можете да го получите чрез функцията mplay_player_id(). Този идентификационен номер се използва също така при получаването на съобщения от определен играч. Като алтернатива, можете да укажете името на играча като низ. Ако множество играчи имат едно и също име, само първия ще получи съобщението.
Второ, може би се питате защо всяко съобщение има целочислен идентификатор. Причината е че това помага на вашето приложение да изпраща различни типове съобщения. Получателя може да провери типа на съобщението, използвайки идентификатора, и да извърши подходящи действия (тъй като не е гарантирано, че съобщенията ще пристигнат, изпращането на идентификатора и стойността в различни съобщения може да предизвика сериозни проблеми.)
За възпроизвеждането на звуците трябва да направим следното. Когато сървъра определи, че топката удря ракетата, той стартира следния код:
{
if (!global.master) exit;
sound_play(sound_bat); // play the sound yourself
mplay_message_send(0,100,sound_bat); // send it to the slave
}
Контролен обект в събитието си Step прави следното:
{
while (mplay_message_receive(0))
{
if (mplay_message_id() == 100) sound_play(mplay_message_value());
}
}
С други думи, той проверява дали има съобщение и ако има, проверява неговия идентификатор. Ако този идентификатор е 100, изпълнява звука, указан като стойност на съобщението.
По-общо, играта ви обикновени има контролен обект, който в събитието си Step прави нещо като:
{
while (mplay_message_receive(0))
{
from = mplay_message_player();
name = mplay_message_name();
messid = mplay_message_id();
val = mplay_message_value();
if (messid == 1)
{
// do something
}
else if (messid == 2)
{
// do something else
}
// etc.
}
}
Внимателното проектиране на протокола за връзка, който се ползва (т.е. определянето кои съобщения от кого и в какъв момент, и как останалите трябва да реагират на тези съобщения) е изключително важно.
Опита и изучаването на примери, направени от други, помагат много..
Dead-reckoning
ping-pong играта, описана по-нагоре, има сериозен проблем. Когато има забавяне във връзката, топката на клиента временно ще замръзне. Не пристигат нови координати и следователно тя не мърда. Този проблем възниква в частност когато разтоянието между компютрите е много голямо и/или връзката е бавна. Когато игрите стават по-сложни, ще имате нужда от повече стойности за да опишете състоянието на играта. Когато променяте множество стойности във всеки кадър, много информация трябва да бъде предадена. Това може да изисква много време, забавяйки вашата игра или карайки нещата да губят синхронизация.
Първия начин да направите синхронизацията чрез поделена информация по-бърза е да не използвате гарантирано предаване на информацията. Това може да се осъществи чрез използване на фунцкията:
•mplay_data_mode(guar) определя дали да се използва гарантирано предаване на поделената информация. guar трябва да бъде true (по подразбиране) или false.
По-добър метод за решаването на този проблем е така наречения dead-reckoning. При него се изпраща информация само от време на време. В интервалите между отделните съобщения играта сама предполага какво се е случва на базата на информацията, която има.
Сега ще използваме това в нашата ping-pong игра. Вместо да изпращаме позицията на топката при всеки кадър, ние ще изпращаме още информация за нейната позиция и посока. Така клиента ще може да извърши повечето от пресмятанията сам. Докато не пристига нова информация от сървъра, клиентът просто ще пресмята къде се премества топкара.
В този случай няма да използваме поделена информация. Вместо това ще използваме съобщения. Ще използваме съобщения, определящи промяната в позицията на топката, нейната скорост, позицията на ракетата и т.н. Сървърът изпраща подобни съобщения винаги, когато нещо се промени. Контролния обект на клиента чака за съобщения и настройва правилните параметри. Но ако клиента не получава нищо, той все още премества топката. Ако той направи малка грешка, по-късно съобщение от сървъра ще коригира позицията. Така, например, в събитието Step на топката можем да сложим следния код:
{
if (!global.master) exit;
mplay_message_send(0,11,x);
mplay_message_send(0,12,y);
mplay_message_send(0,13,speed);
mplay_message_send(0,14,direction);
}
В събитието Step на контролния обект използваме следния код:
{
while (mplay_message_receive(0))
{
messid = mplay_message_id();
val = mplay_message_value();
// Check for bat changes
if (messid == 1) bat_left.y = val;
if (messid == 2) bat_right.y = val;
// Check for ball changes
if (messid == 11) object_ball.x = val;
if (messid == 12) object_ball.y = val;
if (messid == 13) object_ball.speed = val;
if (messid == 14) object_ball.direction = val;
// Check for sounds
if (messid == 100) sound_play(val);
}
}
Забележете че не е необходимо съобщението да се изпраща в гарантиран режим. Ако се пропуска някое от време на време, това не е сериозен проблем. Можете да намерите адаприраната игра във файла pong2.gmd.
Сега ще бъдете разочаровани, когато пуснете играта pong2. Все още има асинхронизация. Какво я предизвиква? Причината е, че предаването може да е бавно. Това означава че клиента може да получава съобщения, изптатени малко по-рано. В резултат той ще върне позицията на топката обратно и тогава, когато получи новото съобщение - отново ще я сложи по-напред.
Затова нека направим трети опит, който ще намерите във файла pong3.gmd. Този път ще разменяме информация единствено, когато топката удари ракета. Останалата част от движението се осъществява чрез използването на dead-reckoning. Сървъра е отговорен за това, което се случва от страната на ракетата на сървъра и клиента - за това, което се случва от другата страна. Докато топката се движи от едната до другата страна не се разменят съобщения. Както можете да видите, топката сега се движи гладко. Само когато тя удря ракета кратко забавяне може да се види или топката може да започне движението си преди да е достигнала до ракетата на противника. Причината е, че този метод предполага, че двете игри вървят с една и съща скорост Ако единия от компютрите е бавен, това може да предизвика проблем. Но прескачене при ракетата е много по-приемливо отколкото прескачания по време на движение. За да избегнете последния проблем, трябва да използвате по-сложен метод. Например бихте могли да изпращате информация за времето, така че всяка страна да знае колко бързо върви играта на другия компютър и да направи съответните корекции.
Надявам се сега разбирате колко трудна е синхронизацията. Може би също така ще започнете да оценявате как комерсиалните игри го постигат. Те трябва да се справят с абсолютно същите проблеми.

Програма за чат
Като наша втора демонстрация ще направим малка програма за чат. Тук ще позволим произволно количество играчи. Освен това ще позволим множество сесии и ще дадем възможно на потребителя да избере една от тях. Ще използваме съобщения с низове за да предадем написания текст.
Тук използвам малко по-сложен метод за създаване на връзка. Първото ниво сега има четири варианта за четири различни типа връзка. Но то не създава връзката. Вместо това то само записва съответната стойност в глобалната променлива connecttype. На второто ниво играчът може отново да избере дали да създаде игра (фактически чат-стая) или да се присъедини към вече съществуваща. Чак тогава връзката е създадена. В зависимост дали играча създава или се присъединява към игра, няколко въпроса се задават.
След като връзката е създадена успешно, играча създава или се присъединява към сесията. Този път играчът се пита за име his/her за да може да бъде идентифициран. Частта по присъединяването е доста по-сложна. Създава се меню с всички достъпни сесии, така че играчът да си избере една от тях.
Обикновено, когато играта, създала сесията, свърши и сесията се приключва. За чат програма това не е желателно. Останалите играчи трябва да имат възможността да продължат да чатят. Това може да се промени чрез функцията:
•mplay_session_mode(move) определя дали да премести сървъра на сесията на друг компютър ако текущия прекрати връзката. move трябва да е true или false (по подразбиране).
Вероятно ще искате да преизползвате в своите игри цялостния механизъм на първите две нива, тъй като той често е до голяма степен същия.
След това преминаваме на нивото, представящо чат-стаята. Там има само един контролен обект, който извършва цялата работа. Няма да обяснявам детайлите за това как се дава възможността на потребителя да пише тект и показването на последните няколко реда. Всичкото е сложено в няколко скрипта, така че можете да го използвате ако искате. Всичко е много просто (ако знаете как да програмирате на GML). Единствената част, която представлява интерес е, че всеки път, когато играчът натисне Enter, написания текст се предава на всички останали играчи, предхождан от името на играча. Освен това, когато играчът се присъединява или излиза, той изпраща съобщение на останалите играчи, показващо какво е направил.
Заключение
Мрежовата поддръжка в Game Maker прави възможно създаването на хубави мрежови игри. Функциите обаче само ви помагат с комуникацията от ниско ниво. Трябва сами да проектирате механизма на комуникация, който да се използва. Това трябва да се прави внимателно. Трябва да се проектира докато се проектира и самата игра. Много е трудно да се добави ефективна мрежова поддръжка по-късно. Ето няколко общи принципи:
•За по-прости игри master-slave метода е най-лесен
•Внимателно проектирайте кой за каква информация е отговорен
•Използвайте dead-reckoning винаги, когато е възможно
•Опитайте се да разчитате колкото се може по-малко на гарантираното предаване




/ Трябва да сте регистриран за да напишете коментар /