- PVSM.RU - https://www.pvsm.ru -
Речь пойдет о web-реализации популярной карточной игры "Мафия [1]". Она писалась для развлечения и получения опыта в разработке игр. Первая версия была написана за две недели свободного от работы времени и за такое же время переписана до второй версии. Плюс такой игры – отсутствие ведущего.
Отталкиваясь от целей разработки, я принял решения о реализации/нереализации фич.
Что точно нужно было сделать:
Что делать не планировалось или можно было отложить:
https://github.com/mrsuh/mafia-backend [2]
Написан на Go. Хранит в себе состояние игры и отвечает за её логику.
Во время игры можно обратиться к серверу, чтобы узнать полную информацию:
curl 'http://127.0.0.1:8000/info?game=23' | python -m json.tool
{
"event": "greet_mafia",
"event_status": 2,
"id": 23,
"is_over": false,
"iter": 1,
"players": [
{
"addr": "172.18.0.1:51438",
"createdAt": "2018-09-23T14:39:29.631475779Z",
"id": 33309,
"name": "Anton",
"role": 4
},
{
"addr": "172.18.0.1:51440",
"createdAt": "2018-09-23T14:39:32.867080927Z",
"id": 5457,
"name": "username:0",
"role": 2
},
{
"addr": "172.18.0.1:51442",
"createdAt": "2018-09-23T14:39:32.882463945Z",
"id": 14214,
"name": "username:2",
"role": 1
},
{
"addr": "172.18.0.1:51444",
"createdAt": "2018-09-23T14:39:32.895209072Z",
"id": 63759,
"name": "username:1",
"role": 3
}
],
"win": 0
}
Или узнать состояние сервера:
curl 'http://127.0.0.1:8000/health' | python -m json.tool
{
"runtime.MemStats.Alloc": 764752,
"runtime.MemStats.NumGC": 0,
"runtime.MemStats.Sys": 4165632,
"runtime.MemStats.TotalAlloc": 764752,
"runtime.NumGoroutine": 14
}
Для определения активен ли еще игрок backend посылает heartbeat. Если игрок не ответил после определенного интервала, то он выбывает из игры. В то же время, если игрок переподключился до окончания интервала(пропала сеть), то он может продолжить игру.
Для стабильной работы backend был покрыт Unit тестами со стандартной библиотекой Go [3], где проверяются основные сценарии работы.
go test mafia-backend/src -cover
ok mafia-backend/src 1.315s coverage: 70.7% of statements
https://github.com/mrsuh/mafia-frontend [4]
Написан на чистом JS и собран с помощью Grunt [5].
Не несет в себе никакой логики.
При возникновении события с backend рендерит нужную страницу, отображает данные, которые ему прислали и проигрывает звук нового события.
Frontend хранит ID игры и игрока в LocalStorage [6] или строке запроса браузера (если необходимо запустить в одном браузере несколько вкладок для разных игроков). Полное отсутствие логики, а также хранение основных параметров игры дают возможность даже после перезагрузки страницы восстановить состояние игры.
Браузер запрещает [7] автовоспроизведение звуков без участия пользователя (например, нажатия на кнопку). Чтобы воспроизводить звуки на каждое событие, которе приходит с backend был сделан всего 1 JavaScript объект Audio. Каждый игрок должен нажать кнопку для начала игры и в этот момент объект Audio становится активным (доступным для воспроизведения), и впоследствии у него можно менять параметр src для воспроизведения разных звуков без участия пользователя.
Также для тестирования работы игры был написан «бот», который может играть сам с собой.
Достаточно открыть вкладку браузера, где в параметрах указано, что нужно запустить тест
http://127.0.0.1?master=1&test=1&sound=0&testUsersCount=5
и разрешить открывать новые вкладки из JavaScript для этого домена.
После начала игры откроются еще 5 вкладок с игроками и они начнут играть между собой.
Протокол WebSocket [8] был выбран по причине необходимости постоянного двухстороннего обмена данными между backend и frontend и его поддержки обоими языками.
Вся игра разделена на события:
События имеют начало, конец и содержательную часть.
В начале и конце события всем активным игрокам рассылается уведомление, которое нужно подтвердить. Игра продолжается только после подтверждения этого события всеми активными игроками (например, только после того, как будет воспроизведен звуковой файл).
Всю игру можно поднять с помощью Docker [9]:
docker-compose.yml
version: '3'
services:
mafia-frontend:
image: mrsuh/mafia-frontend:latest
container_name: mafia_frontend
ports:
- 9080:80
mafia-backend:
image: mrsuh/mafia-backend:latest
container_name: mafia_backend
ports:
- 8000:8000
Достаточно установить Docker (если вы этого еще не сделали), скопировать к себе текст docker-compose.yml и выполнить команду:
docker-compose up
После этого можно открывать вкладку с игрой в браузере:
http://127.0.0.1:9080
Вот тут можно посмотреть что итоге получилось (скорость воспроизведения увеличена в 1.5 раза).
После почти месяца разработки в свободное время получилась довольно стабильная игра в которую можно поиграть с друзьями. Игра выдерживает перезагрузку страницы или временное пропадание сети. Озвучка событий на устройствах работает, хоть и без синхронизации по времени. Дальнейшее развитие игры не планируется.
P.S.: Спасибо Лере [10] за озвучку игры.
Автор: mrsuh
Источник [11]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/294902
Ссылки в тексте:
[1] Мафия: https://ru.wikipedia.org/wiki/%D0%9C%D0%B0%D1%84%D0%B8%D1%8F_(%D0%B8%D0%B3%D1%80%D0%B0)
[2] https://github.com/mrsuh/mafia-backend: https://github.com/mrsuh/mafia-backend
[3] библиотекой Go: https://golang.org/pkg/testing
[4] https://github.com/mrsuh/mafia-frontend: https://github.com/mrsuh/mafia-frontend
[5] Grunt: https://gruntjs.com
[6] LocalStorage: https://developer.mozilla.org/ru/docs/Web/API/Window/localStorage
[7] запрещает: https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#webaudio
[8] WebSocket: https://ru.wikipedia.org/wiki/WebSocket
[9] Docker: https://ru.wikipedia.org/wiki/Docker
[10] Лере: https://vk.com/id15305045
[11] Источник: https://habr.com/post/423821/?utm_campaign=423821
Нажмите здесь для печати.