Multiplayer chat room[Перевод]

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

Сообщение Multiplayer chat room[Перевод]
» 24 апр 2014, 22:00

 Примечания
C2 - Construct 2
layout - макет уровня(редактор, где мы размещаем наши объекты и прочее)
text box (текст бокс) - поле ввода текста
хост - тот кто создал комнату для игры
пир - тот кто зашёл в комнату хоста
ретрансляция - отправка полученных сообщений. Есть специальное действие ретрансляции для хоста Broadcast


Данный туториал предусматривает, что вы уже читали введение в мультиплеер.

Самое лёгкое введение в мультиплеер это реализация обычного чата. Реализация чата связана лишь с подключением и входом в комнату, входом и выходом других пиров, трансляцией сообщений в чат. Некоторые из более сложных вопросов, таких как прогнозирование нажимаемых клавиш и компенсации запаздывания здесь просто не нужны, так как у нас нет ни одного объекта под управлением игрока. Они будут рассмотрены в следующем уроке, а сейчас мы можем сосредоточиться на основах и сообразить что-нибудь полезное. Чтобы начать, откройте Example: Multiplayer - chat room example, который поставляется вместе с C2. Его вы можете найти открыв диалог File > New. Данный пример прокомментирован, однако туториал позволит вам переходить от событий к событиям и понять всё в мельчайших деталях, ведь всё же некоторые из особенностей организации чата могут потребовать больше объяснений, нежели в обычных комментариях.

Запуск и тестирование

Протестируйте имеющийся пример чата, вам лучше запустить его с первого layout(F4). Если вы запустите сразу же layout "Chat", то чат не будет работать, так как у вас нет логина, который нужно ввести в layout "Login".
Когда вы будете тестировать примеры мультиплеерных игр, вы возможно встретите другого пользователя, у которого возможно уже тоже будет включена игра в этот момент. Однако скорее всего этот пользователь отошёл от клавиатуры ("away from keyboard", AFK) или просто оставил всё запущенным и забыл. Так что не удивляйтесь тому, что он не реагирует на ваши сообщения в чате. Если таки не получится найти кого-нибудь активного в чате, вы можете позвать друзей, чтобы они протестировали чат вместе с вами.
Также возможно, что кто-то уже будет хостить чат, но вы не сможете к нему подключиться по каким либо причинам(скорее географическим). Если такое произойдёт, то попробуйте изменить название игры, версию или комнату, чтобы хостануть игру чисто для себя.

Layout "Login"

Первый layout, "Login", не требует сильных объяснений. По существу, там только текст бокс и кнопка "Join"(войти). Введённое имя сохранится в глобальную переменную и ничего особого больше не произойдёт, до следующего layout'а. События просто нацелены исключительно на текст бокс, чтобы ты не мог подключиться к чату не введя себе логин, который в дальнейшем сохранится в глобальную переменную MyUsername по нажатию кнопки "Join". Ах да! также в событиях есть условие, которое проверяет, поддерживает ли браузер WebRTC. К сожалению, не все браузеры поддерживают WebRTC и, если очередной пользователь натолкнётся на эту проблему, его необходимо информировать об этом.

layout "Chat"

Во время действий события On Start of layout мы подключаемся к чату, используя сохранённый ник-нейм в глобальной переменной MyUsername.
Объекты в layout'е расположены таким образом, чтобы в целом они представляли обычный чат, который включает в себя: главный ChatLog, в котором показываются сообщения, PeerList - список других участников чата, text box для ввода сообщения и кнопка "send", чтобы отправить его.
В событиях мы будем иметь дело с:
-подключением к сигнальному серверу и входом в него под своим логином
-входом в чат-комнату
-списком тех, кто находится в комнате и обновлением списка с учётом пришедших и ушедших участников чата
-показом транслированных сообщений
-отправкой сообщений
-ошибками и различными disconnect'ами
Что ж приступаем.
События чата
Сверху нашего листа событий мы видим несколько глобальных переменных:

Изображение

Весьма удобно иметь глобальные константы для названия игры, её версии и названия комнаты на сервере, если они никогда не изменяются в событиях. Они всегда находятся в удобном месте и если нам понадобиться их изменить мы всегда знаем, где они находятся.*От меня: константы не изменяются по мере выполнения кода игры, поэтому их начальное значение можно спокойно изменять, зная что оно само не поменяется во время игры*. Любой кто использует идентичные константы, что и у вас он подключится в общий с вами чат. Если вы захотите создать отдельный чат, разумнее изменить именно комнату на сервере сигнализации, ведь версия игры и название игры всегда должны соответствовать названию и версии проекта.

Группа событий "Chat log"

Изображение

Группа содержит только функцию, которая просто добавляет новую строчку в тексте чат-лога и скролит его вниз. Если обновлять чат вручную, то мы будем использовать много лишнего места, поэтому мы воспользовались функцией, которая убирает лишнее повторение одних и тех же действий в разных событиях. Также после нескольких сообщений, содержание текста в чат-логе может сместиться, поэтому мы скроллим чат вниз, чтобы всегда видеть новые сообщения.

Группа событий "Signalling"

Эта группа связана с сигнальным сервером. Здесь мы будем подключаться к сигнальному серверу и проверять есть ли кто в комнате, проверять возможность подключения к ним и в ином случае хостить чат самостоятельно. Сначала нам нужно подключиться к сигнальному серверу, который официально поставляется Scirra wss://multiplayer.scirra.com . (Каждый этап входа в чат прописывается в чате, поэтому пользователям будет понятен процесс происходящего)

Изображение

Спустя мгновение, мы, предполагая, что всё прошло удачно, приступаем к триггеру On signalling connected. Однако сервер не позволит нам войти в какую-либо игру без логина. При подключении к сигнальному серверу, мы запрашиваем у него вход именно с введённым логином на layout'e "Login"

Изображение

В случае, если запрос на вход в сигнальный сервер под введённым логином прошёл успешно, мы переходим к триггеру On signalling logged. Теперь мы готовы войти в игру. Обратите внимание, что, если запрашиваемый псевдоним уже используется на сервере сигнализации, он может просто назначить вам новый псевдоним. Для примера возьмём двух пользователей с ником "Joe", второй подключившийся пользователь получит ник "Joe2". Чтобы избежать путанницы, будет хорошей идеей показать вошедшему пользователю его логин. Чтож теперь мы вошли в игру и мы готовы войти в соответствующую нашим глобальным константам комнату.

Изображение

После входа в комнату, нам в чат-логе напишут, являемся ли мы хостом комнаты или нет. Сигнальный сервер делает так, что первый человек в комнате - становится хостом. Фактически хост является средством обмена данных между другими пользователями в комнате(он действует, как сервер игры). Мы проверяем, стали ли мы хостом или нет в под-событиях триггера On signalling joined. Так как хост(лицо действующее, как сервер игры) и пир(лицо действующее, как клиент) пользуются одним и тем же приложением, нам следует организовать события для них в виде двух различных групп событий: группа Host и группа Peer. Обе эти группы изначально деактивированы, но после подключения мы активируем необходимую нам группу, в соответствии с нашим статусом. Это означает, что события для хоста и пиров будут удобно организованы. Мы также добавим себя в список участников чата, т.к. мы не получаем уведомление "peer joined ..." для себя(подробнее про уведомление читайте в группе Common).

Изображение

Последние три события в группе Signalling просто для обработки ошибок. В большинстве случаем выше описанные события работают нормально, однако если мы выйдем из комнаты, отключимся от сигнального сервера или столкнёмся с ошибкой на сигнальном сервере, система выведет сообщение пользователю о случившемся.

Изображение

Эта группа включила в себя подключение к сигнальному серверу, вход в комнату и активацию пользователю группу соответствующую его статусу(хост/пир). После того, как пользователь присоединился к игре, его данные обрабатываются уже через хоста. Оставшиеся события - разработка самого чата. Нас ждут ещё три группы чата: группа для хоста, для пира и общая группа.

Группа "Common" (Общая)

Группа Common всегда активна, она содержит общие события для пира и хоста. Это еще один разумный способ организовать структуру кода, без необходимости дублирования одинаковых событий между группами Peer и Host.
Когда кто-либо подключится в комнату, наша система запускает триггер On peer connected. В этом событии выражение Multiplayer.PeerAlias показывает нам псевдоним подключившегося. Здесь мы уведомляем остальных о том, что пользователь подключился и добавляем его в список участников разговора. Внимание сам подключившийся не получает этого уведомления! Другими словами, если пять человек уже находятся в комнате, когда ты подключился, то триггер On peer connected will выполняется исключительно для этих пяти человек.

Изображение

Когда кто-либо вышел из чата, запускается триггер On peer disconnected. Также, как и в подключении, Multiplayer.PeerAlias показывает имя того, кто вышел. Единственное небольшое осложнение в этом событии - удалить ник ушедшего пользователя из списка участников разговора. Чтобы убедиться, что ник вышедшего удалён из списка участников, мы запустим проверку каждого пункта списка; если в списке найдётся ник-нейм вышедшего участника, то мы просто удалим этот ник-нейм.

Изображение

Наконец, мы обрабатываем кик(kick) пользователю. Kick означает то, что мы были выгнаны из чата, без нашего согласия. Обычно это происходит по одной из двух причин. Первая причина: если хост выйдет из игры, игра обрывается, т.к. до этого её поддерживал хост. Вторая причина: если мы не можем подключиться к хосту в течение определённого периода, нас тут уже кикает сам сигнальный сервер. Некоторые типы NAT не дают пользователям подключится к хосту, заставляя их тупо сидеть и пытаться подключиться, что будет выходить всегда безуспешно. Тайм-аут сервера сигнализации (по умолчанию 20 секунд) означает то, что вы по крайней мере получите возможность присоединиться в другую игру, или повторите попытку.

Изображение

Группа "Peer"

Группа Peer активна только в том случае, если мы являемся пиром(не хостом). Заметим, что в этом случае мы связаны только с хостом - нет соединения непосредственно между другими пирами. Хост выступает в качестве сервера, так что если два пира хотят общаться, их сообщения будут отправляться к хосту, а уже потом от него передаваться их собеседникам. Эти действия выполняются в группе Host, всё что нам нужно здесь: отправка и получение сообщений.
В первую очередь, если мы нажмём кнопку "Send" или клавишу Enter, а поле для ввода будет не пустым, то мы добавляем текст нашего сообщения в наш чат-лог и отправляем его хосту с тегом "Chat" и режимом reliable ordered (используем действие Send message). Reliable order - режим, заставляющий отослать информацию снова, если она будет утеряна. Мы не желаем использовать недостоверный режим(ваше сообщение возможно никогда не придёт) и достоверный, но не упорядочный режим, так как сообщение может задержаться и дойти до собеседника в неподходящий момент и возможно изменить смысл разговора. Тег для сообщений - простой способ сортировки различных типов сообщений. Например сообщения с тегом "Chat" в данном случае являются для общего чата, но другой тег "Private message" может быть использован для сообщений в приватном чате. Также отметим, что в качестве адреса отправки, мы оставляем параметр (Peer ID) пустым, чтобы отправить его хосту, так как у него нет PeerID.

Изображение

Приём сообщений очень прост. Когда сообщение с тегом "Chat" мы запускаем действия, относящиеся к триггеру On peer message "chat". В этом случае мы просто добавляем в чат-лог имя отправителя (выражением Multiplayer.FromAlias) и сообщение, которое он отправил (Multiplayer.Message). Помните, что отправитель не получает своих сообщений от хоста, поэтому мы добавили действие для вывода своего сообщения в чат в событии отправки сообщения.

Изображение

Группа "Host"

Группа Host схожа с группой Peer, но теперь мы общаемся со всеми пирами. Когда пир посылает сообщение, он передаёт его только хосту. Однако когда хост посылает сообщение, он транслирует его каждому пиру. Это делается с отдельным Broadcast действием который может быть использован только хостом. Также вместо указания получателя, мы указываем отправителя, что полезно для пересылки сообщений(ретрансляции) от одного пира другим. В этом случае мы оставляем From ID пустым, чтобы указать, что это сообщение от хоста.

Изображение

Наконец, мы перешли к ключевой части части чат-комнаты: ретрансляция. Когда хост получает "Chat" сообщение, мы добавляем его в окне чата так же, как это делают пиры. Однако если бы мы оставили все как есть, у нас был бы странный чат: пиры будут получать только сообщения, отправленные от хоста, в то время как сам хост может видеть сообщения от всех. Для того, чтобы пиры видели сообщения других пиров, хост должен ретранслировать сообщения на всех остальных. Поэтому, когда хост получает сообщение в чате, он также передает его, так все остальные пиры тоже будут его получать. Каждый пир имеет уникальный Peer ID, назначенный сигнальным сервером, и может быть использован для обозначения отправителя данных. Как и в случае выражения FromAlias, в "On peer message" выражение Multiplayer.FromID получает ID пира от которого пришло сообщение. Поэтому, когда хост ретранслирует сообщение, это означает, что оно на самом деле от пира. Это означает, что когда другие пиры получают сообщение и срабатывает триггер "On peer message", сообщение появляется, как от первоначального, посылаемого пира, а не от хоста. Другими словами сообщение исходит от хозяина, но мы видим его от имени пира-отправителя. Также обратите внимание, что хост не ретранслирует полученные сообщения каждому пиру, ведь было бы бессмысленно отправлять сообщение обратно отправителю. Так сообщение передается всем кроме первоначального отправителя.

Изображение

Заключение

На этом мы завершаем разработку чата в 26 событиях! Надеюсь, что теперь у вас есть хорошее понимание сигнализации, обработки пиров, входа и выхода, обмена сообщениями, и как настроить отдельные события для хозяина и пира.
Если вам стало интересно, вы можете попробовать реализовать приватный чат. В IRC это делается со слеша: "/pm SomeBody hello!". Хост должен был бы ретранслировать сообщение также, но уже не всем, а только определённому получателю. Наверное вы бы не хотели показывать всем свои личные сообщения!
Аватара пользователя

Игродел
Сообщений: 149
Я тут с 13 сен 2012
Откуда: у меня клавиатура?
Skype: voltermag
Репутация 30 [ ? ]

Сообщение Multiplayer chat room[Перевод]
» 02 май 2014, 20:47

полезная штука для оживления игр, остается только свой сервер для этих нужд реализовать, а не базовый )
Если помогли ? скажи спасибо нажав Изображение

Оптимизация проектов на С2 || ТОП рекордов Онлайн

Изображение
Аватара пользователя

Игродел
Сообщений: 329
Я тут с 18 апр 2014
Откуда: астрал
Репутация 46 [ ? ]

Сообщение Multiplayer chat room[Перевод]
» 13 май 2014, 09:13

Я таки решил сделать свой чат на основе этого урока. У меня есть друг, который согласился тестировать. В общем, после долгих поисков ответа на вопрос: почему же мы не видим сообщений своих оппонентов, я решил попробовать протестировать официальный пример. Как выяснилось, он тоже не работает: только вы можете видеть свои сообщения, никто другой не получает их от вас и ни от кого другого вам не придут сообщения. Однако, мы до этого тестировали пример мультиплеерного понга, который, на удивление, работал хорошо. Так что можно сделать чат, но другим способом.
Аватара пользователя

Игродел
Сообщений: 149
Я тут с 13 сен 2012
Откуда: у меня клавиатура?
Skype: voltermag
Репутация 30 [ ? ]

Сообщение Multiplayer chat room[Перевод]
» 30 июл 2014, 09:01

а интересно, как сделать архив сообщений для чата? :?
Аватара пользователя

Участник
Сообщений: 14
Я тут с 12 мар 2014
Откуда: Благовещенск
Двиг: Construct 2
Лицензия: Personal
Репутация 12 [ ? ]

Сообщение Multiplayer chat room[Перевод]
» 30 июл 2014, 09:50

BigPig писал(а):а интересно, как сделать архив сообщений для чата?

Сохранять текст Chatlog'а.
Аватара пользователя

Модератор
Сообщений: 2154
Я тут с 11 окт 2013
Откуда: Челябинск
Двиг: С2
Лицензия: Pirate
VK: night_silent
Репутация 223 [ ? ]

Сообщение Multiplayer chat room[Перевод]
» 24 янв 2015, 01:26

Всем привет!
Сделал комнаты и чат, переписываюсь с другом и постоянно после нескольких минут общения кто-то из нас disconected... используем стандартный сервер скирры. Подскажите кто сталкивался, что за проблема?

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

Участник
Сообщений: 19
Я тут с 31 окт 2014
Репутация 1 [ ? ]

Сообщение Multiplayer chat room[Перевод]
» 11 мар 2015, 09:51

Здорово!
А будут уроки по пинг-понгу и шутеру из примеров?
Там чат по другому реализуется, и вообще много интересного.
Аватара пользователя

Участник
Сообщений: 169
Я тут с 12 авг 2014
Откуда: Екатеринбург
Skype: they_maspel
VK: vk.com/Maspel
Репутация 0 [ ? ]



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

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

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

Наверх