Рубрики
Без рубрики

Узнайте основы Socket.io, сделав многопользовательскую игру

С ростом спроса на многопользовательские игры в современном мире, разработчики должны принять к сведению T … Tagged with HTML, JavaScript, Node, новички.

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

Итак, мы решили заняться основы создания многопользовательской игры, которая будет понравиться многим и в то же время будет достаточно простым, чтобы кодировать. Это когда он пересек наши умы, чтобы воссоздать Змеи и лестницы Знаменитая настольная игра, которую многие из нас провели бесчисленное количество часов, рос.

Там нет никаких предпосылок как таковых, так как мы будем кодировать игру с нуля. Тем не менее, некоторые базовые знания в настройке Экспресс сервер на Node.js и некоторые Ваниль JS обеспечит тщательное понимание охватываемых тем.

Весь проект был разделен на следующие разделы для ясности и разделения проблем:

Что мы будем делать

Давайте сформулируем то, что нам нужно сделать, чтобы достичь желаемого результата. Прежде всего, нам нужен сервер с голой Minimum, который будет отправлять запросы всем подключенным клиентам. Нам нужно настроить подключения к сокетам для общения в реальном времени. Наконец, нам понадобится код Frontend HTML, CSS и Vanilla JS для игровой логики.

Загрузка стартового проекта

Мы предоставили стартовый код для проекта, чтобы вы могли напрямую прийти к кодированию важных вещей, не проходившие проблемы с необходимостью организовать все игровые активы и файлы в соответствующие папки. Полностью написанный CSS Файл также был предоставлен для устранения необходимости стилизации html Компоненты с нуля, так как это не связано напрямую с целью статьи. Вы всегда можете включать свой собственный обычай CSS Если хотите, но это не будет необходимо. Вы можете скачать стартовый проект Здесь Анкет

Установка необходимых пакетов

После того, как вы загрузили начальные файлы, вам нужно установить необходимые пакеты. Внутри основной папки вы найдете Package.json файл. Запустите следующую команду, чтобы установить необходимые пакеты, а именно, Экспресс , Socket.io и http :

npm install

Вы должны установить Node.js для запуска команды. Если Node.js не установлен, перейдите на официальный веб -сайт Node.js, как указано выше и загрузите последнюю версию для вашей желаемой операционной системы. После загрузки и установки запустите команду снова.

Настройка сервера

Начнем с настройки нашего Express Server и Socket.io. Напишите следующий код внутри Server.js файл:

const express = require("express");
const socket = require("socket.io");
const http = require("http");

const app = express();
const PORT = 3000 || process.env.PORT;
const server = http.createServer(app);

// Set static folder
app.use(express.static("public"));

// Socket setup
const io = socket(server);

server.listen(PORT, () => console.log(`Server running on port ${PORT}`));

Скелет

Весь передний код для Node.js и Express Project обычно входит в public Папка, которую мы уже указали внутри Server.js . Прежде чем приступить к написанию игровой логики, важно создать html Файл с необходимыми компонентами, чтобы пользователь мог иметь возможность взаимодействовать с игрой. Идите вперед и включите следующий код в index.html Файл внутри публичный папка:




  
    
    
    Snakes and Ladders
    
    
  
  
    

Players currently online:


index.html Файл будет содержать особый элемент, холст , где наша игра оживила бы. холст Тег используется для рисования графики с использованием JavaScript. Он имеет встроенные функции для рисования простых форм, таких как дуги, прямоугольники, линии. Он также может отображать текст и изображения.

Для того, чтобы Socket.io имел возможность общаться с сервером Express Back-end с фронт-конца, мы добавляем следующее Скрипт ярлык:


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

Настройка соединения сокета

То, как работает Socket.io, довольно просто. По сути, клиенты выделяют определенные события, которые сервер может прослушать и, в свою очередь, передавать их всей или избранной части клиентов, которые находят использование для этой информации. Чтобы установить соединение, нам нужно добавить соединение Слушатель событий в io объект в Server.js файл следующим образом:

io.on("connection", (socket) => {
  console.log("Made socket connection", socket.id);
});

Это говорит серверу установить соединение сокета со всеми клиентами и отобразить id из розетков, как только соединение установлено. Консоль.log Заявление служит способом обеспечения успешной связи в случае, если что -то пойдет не так.

В то же время, внутри index.js Файл под public Папка, добавьте следующий код:

const socket = io.connect("http://localhost:3000");

Это говорит о сокете подключиться к передней части клиента, который доступен на упомянутом URL.

Игровая логика

Теперь мы перенесем наше внимание на логику, которая диктует игру. Мы напишем весь код в index.js файл. Вся логика можно разделить на следующие подкатегории:

  • Инициализация – Мы объявляем следующие глобальные переменные:
let canvas = document.getElementById("canvas");
canvas.width = document.documentElement.clientHeight * 0.9;
canvas.height = document.documentElement.clientHeight * 0.9;
let ctx = canvas.getContext("2d");

let players = []; // All players in the game
let currentPlayer; // Player object for individual players

const redPieceImg = "../images/red_piece.png";
const bluePieceImg = "../images/blue_piece.png";
const yellowPieceImg = "../images/yellow_piece.png";
const greenPieceImg = "../images/green_piece.png";

const side = canvas.width / 10;
const offsetX = side / 2;
const offsetY = side / 2 + 20;

const images = [redPieceImg, bluePieceImg, yellowPieceImg, greenPieceImg];

const ladders = [
  [2, 23],
  [4, 68],
  [6, 45],
  [20, 59],
  [30, 96],
  [52, 72],
  [57, 96],
  [71, 92],
];

const snakes = [
  [98, 40],
  [84, 58],
  [87, 49],
  [73, 15],
  [56, 8],
  [50, 5],
  [43, 17],
];

Прежде всего, мы установили размер холст Чтобы соответствовать размерам игровой доски и получить контекст из холст , который потребуется для рисования игроков. После этого мы объявляем коллекцию Игроки , который должен будет отслеживать игроков, которые в настоящее время находятся в игре, и CurrentPlayer Это хранит ссылку на игрока, который играет в игру на конкретном клиенте. Затем мы храним ссылки на четыре-игроки, а именно: красный, синий, желтый и зеленый. Мы инициализируем переменные сторона , offsetx а также OffSety который потребуется для регулировки позиции игроков на холсте. Наконец, переменные Лестницы и змеи инициализируются, которые являются коллекциями, которые хранят набор точек, связанных лестницами и змеями соответственно, как показано на игровой доске. Это потребуется для изменения позиции игроков, когда земля на квадрате с лестницей или змеей.

  • Игрочный класс – Мы хотели использовать парадигму ООП (объектно -ориентированное программирование) для представления игроков, что облегчает назначение соответствующих свойств и функций. Игрок класс смоделирован следующим образом:
class Player {
  constructor(id, name, pos, img) {
    this.id = id;
    this.name = name;
    this.pos = pos;
    this.img = img;
  }

  draw() {
    let xPos =
      Math.floor(this.pos / 10) % 2 == 0
        ? (this.pos % 10) * side - 15 + offsetX
        : canvas.width - ((this.pos % 10) * side + offsetX + 15);
    let yPos = canvas.height - (Math.floor(this.pos / 10) * side + offsetY);

    let image = new Image();
    image.src = this.img;
    ctx.drawImage(image, xPos, yPos, 30, 40);
  }

  updatePos(num) {
    if (this.pos + num <= 99) {
      this.pos += num;
      this.pos = this.isLadderOrSnake(this.pos + 1) - 1;
    }
  }

  isLadderOrSnake(pos) {
    let newPos = pos;

    for (let i = 0; i < ladders.length; i++) {
      if (ladders[i][0] == pos) {
        newPos = ladders[i][1];
        break;
      }
    }

    for (let i = 0; i < snakes.length; i++) {
      if (snakes[i][0] == pos) {
        newPos = snakes[i][1];
        break;
      }
    }

    return newPos;
  }
}

Каждый Игрок Объект требует id , a имя , позиция на доске, обозначаемая поступок и изображение булавки, как это обозначено IMG . Затем мы пишем функции нарисовать , UpdatePos и Isladderorsnake соответственно, чтобы нарисовать и обновить позицию игроков и найти, есть ли у квадрата игрока на доске лестницу или змею. UpdatePos Метод просто обновления поступок С номером, который игрок только что катился на кости и проверяет состояние, которое мешает игроку выйти за пределы 100 -й квадрат на доске. Здесь следует отметить, что позиция игрока, хотя и начинается с 1, обозначается 0, что делает логику рисования проще. ISLADDERORSNAKE Функция принимает аргумент в качестве позиции игрока и сравнивает его с квадратами в коллекции Лестницы и змеи и соответственно возвращает новую позицию игрока на доске. нарисовать Функция может показаться немного сложной, но все, что она делает, это нарисовать игроки на правильных квадратах на доске. Функция заботится о альтернативном правом и левом движении через ряды и вверх движением по столбцам.

  • Функции утилиты – Помимо функций, которые мы написали внутри Игрок Класс, нам нужно написать еще две функции утилиты следующим образом:
function rollDice() {
  const number = Math.ceil(Math.random() * 6);
  return number;
}

function drawPins() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  players.forEach((player) => {
    player.draw();
  });
}

Rolldice Функция возвращает случайное число от 1 до 6, в то время как Drawpins Функциональные циклы через Игроки Сбор и рисует соответствующие игроки, используя их нарисовать функция

  • Увольнение событий и обработка их – До сих пор мы написали код для игровых сущностей. Однако, если мы не уволимся с событиями сокетов с фронт-конца, ни один из игроков не сможет передать свои позиции и другие данные между собой. Прежде всего, добавьте следующую строку кода ниже io.connect функция в index.js файл:
socket.emit("joined");

Затем добавьте следующие слушатели событий в соответствующие html элементы следующим образом:

document.getElementById("start-btn").addEventListener("click", () => {
  const name = document.getElementById("name").value;
  document.getElementById("name").disabled = true;
  document.getElementById("start-btn").hidden = true;
  document.getElementById("roll-button").hidden = false;
  currentPlayer = new Player(players.length, name, 0, images[players.length]);
  document.getElementById(
    "current-player"
  ).innerHTML = `

Anyone can roll

`; socket.emit("join", currentPlayer); }); document.getElementById("roll-button").addEventListener("click", () => { const num = rollDice(); currentPlayer.updatePos(num); socket.emit("rollDice", { num: num, id: currentPlayer.id, pos: currentPlayer.pos, }); }); document.getElementById("restart-btn").addEventListener("click", () => { socket.emit("restart"); });

присоединился Событие, излучаемое сокетом, сообщает новому игроку, который только что присоединился к игре о игроках, которые уже присоединились к игре, что означает их позицию и их изображение PIN. Вот почему он уволен, как только присоединится новый пользователь. После этого мы добавили три нажимать Слушатели событий к кнопке запуска, кнопке Roll и кнопкой перезапуска. Кнопка «Пуск» берет имя недавно объединенного игрока и создает новый CurrentPlayer объект. После этого несколько из html Теги манипулируют, чтобы передать статус игры, после чего A Присоединяйтесь Событие испускается, что уведомляет сервер недавно присоединенного игрока. Слушатель событий Roll Button просто свертывает кости и обновляет положение CurrentPlayer и посылает номер, свернутый на кости вместе с их я бы и имя . Кнопка перезапуска в качестве имени предлагает пожары A перезапуск Мероприятие с фронта.

Мы также должны иметь возможность получать эти события на стороне сервера. Напишите код, как указано ниже внутри соединение Слушатель событий io Объект3:

socket.on("join", (data) => {
    users.push(data);
    io.sockets.emit("join", data);
  });

  socket.on("joined", () => {
    socket.emit("joined", users);
  });

  socket.on("rollDice", (data) => {
    users[data.id].pos = data.pos;
    const turn = data.num != 6 ? (data.id + 1) % users.length : data.id;
    io.sockets.emit("rollDice", data, turn);
  });

  socket.on("restart", () => {
    users = [];
    io.sockets.emit("restart");
  });
});

У бэкэнда есть те же слушатели событий, а также Пользователи Коллекция, которая хранит и передает информацию о игроках, которые играют.

Мы также должны иметь возможность обрабатывать эти события на переднем конце, и код для этого:

socket.on("join", (data) => {
  players.push(new Player(players.length, data.name, data.pos, data.img));
  drawPins();
  document.getElementById(
    "players-table"
  ).innerHTML += `${data.name}`;
});

socket.on("joined", (data) => {
  data.forEach((player, index) => {
    players.push(new Player(index, player.name, player.pos, player.img));
    console.log(player);
    document.getElementById(
      "players-table"
    ).innerHTML += `${player.name}`;
  });
  drawPins();
});

socket.on("rollDice", (data, turn) => {
  players[data.id].updatePos(data.num);
  document.getElementById("dice").src = `./images/dice/dice${data.num}.png`;
  drawPins();

  if (turn != currentPlayer.id) {
    document.getElementById("roll-button").hidden = true;
    document.getElementById(
      "current-player"
    ).innerHTML = `

It's ${players[turn].name}'s turn

`; } else { document.getElementById("roll-button").hidden = false; document.getElementById( "current-player" ).innerHTML = `

It's your turn

`; } let winner; for (let i = 0; i < players.length; i++) { if (players[i].pos == 99) { winner = players[i]; break; } } if (winner) { document.getElementById( "current-player" ).innerHTML = `

${winner.name} has won!

`; document.getElementById("roll-button").hidden = true; document.getElementById("dice").hidden = true; document.getElementById("restart-btn").hidden = false; } }); socket.on("restart", () => { window.location.reload(); });

Большинство слушателей событий сокетов довольно просты, и хороший взгляд на функциональные операторы говорят вам, что все, что мы здесь делаем, – это отображение текущего состояния игры, отключив и включив необходимое HTML элементы.

Заканчивать

Теперь, когда все на месте, пришло время запустить терминал и запустить Node Server.js , который разоблачает сервер node.js в порт 3000 Localhost . После этого вы можете посетить http://localhost: 3000 с несколькими окнами браузера и протестируйте игру.

Этот проект предназначен для того, чтобы служить точке входа в бесконечные возможности сферы многопользовательских игр и общения сокетов. Мы стремились объяснить абсолютные основы здесь, и есть место для большого улучшения. Например, в настоящее время игра позволяет только 4 игрокам играть одновременно, но на самом деле такая игра должна иметь определенные комнаты, в которые могут присоединиться игроки, что позволяет нескольким игрокам одновременно получить доступ к игре. Вы также можете добавить внутриигровой чат, где игроки могут общаться друг с другом во время игры. Движение игроков на холст также мгновенный, что не так привлекательно. Настоятельно рекомендуется попробовать добавить такие функции в игру, чтобы получить еще более сильное понимание основных технических данных.

Супо/змеи и ладдерс-мультиплейер

Многопользовательская игра змей и лестниц, сделанная с использованием Nodejs и Socket. Io

Главная филиал содержит завершенный проект, тогда как стартовый филиал обеспечивает начальный код.

Эта статья была в соавторстве:

Супирно Пол

Нирвик Агарвал

Мы надеемся, что вы нашли это проницательным. Посетите наш Веб -сайт Чтобы узнать больше о нас, а также следить за нами:

Кроме того, не забудьте отбросить подобное и прокомментировать, если вы заинтересованы в том, чтобы узнать больше о разработке игры с использованием JavaScript. Вы можете свободно вызвать сомнения и предложить улучшения.

До тех пор, Оставаться в безопасности и Май Источник с вами!

Оригинал: “https://dev.to/nitdgplug/learn-the-basics-of-socket-io-by-making-a-multiplayer-game-394g”