Войти
ПрограммированиеФорумВеб

Прошу совета по разработке многопользовательской html5 игры.

#0
18:45, 8 дек. 2012

Всем привет.

Есть концепция игры - банальный пинг-понг с реализацией на html5 Canvas. Тема для меня новая - поэтому сделал как пришло в голову.

На клиенте - вход в игру и канвас где она отрисовывается. Когда игрок заходит в игровую комнату - его сессия заносится в БД и там же хранятся координаты мячика. Два первых зашедших человека начинают игру- остальные могут смотреть как наблюдатели. Когда один игрок выходит, любой другой может занять его место.
Когда игрок запускает игру - каждое движение игрока мышью активирует AJAX который пересылает координаты курсора в php-скрипт, который записывает их в базу - привязывая к ключу сессии этого пользователя.
И раз в 100 милисекунд каждый клиент запрашивает у другого скрипта координаты всех объектов.

Синхронизации то я добился - у всех пользователей на канвасе все синхронно. Но тормозит вся эта конструкция просто безбожно. +))

В связи с чем прошу знающих людей помочь советом - в какую сторону лучше копать?) Мне посоветовали node.js и я уже третий день сижу читаю разные статьи - но к сожалению статей про серверную часть браузерных игр почти нет((


#1
18:56, 8 дек. 2012

Это реалтайм игра, т. е. самый сложный по сетевой части вариант. Я не в курсе, html5/JS умеет посылать UDP пакеты? Должен быть выделенный сервер, который считает физику, получая движение ракетки от клиентов. Клиенты должны посылать свое положение, получать данные с сервера и предсказывать положение мячика на пинг вперед (Client Side Prediction). В общем не советовал бы пытаться такое делать для новичка.

#2
19:07, 8 дек. 2012

Ну так я уже это сделал - мне это надо просто улучшить) Изучить более грамотный способ сделать то, что я уже сделал.)

#3
20:49, 8 дек. 2012

T0SH1R0
> Когда игрок заходит в игровую комнату - его сессия заносится в БД и там же хранятся координаты мячика.
Не надо хранить координаты мячика в БД. В твоём случае имеет смысл сохранять данные между партиями, но не сами партии.

Как сказал Smile, нужно завести отдельную сущность, которая обрабатывает партии (в самом простом случае - отдельный процесс на партию). Делать примерно так (очень примерно):

- В момент создания партии порождаешь новый процесс, ему сообщаешь id игроков. Игрокам сообщаешь как подключаться к процессу (например, ip адрес + порт).
- игроки устанавливают постоянное соедниение (ajax для реалтайма не катит хотя бы потому, что http - не самый быстрый протокол), например, с помощью websockets, и общаются напрямую с процессом, который обрабатывает их игру.
- клиенты отображают ситуацию в игре с учётом прошедшего с момента последней "синхронизации" с сервером времени (т.е, учитывают скорость движения мячика и прочее)
- по завершении игры процесс сохраняет результат в базу и завершает свою работу.

#4
23:14, 8 дек. 2012

Каждое движение мяча в базу данных через AJAX это будет очень очень много боли и унижения. При 10 игроках, сервер и БД будет нагружен на 200%. Состояние игры хранится ТОЛЬКО в памяти, в базу пишем, когда игрок отключился, ну и если что-то важное происходит, какие-то важные события надо сохранять в течение игры, то пишем в базу периодически на всякий случай, если сервер крашнется, чтоб очки не пропали за последние 5 минут, пишем каждые 5 минут.

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

И не надо пользоваться AJAX, открывается вебсокет и по нему не сильно напрягая сервер ведется обмен данными, если вебсокета браузер не поддерживает - очень плохо, можно решить, но нужно ли для твоего хобби проекта?

#5
1:28, 9 дек. 2012

T0SH1R0
> В связи с чем прошу знающих людей помочь советом - в какую сторону лучше
> копать?) Мне посоветовали node.js и я уже третий день сижу читаю разные статьи
> - но к сожалению статей про серверную часть браузерных игр почти нет((
NodeJS посоветовали правильно - для таких игр он идеальное решение.
В качестве транспорта берёшь веб-сокеты, все новые браузеры их уже поддерживают.

Про традиционный php забудь - в динамичной игре сервер должен постоянно держать соединение,
а не завершать скрипт после каждого обращения. Плюс он должен хранить состояние игры в памяти, лишь
изредка сливая его в базу, как сказал kvakvs. Можно, конечно, поставить php как демон, но
здесь он неэффективен и более сложен в настройке (и даже в поиске хостинга), чем nodejs.

Если твоих знаний JS/Node будет достаточно для понимания этого, то посмотри исходники
browserquest'а - это небольшая реалтайм ММО на nodejs и вебсокетах.

http://browserquest.mozilla.org/
https://github.com/mozilla/browserquest

p.s. Впрочем, я не советую бросаться в эту кучу исходников. Легче разобраться в nodejs с нуля,
наладить пересылку данных по вебсокетам и дальше уже сам смекнёшь, что делать.

#6
7:54, 9 дек. 2012

Это весьма простой пример реал-тайм игры.

Проблема тут в том что для web'а, реалтайм - это новшевство, и многие не совсем в курсе новых технологий, которые позволяют удобно и легко реализовать такого рода задачу.
Как тебе посоветовали - используй node.js.
Я тебе посоветую тоже самое, по нескольким причинам:
1. реалтайм. Значит отправка пакетов достаточно часто и с минимальой задержкой. HTTP запросы через AJAX будут создовать новое соединение при каждом запросе и реализовывать пожатие (handshake), что также всё замедляет. Далее твой AJAX stack в броузере также может замедляться в очереди пока другие запросы не будут обработанны. Что node.js предлагает, так это конкретная библиотека socket.io - это серверная реализация WebSockets протокола. WebSockets в использовании ужасно прост, как на клиенте так и на сервере: простой event subscriber, получаешь и отправляешь данные в JSON формате. Куда может быть удобнее. WebSockets - это протокол для реалтайм коммуникации между броузером (JS) и сервером. Используется TCP + небольшая надстройка для фреймов пакетов. Но т.к. соединение открывается один раз и далее шлются пакеты, это в разы шустрее и более производительно чем AJAX.
2. обмен данными между клиентами на сервере. Чем я PHP или т.п. решения не люблю - так это то что все сессии между собой не общаются. Нужно использовать Shared Memory хрень, или базу данных как ты реализовал для обмены данных. Но это полный изврат! В node.js ты по сути пишешь apache сервер, это один процесс, и через этот процесс ты описываешь логику работы с клиентами. Тем самым ты можешь завезти любого рода глобальные или относительно локальные данные и использовать их между разными клиентами. Что может быть лучше - чем работа с данными на прямую?

Советую тебе просто установить node.js и используя npm установить socket.io. Интернеты уже кишат инфой по этому поводу. Глянь тут как всё просто: http://socket.io/

Пиши в этот топик, я тебе смогу помочь по деталям.

#7
13:53, 9 дек. 2012

MoKa
Я, кстати, в своё время не смог разобраться с socket.io, лол.
Там непонятно, откуда брать файлы для клиента:

<script src="/socket.io/socket.io.js"></script>

Да и вообще, очень громоздкая штука.

Adobe® Flash® Socket
AJAX long polling
AJAX multipart streaming
Forever Iframe
JSONP Polling

Использование этих технологий в качестве fallback'а?
Оно правда здесь нужно - подстраиваться под древние браузеры,
где помимо вебсокетов наверняка не поддерживается и канвас?

#8
14:28, 10 дек. 2012

петрушка
> Я, кстати, в своё время не смог разобраться с socket.io, лол.
> Там непонятно, откуда брать файлы для клиента:
> <script src="/socket.io/socket.io.js"></script>
Клиент делает запрос на "/socket.io/socket.io.js", socket.io уже заранее прописывает get route на этот запрос, и выдаст сам скрипт. Так что тебе не нужно париться об этом, просто запроси его от сервера, он выдаст.

петрушка
> Да и вообще, очень громоздкая штука.
По сути если ты это дело не активируешь, то оно и не будет использоваться, и никак не повлияет на громоздкость.
Я не использую ни один из fallback'ов, т.к. как ты подметил, если нету canvas то и socket'ов не будет. И там так сделано, что даже "ношение" с собой функционала fallback'ов, никак не влияет на производительность и юзабилити при использовании только WebSocket'ов.

На оффициальном сайте http://socket.io/ есть простейший пример, просто копи-пастни, он работает из короби.

#9
15:16, 10 дек. 2012

Всем огромное спасибо за ответы!) Теперь более ясно понял курс в котором копать и курить - к чему и приступаю)

ПрограммированиеФорумВеб

Тема в архиве.