Урок по стандартному плагину Multiplayer

другие уроки, мануалы, советы по Construct 2

Сообщение Урок по стандартному плагину Multiplayer
» 11 янв 2016, 19:00

 Делаем подключение к серверу Scirra и создаем лобби
Уроков по стандартному плагину мультиплеер на форуме не находил, поэтому написал свой. Создавать мультиплеер не так уж и легко, как хотелось бы. Урок рассчитан на уже знающих основы констракта. Чтобы не загружать много скринов я брал кучку эвентов в одном скриншоте и пояснял последовательно.
Для начала создаем лайоут, его размеры не важны, создаем еще один слой Rooms, а первый называем Login. Добавляем на слой Login три объекта, это объект Text называем его TextInfo, второй объект Text box называем его TextLogin, и еще кнопку ButtonLogin. Текстбокс и кнопку ставим изначально на Disabled.
Изображение
Переходим в таблицу эвентов, и добавляем глобальную переменную GAMENAME, добавляем ей свойство Constant, Type ставим Text, и Initial Value пишем на английском Ваше имя(компания)-Название игры (так рекомендует скирра, чтобы не перепутать вашу игру с другой), по этой переменной будет идентифицироваться ваша игра на сигнальном сервере скирры.
Изображение
При старте сцены игра подключается к сигнальному серверу скирры, и выводится текст что игра подключается.
Изображение
Когда игра подключилась к серверу выводится текст "Подключено!" и активируются кнопка и текстовое поле. Добавляем еще условие как на скриншоте.
Изображение
Все описание условий есть на скриншоте.
Изображение
На слой Lobby добавляем объекты List, Textbox с названием TextRoomName, ну и кнопку ButtonCreateRoom. Выглядить будет примерно так:
Изображение
Если игрок вошел на сервер со своим именем тогда активируем слой 1 (лобби), а также запрашиваем список всех созданных комнат игры.
Изображение
В строку Game вводим переменную с названием игры, Instance ставим на default, а в параметре Which выбираем какие комнаты будем запрашивать, all – все, unlocked-открытые,available- те комнаты к которым игрок может подключиться.
Изображение
Когда от сервера приходит “свежий” список комнат, очищается наш лист и заполняется по новой. Не забудьте добавить условие которое ниже. Чтобы добавить много комнат обязательно нужен Repeat, чтобы знать сколько раз повторить берем выражение Multiplayer.ListRoomCount т.е. число комнат.
Изображение
При нажатии на кнопу "Создать комнату" и текстовое поле не пустое, тогда создается новая комната.
Создание комнаты:
Изображение
Game – вставляем переменную с названием игры. Instance оставляем на Default, Room – название комнаты, берем его из текстбокса, Max peers – максимальное количество игроков. Я поставил на 20.
Изображение
Подсоединение к комнате:
Изображение
Game – вставляем переменную с названием игры. Instance оставляем на Default, Room – название комнаты, берем его из листа с комнатами, Max peers – оставляем на нуле, так как игрок подключается не к своей комнате он не может регулировать максимальное количество игроков .
Добавьте уровень на котором будут проходить основные онлайн действия игры. У меня он называется Game. На нем и сделаем чат.

 Простой чат
В стандартном мультиплеере хост (игрок который создал комнату и вошел в неё первым) выполняет функции сервера для пиров (игроки которые подключились к игре после хоста), соответственно если хост отключится то и удалится комната и игроки не смогут синхронизироваться между собой. Мультиплеер работает по принципу: пир отправляет данные хосту , хост обрабатывает данные и пересылает эти данные всем пирам.
На уровне Game создаем 2 текстбокса, 1 называем ChatBox, а 2 SendBox и еще 2 кнопки ButtonSend(отправить), и ButtonLeaveRoom(покинуть комнату). У объекта Chatbox нужно изменить параметры, Read Only ставим на Yes и Type на TextArea. Получается как то так:
Изображение
Создаем три группы: Host, Peer, Common. У групп хост и пир снимаем галочку с Active on start. В группе хост будут происходить действия для хоста, в группе пир для пиров, а в коммон общие действия.
Создаем в общей группе вот такие условия:
Изображение
При старте уровня, проверяется, если вы хост то активируется группа хост, если нет то группа пир, вписывается в чатбокс текст что вы подключились к такой то комнате. Если вы нажали на кнопку покинуть комнату то игрок отсоединяется от комнаты. Если вы вышли из комнаты то происходит переход на уровень логин.
События для группы пир:
Изображение
Если нажата кнопка ентер или клик мыши по кнопке и текстовое поле не пустое, то тогда отправляем хосту текст из SendBox с тегом “Chat”(mode ---> оставляем как есть), добавляется текст в ChatBox(ChatBox.Text&newline&"["&Multiplayer.MyAlias&"]"&SendBox.Text ----> Multiplayer.MyAlias это ваше имя, которое будет находится в квадратных скобках, вся эта стрепня нужна для приведения вашего чат примерно в такой вид [Ник]Всем привет!) из SendBox, SendBox соответственно очищается.
Изображение
Когда мы получаем сообщение с тегом Chat
Изображение
Итак игрок передал данные хосту, теперь их нужно обработать и передать всем остальным. Для транслирования сообщения всем от хоста используется действие Broadcast Message. Создаем это все в группе хоста.
Изображение
Когда приходит сообщение от пира с тэгом «Чат» , хост транслирует сообщение всем кроме отправителя.
Изображение
From ID – идентификатор отправителя, если оставить пустым то сообщение будет передаваться всем, даже отправителю, но нам надо именно с идентификатором, для этого пользуемся командой Multiplayer.FromID. Tag – ставим на “Chat” . Message – на Multiplayer Message, Mode – оставляем как есть. (Функция Mode вообще отвечает за быстроту и надежность доставки сообщений, Reliable Ordered – самый надежный, соответственно другие варианты быстрее но фиг его знает дойдет ли). Вторым действием добавляем в чатбокс хоста данные сообщения.
Изображение
Если нажат Enter или клик мыши и текстовое поле не пустое тогда транслируем всем по тегу «чат» текст СендБокса хоста и FromID ставим на Multiplayer.MyID .А также добавляем текст в ЧатБокс из СендБокса, затем текстовое поле очищается.
Добавим еще 2 условия в группу коммон. Эти условия нужны для того что бы в чате показывалось, если игрок подключился/отключился то выводится сообщение что он онлайн/оффлайн.
Изображение
Multiplayer.PeerAlias – имя пира. Только учтите если хост отключится то работать ничего небудет. Так что добавьте к On peer disconnected подусловие System --->Compare two values---> First Value ставим на Multiplayer.PeerID а Second Value на Multiplayer.HostID знак ставьте на равно, добавляем действие ChatBox ---> Set text--->”Хост отключился!”. Если отключился пир с идентификатором хоста (т.е. хост отключился) выводим текст в чатбокс что хост отключился. Ну а дальше можете сделать переход на уровень Login чтобы зайти в другую комнату.

 Синхронизация объектов, онлайн игра
В синхронизации объектов есть несколько методов, здесь я только описал передачу сообщений, 2 метод описать навряд ли смогу.
Если вам игра нужна с чатом, то просто перенесите все элементы чата на другой отдельный слой.
Оставляем те же самые три группы.
Прежде всего создаем спрайт Player(Добавьте ему переменные Health(тип number) и ID(тип text)и поведение Drag’nDrop, изначально Drag’nDrop ставим на Disabled), Bullet(добавьте переменную ID(тип text), поведение Bullet) и текст PeerInfo(добавьте переменную ID(тип text)).
С помощью переменной ID будем идентифицировать каждого игрока.
Начинаем с активации групп и присваивания идентификатора. Также устанавливаем текст с ником и здоровьем над каждым игроком. Все эти условия добавляем в группу Common. Если ид PeerInfo равен иду Player, тогда текст устанавливается над игроком. Multiplayer.PeerAliasFromID – означает Мультиплеер.ИмяПираИзИдентификатора, идентификатор нам известен, он находится в переменной объекта Player, записывается ид рядом в скобках Multiplayer.PeerAliasFromID(Player.ID). При старте сцены объектам Player и PerInfo присваивается наш ид, и перемещаем объект Player на рандомную позицию(не обязательно). Если игрок хост/пир включается соответствующая группа.
Изображение
Если пир подключен (On peer connected) к комнате то для него создается объект Player и PeerInfo и им присваивается соответствующий идентификатор. Если пир отключился (On peer disconnected) то объекты Player и PeerInfo с его идентификатором уничтожаются. Если отключился пир с идом хоста (соответственно хост отключился) тогда выводим текст что хост отключился (если хост отключился, о синхронизации не может быть и речи, нужно делать либо переход на уровень лобби, либо перезапускать игру, это решайте сами) .
Немного о выражении Multiplayer.PeerID - это ид какого либо пира меняющееся от условия, если будет условие On peer connected то это выражение будет вам выдавать ид подключенного игрока, с условием On peer disconnected выражение будет работать наоборот, т.е выдавать ид отключенного игрока.
Все эти условия добавляем в группу Common.
Изображение
В группу Common осталось добавить только эвенты соприкосновения пули с плейром и действия когда здоровье плейра становится равно нулю. Итак сделаем условия чтобы при соприкосновении с вражеской пулей у нашего игрока отнималось здоровье. При соприкосновении пули с плейром, проверяем вражеская ли это пуля по идентификатору, если ид пули не равен иду плейра тогда ее уничтожаем(это условие нужно чтобы при соприкосновении пули с чужими игроками она уничтожалась), если ид пули не равен нашему, а ид игрока равен нашему, тогда пулю уничтожаем и отнимаем 5 от переменной здоровья. Если переменная здоровья меньше или равно нулю тогда просто перемещаем объект на рандомную позицию, и устанавливаем переменной число 100 по новой (т.е если у игрока закончилась жизнь, его жизнь восстанавливается и он просто перемещается в другое случайное место).
Изображение
Теперь переходим к группе Peer. Если ид Player равен нашему, значит это наш объект. Добавьте плагин мыши. Если это наш игрок то Drag’nDrop активируется и мы можем двигать только нашем объектом. Каждые 0.05 секунд игра будет отправлять хосту наши данные с тэгом PlayerInfo, а именно расположение Player по Х и У, и значение переменной Health (здоровье), все это нужно прописать через разделитель (сепаратор), я выбрал для этого вертикальную палку, это нужно для того чтобы разобрать сообщение с помощью tokenat.
Изображение
Multiplayer.HostID – выражение возвращает нам идентификатор хоста. Правая кнопка мыши будет у нас для выстреливания. Если нажата правая кнопка мыши, отправляем хосту сообщение с тегом SpawnBullet с углом пули, преобразовываем его в строку с помощью приставки str(). Так как сообщение передает только строковые значения (текст). Также спавним пулю, и присваиваем ей наш идентификатор.
Изображение
Мы смогли отправить наши данные, теперь нужно принять и обработать данные от других игроков. Теперь обработаем сообщения которые придут пиру от других, чтобы у нас объекты остальных игроков тоже перемещались. Когда принимаем сообщение с тегом PlayerInfo, устанавливаем положение объекта Player и количество здоровья (переменная Health) с идентификатором отправителя (Multiplayer.FromID)
Изображение
Чтобы обработать сообщение, воспользуемся tokenat, эта функция разбивает строку на части и возвращает нам нужную. Tokenat (Данные, Индекс, Разделитель). Данные у нас это Multiplayer.Message, индекс это номер тех данных которые нужно запросить начиная от нуля (например если индекс будет 0, тогда нам придут данные с Player.X, если индекс = 1 тогда Player.Y и т.д.), и разделитель (сепаратор) это символ который разделяет данные на части, у нас это вертикальная палка“|”. Не забудьте поставить приставку int(), она преобразовывает наши данные из строковых в числовые.
Если приходит сообщение с тэгом SpawnBullet, тогда спавним пулю с углом из переданных нам данных Multiplayer.Message возле объекта Player с идентификатором отправителя.
Изображение
Итак, что мы сделали, когда мы перемещаемся, стреляем, тогда отправляются данные с углом пули, значением переменной Health и расположением объекта Player под разными двумя тэгами. Мы также можем принимать данные, и устанавливаем эти данные для нужных объектов. Мы передаем данные только хосту, но нам надо чтобы данные передавались всем. Вот теперь перейдем к группе Host.
Host тоже принимает эти данные как пир, но единственное различие то что он передает эти данные всем, с помощью действия Broadcast Message.
Изображение
Также принимаем сообщения по тэгам и устанавливаем эти значения объектам с идом отправителя. Этим двум условиям добавляем только Broadcast Message. FromID – ставим на Multiplayer.FromID, тэг – зависит к какому условию добавляете(посмотрите на скриншоте, к первому условию тег – PlayerInfo, для второго SpawnBullet), Message – на Multiplayer.Message (т.е. передаем те же данные всем что и передали хосту).
Осталось только добавить условия чтобы хост тоже мог стрелять и двигаться как все. Для передачи данных копируем эвент из группы пира в группу хоста и меняем только Send Message на Broadcast Message и FromID на Multiplayer.MyID.
Изображение
Что бы проверить игрушку открывайте не в двух разных вкладках браузера а в двух (или более) разных окнах.

Задавайте свои вопросы, по возможности отвечу.
ЛоббиЧат.capx
(179.04 КБ) Скачиваний: 278
Чат
Онлайн игра.capx
(183.2 КБ) Скачиваний: 526
Онлайн игра
Последний раз редактировалось RusM 11 мар 2016, 20:48, всего редактировалось 6 раз(а).
Разрабатываю мультиплеер для игр на заказ, обращайтесь в лс.
Аватара пользователя

Участник
Сообщений: 96
Я тут с 17 сен 2015
Двиг: C2
Лицензия: Personal
Репутация 32 [ ? ]

Сообщение Урок по стандартному плагину Multiplayer.
» 13 янв 2016, 01:21

RusM, Просто супер урок, таких вообще нет! Спасибо за бесценные уроки!)! :good: :good: :good: :good: :good:
Аватара пользователя

Участник
Сообщений: 8
Я тут с 13 янв 2016
Репутация 0 [ ? ]

Сообщение Урок по стандартному плагину Multiplayer.
» 13 янв 2016, 01:42

RusM, Сэнцэй))Скажи пожалуйста! Как сделать, если хост выходит из игры, то чтобы для других игроков игра продолжалась? То есть, при выходе из игры хоста, хост бы передавался другому игроку, и так до последенего участника игры! Извини сразу задам 2 вопрос, просто таких как ты мало, вот и хочется сразу всё спросить) Если создаю танк, башню к нему присоединяю отдельным спрайтом - у башни своё поведение( она следит за мышкой), а танк ездит, То в мультиплеере придётся прописывать события к двум спрайтам(танку и башне-которая стреляет). Или как? Заранее спаибо огромное!)!
Аватара пользователя

Участник
Сообщений: 8
Я тут с 13 янв 2016
Репутация 0 [ ? ]

Сообщение Урок по стандартному плагину Multiplayer.
» 13 янв 2016, 01:47

RusM, Да и ещё, А вот ваш исходник расчитан на сколько человек в каждой комнате( сколько одновременно могут подключиться к одной комнате)?
Аватара пользователя

Участник
Сообщений: 8
Я тут с 13 янв 2016
Репутация 0 [ ? ]

Сообщение Урок по стандартному плагину Multiplayer.
» 13 янв 2016, 12:24

qwe14 писал(а):Как сделать, если хост выходит из игры, то чтобы для других игроков игра продолжалась? То есть, при выходе из игры хоста, хост бы передавался другому игроку, и так до последенего участника игры!


Такой функции к сожелению в движке нет (По крайней мере я не находил). Отключился хост = удалилась комната.

qwe14 писал(а):Если создаю танк, башню к нему присоединяю отдельным спрайтом - у башни своё поведение( она следит за мышкой), а танк ездит, То в мультиплеере придётся прописывать события к двум спрайтам(танку и башне-которая стреляет).

Скорее всего нужно добавить к танку и башне переменную с идентификатором.
И обязательно добавь чтобы соответствующему игроку присваивался свой ид.
Сделай события для передачи позиции танка и угла башни. (Танк.X&"|"&Танк.Y&"|"&Башня.Angle)
При принятии сообщения устанавливай с помощью токената позицию танка и угол башни для игрока с его идом. В моем примере можно посмотреть как я установил над каждым игроком текст с его данными. Ты сделай так чтобы башня устанавливалась к своему танку с помощью ид на примере текста с данными.
qwe14 писал(а):Да и ещё, А вот ваш исходник расчитан на сколько человек в каждой комнате( сколько одновременно могут подключиться к одной комнате)?

Движок с2 не накладывает лимита на количество игроков подключаемых к комнате. Ты можешь регулировать его сам. Посмотри повнимательней урок в разделе где я создавал лобби. Там при нажатии кнопки создавалась комната, вот в этом действии можно регулировать кол. игроков.
Если будет слишком много игроков то будет большая нагрузка на хоста, соответственно есть риск что будут лаги.
Разрабатываю мультиплеер для игр на заказ, обращайтесь в лс.
Аватара пользователя

Участник
Сообщений: 96
Я тут с 17 сен 2015
Двиг: C2
Лицензия: Personal
Репутация 32 [ ? ]

Сообщение Урок по стандартному плагину Multiplayer.
» 13 янв 2016, 14:30

Огромное вам спасибо за помощь! Очень помогли! А, если я игру выкину на платный хостинг, то при выходе игрока(хоста), всё равно будет заканчиваться игра?
Аватара пользователя

Участник
Сообщений: 8
Я тут с 13 янв 2016
Репутация 0 [ ? ]

Сообщение Урок по стандартному плагину Multiplayer.
» 13 янв 2016, 14:43

И ещё вопросик)))Как сделать рандом в мультиплеере? Например, что бы при каждом заходе игры выбирался разный танк(сначала играешь - зелёным - проиграл, снова начал игру - уже танк другого цвета!) Просто я делал рондом, но у меня только у хоста разные цвета выбираются, а у пиров всегда один! Не могу понять, что не так сделал!
Аватара пользователя

Участник
Сообщений: 8
Я тут с 13 янв 2016
Репутация 0 [ ? ]

Сообщение Урок по стандартному плагину Multiplayer.
» 13 янв 2016, 15:23

qwe14 писал(а):Огромное вам спасибо за помощь! Очень помогли! А, если я игру выкину на платный хостинг, то при выходе игрока(хоста), всё равно будет заканчиваться игра?

Я никогда к платному хостингу не подключался, так что этого я не знаю. Я думаю что скорее всего да, это все зависит от самого плагина Multiplayer, ибо в нем нет соответствующей функции для передачи хоста другим игрокам.
qwe14 писал(а):И ещё вопросик)))Как сделать рандом в мультиплеере? Например, что бы при каждом заходе игры выбирался разный танк(сначала играешь - зелёным - проиграл, снова начал игру - уже танк другого цвета!) Просто я делал рондом, но у меня только у хоста разные цвета выбираются, а у пиров всегда один! Не могу понять, что не так сделал!

Добавь танку переменную, назови ее например Colour. При старте уровня (либо же при проигрыше) сделай действие чтобы переменной присваивалось случайное значение (выражение random (цифра)) например от 0 до 3 round(random(3)) (round это округлитель, а то рандом может вытаскивать не целые числа). Добавь условия, если переменная Colour = 3 ----> цвет танка серый, Colour=2 ---> цвет танка красный и т.д. Теперь просто передавай данные со значением переменной Colour(с передачей думаю сам разберешься).
Разрабатываю мультиплеер для игр на заказ, обращайтесь в лс.
Аватара пользователя

Участник
Сообщений: 96
Я тут с 17 сен 2015
Двиг: C2
Лицензия: Personal
Репутация 32 [ ? ]

Сообщение Урок по стандартному плагину Multiplayer.
» 13 янв 2016, 16:20

Спасибо вам!)!
Аватара пользователя

Участник
Сообщений: 8
Я тут с 13 янв 2016
Репутация 0 [ ? ]

Сообщение Урок по стандартному плагину Multiplayer.
» 13 янв 2016, 17:26

В 1 спойлере скрин был перепутан, исправил, так что еще раз посмотрите.
Последний раз редактировалось RusM 14 янв 2016, 10:41, всего редактировалось 4 раз(а).
Разрабатываю мультиплеер для игр на заказ, обращайтесь в лс.
Аватара пользователя

Участник
Сообщений: 96
Я тут с 17 сен 2015
Двиг: C2
Лицензия: Personal
Репутация 32 [ ? ]



Вернуться в Другие уроки по Construct 2

Сейчас эту тему просматривают

Зарегистрированные пользователи: нет зарегистрированных пользователей

Наверх