Игровые сценарии
Начинать основную разработку я решил с бэкенда. И чтобы не спотыкаться и не терять время на параллельное изучение Angular-а, клиент временно будет на jQuery с минимальным набором инструментов для отладки бэкенда. Потом, когда бэкенд будет готов, перейдём на Angular. Вот такая примерно идея.
GAME CREATION
Подключаем jQuery в index.html
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
Добавляем кнопку для создания новой игры
<button id="create-game-btn">Create Game</button>
И обработчик события в client.js. Пока что захардкодим игру на 3 игроков, потом будет отдельное поле для количества игроков.
$('#create-game-btn').on('click', function(e){
e.preventDefault();
console.log('creating game...');
socket.emit('create-game', {
numberOfPlayers: 3
});
})
Обработка события на сервере, server.js
io.on('connection', (socket) => {
…
socket.on('create-game', (data) => {
const gameRoom = createGameRoom(data.numberOfPlayers);
console.log('Game created:', gameRoom.id);
});
…
Так как любой пользователь может создать игру, то игровых комнат может быть много. Хранить их будем в:
const gameRooms = new Map();
При создании новой игры выбираем случайную, еще не занятую фразу и устанавливаем её как название игровой комнаты (или проще говоря игры). По этому названию другие игроки будут знать к какой игре им подключаться. Кроме названия у игры будут такие поля как уникальный id, количество игроков и флаг состояния - открыта комната для новых подключений или нет. Как только игра инициализирована, она добавляется в общий список.
const createGameRoom = (numberOfPlayers) => {
//get free game id and title
let randomPhrase = {};
do {
randomPhrase = getPhrase();
} while (gameRooms.size && gameRooms.has(randomPhrase.id));
const gameRoom = {
id: randomPhrase.id,
title: randomPhrase.name,
numberOfPlayers,
isOpen: true
}
gameRooms.set(randomPhrase.id, gameRoom);
return gameRoom;
}
GAME LISTING
Список открытых комнат для подключения. Используется в сценарии, когда пользователь выбирает опцию Join Game.
Добавим кнопку в index.html
<button id="list-games-btn">List Games</button>
И обработчик для неё в client.js
$('#list-games-btn').on('click', function(e){
e.preventDefault();
console.log('requesting list of the games...');
socket.emit('list-games-request');
})
Сервер на событие 'list-games-request' будет отвечать событием 'list-games-response' с параметром в виде списка доступных игр. server.js
socket.on('list-games-request', () => {
socket.emit('list-games-response', {
games: getOpenRooms()
})
});
const getOpenRooms = () => {
let ret = [];
for (let value of gameRooms.values()) {
if (value.isOpen) {
ret.push({
id: value.id,
title: value.title
});
}
}
return ret;
}
Обработчик события 'list-games-response' на стороне клиента. При получении списка игр выводим их в консоли. client.js
//response to list-games-request
socket.on('list-games-response', (data) => {
console.log('listing games', data.games);
});
Протестируем изменения в браузере. Создадим несколько игр и получим их список.
JOIN GAME
Подправим немного вёрстку, добавим контейнер для списка игр. index.html
<!DOCTYPE html>
<html>
<head>
<title>Socket Client Test</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="https://cdn.socket.io/4.8.1/socket.io.min.js" integrity="sha384-mkQ3/7FUtcGyoppY6bz/PORYoGqOl7/aSUMn2ymDOJcapfS6PHqxhRTMh1RR0Q6+" crossorigin="anonymous"></script>
</head>
<body>
<div>
<button id="create-game-btn">Create Game</button>
</div>
<div>
<button id="list-games-btn">List Games</button>
<ul id="game-list"></ul>
</div>
</body>
<script type="text/javascript" src="client.js"></script>
</html>
Добавим формирование списка игр, с опцией присоединения к игре. client.js
//response to list-games-request
socket.on('list-games-response', (data) => {
console.log('listing games', data.games);
//render game list
$('#game-list').empty();
if (Array.isArray(data.games)) {
data.games.forEach(i => {
$('#game-list').append(`<li>${i.title} <button class="join-game-btn" data-id-game="${i.id}">Join</button></li>`);
});
}
});
И сам обработчик присоединения к игре. client.js
$('#game-list').on('click', '.join-game-btn', function(e){
e.preventDefault();
const gameId = $(this).data('idGame');
console.log(`joining game with id ${gameId} ...`);
})
Проверим результат. Создадим несколько игр, получим их список и присоединимся к одной из них.
Продолжение следует ...
