Web игрa Spy на Node.JS, Angular и Websockets (Часть 3)

Игровые сценарии  

Начинать основную разработку я решил с бэкенда. И чтобы не спотыкаться и не терять время на параллельное изучение 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);

});    

Протестируем изменения в браузере. Создадим несколько игр и получим их список.

Тест сценариев create game и game listing

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} ...`);

})

Проверим результат. Создадим несколько игр, получим их список и присоединимся к одной из них.

Сценарий подключения к игре

Продолжение следует ...

Leave a Reply

Your email address will not be published. Required fields are marked *