Введение в разработку многопользовательских игр

Создание многопользовательской онлайн-игры — сложная и увлекательная задача, которая может стать испытанием даже для самых опытных разработчиков. Однако при наличии подходящих инструментов и творческого подхода можно воплотить идеи многопользовательской игры в жизнь. В этой статье мы рассмотрим, как создать многопользовательскую онлайн-игру с помощью Phaser и Node.js — мощных инструментов из арсенала разработчиков игр.

Почему Phaser и Node.js?

Phaser — это популярный JavaScript-фреймворк для создания 2D-игр, известный своей простотой использования, обширной документацией и надёжным набором функций. Он поддерживает различные типы игр, от простых аркадных до сложных платформеров, и широко используется как новичками, так и профессионалами.

Node.js, с другой стороны, представляет собой среду выполнения JavaScript, позволяющую запускать JavaScript на стороне сервера. В сочетании с Socket.io он предоставляет отличное решение для обмена данными между клиентами и серверами в реальном времени, что крайне важно для многопользовательских игр.

Настройка среды разработки

Прежде чем приступить к написанию кода, убедитесь, что у вас установлены необходимые инструменты:

Node.js и npm: скачайте и установите их с официального веб-сайта Node.js, если вы этого ещё не сделали. — Phaser: вы можете добавить Phaser в свой проект через CDN или установив его через npm. — Socket.io: эта библиотека будет использоваться для обмена данными в реальном времени между клиентом и сервером.

Установка зависимостей

Чтобы начать работу, создайте новый каталог для своего проекта и перейдите в него в терминале или командной строке. Затем установите необходимые зависимости:

npm init -y
npm install express socket.io

Создание сервера

Сервер станет центральным узлом, который управляет состоянием игры и обменивается данными с клиентами. Вот как можно настроить его с помощью Node.js и Express:

Код сервера

Создайте файл с именем server.js и добавьте следующий код:

const express = require('express');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io')(server);

let players = {};

io.on('connection', (socket) => {
    console.log('New player connected');

    // Handle new player connection
    socket.on('newplayer', () => {
        players[socket.id] = {
            x: Math.floor(Math.random() * 700) + 50,
            y: Math.floor(Math.random() * 500) + 50,
            playerId: socket.id,
            team: (Math.floor(Math.random() * 2) == 0) ? 'red' : 'blue'
        };

        // Send the new player's info to all connected clients
        socket.emit('currentPlayers', players);
        socket.broadcast.emit('newPlayer', players[socket.id]);
    });

    // Handle player movement
    socket.on('playerMovement', (data) => {
        if (players[socket.id]) {
            players[socket.id].x = data.x;
            players[socket.id].y = data.y;
            io.emit('playerMoved', players[socket.id]);
        }
    });

    // Handle player disconnection
    socket.on('disconnect', () => {
        delete players[socket.id];
        io.emit('playerDisconnected', socket.id);
    });
});

server.listen(8081, () => {
    console.log('Server listening on port 8081');
});

Создание клиента

Клиент будет отвечать за рендеринг игры и обработку пользовательского ввода. Вот как вы можете настроить его с помощью Phaser:

Код клиента

Создайте HTML-файл с именем index.html и добавьте следующий код:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/phaser.min.js"></script>
    <script src="/socket.io/socket.io.js"></script>
</head>
<body>
    <div id="phaser-example"></div>
    <script src="game.js"></script>
</body>
</html>

Создайте JavaScript-файл с именем game.js и добавьте следующий код:

const config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    scene: {
        preload: preload,
        create: create,
        update: update
    },
    physics: {
        default: 'arcade',
        arcade: {
            gravity: { y: 0 },
            debug: false
        }
    }
};

const game = new Phaser.Game(config);

let socket;
let players;

function preload() {
    this.load.image('player', 'path/to/player.png');
}

function create() {
    socket = io.connect('http://localhost:8081');

    // Initialize the player object
    players = {};

    // Listen for new players
    socket.on('currentPlayers', (data) => {
        Object.keys(data).forEach((id) => {
            if (id === socket.id) return;
            players[id] = this.add.sprite(data[id].x, data[id].y, 'player');
        });
    });

    // Listen for new player connections
    socket.on('newPlayer', (data) => {
        players[data.playerId] = this.add.sprite(data.x, data.y, 'player');
    });

    // Listen for player disconnections
    socket.on('playerDisconnected', (id) => {
        if (players[id]) players[id].destroy();
        delete players[id];
    });

    // Listen for player movements
    socket.on('playerMoved', (data) => {
        if (players[data.playerId]) players[data.playerId].setPosition(data.x, data.y);
    });

    // Emit new player event
    socket.emit('newplayer');

    // Handle user input
    this.input.keyboard.createCursorKeys();
}

function update() {
    if (this.input.keyboard.isDown(Phaser.Input.Keyboard.LEFT)) {
        socket.emit('playerMovement', { x: players[socket.id].x - 5, y: players[socket.id].y });
    } else if (this.input.keyboard.isDown(Phaser.Input.Keyboard.RIGHT)) {
        socket.emit('playerMovement', { x: players[socket.id].x + 5, y: players[socket.id].y });
    }
}

Взаимодействие в реальном времени

Настоящая магия происходит, когда сервер и клиенты начинают обмениваться данными в режиме реального времени. Вот диаграмма последовательности, иллюстрирующая взаимодействие клиента и сервера:

sequenceDiagram participant Client participant Server Note over Client,Server: Client connects to the server Client->>Server: Establish connection Server->>Client: Welcome message Note over Client,Server: Client requests to join the game Client->>Server: newplayer event Server->>Client: currentPlayers data Server->>Client: newPlayer event (broadcast to other clients) Note over Client,Server: Client moves their player Client->>Server: playerMovement event Server->>Client: playerMoved event (broadcast to other clients) Note over Client,Server: Client disconnects Client->>Server: Disconnect Server->>Client: playerDisconnected event (broadcast to other клиентов)

Тестирование вашей игры

Чтобы протестировать свою игру, запустите сервер, выполнив команду node server.js в терминале. Затем откройте несколько окон браузера и перейдите по адресу http://localhost:8081. Вы должны увидеть, как несколько игроков перемещаются, и любое движение или отключение должно отразиться в режиме реального времени на всех подключённых клиентах.