Как сделать игру на javascript
Перейти к содержимому

Как сделать игру на javascript

  • автор:

2D игра на чистом JavaScript

В этом пошаговом руководстве мы создадим простую игру MDN Breakout, написанную на чистом JavaScript и отрендеренную на HTML5 .

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

Для извлечения максимальной пользы из этой серии статей необходимо иметь средние (или хотя бы базовые) знания языка JavaScript. После прохождения этого урока вы сможете создавать собственные простые браузерные игры.

Gameplay screen from the game MDN Breakout where you can use your paddle to bounce the ball and destroy the brick field, with keeping the score and lives.

Детали к урокам

Все уроки и версии игры MDN Breakout доступны в GitHub:

Лучший способ получить надёжные знания в области разработки браузерных игр — это начать с чистого JavaScript. Затем можно выбрать любой фреймворк для использования в своих проектах. Фреймворки — это инструменты, созданные на языке JavaScript; поэтому, даже если вы планируете работать с ними, нелишним будет сначала изучить сам язык, чтобы понимать, что именно происходит внутри. Фреймворки ускоряют разработку и помогают справиться со скучными частями игры, но если что-то работает не так, как ожидалось, всегда можно попытаться отладить код или написать собственное решение на чистом JavaScript.

Примечание: Если вам интересно узнать о разработке двухмерных игр с помощью игровой библиотеки, ознакомьтесь с альтернативной серией статей 2D игра Breakout с использованием Phaser (en-US) .

Примечание: Эту серию статей можно использовать как материал для практических занятий по разработке игр. Также можно воспользоваться набором инструментов Gamedev Canvas Content Kit, основанном на этом уроке, если нужно сделать доклад о разработке игр в целом.

Создать JS-игру с мультиплеером за 24 часа и выжить

Как всего за сутки мы с моими коллегами (шестью фронтендерами и одним бэкендером) создали настоящую мультиплеерную игру на JavaScript.

За 24 часа можно успеть очень много. Сегодня я решил рассказать, как всего за сутки мы с моими коллегами (шестью фронтендерами и одним бэкендером) создали настоящую мультиплеерную игру на JavaScript. Поехали!

Вадим Силантьев
Frontend-разработчик IRLIX

Создать JS-игру с мультиплеером за 24 часа и выжить 1

Собрались похакатонить…

Совсем недавно в компании IRLIX, где я работаю frontend-разработчиком, прошло знакомое для многих мероприятие — хакатон. На мой взгляд, это очень крутой формат, который независимо от масштаба позволяет изучить новые грани разработки. В том числе для frontend направления. Главное — объективно оценивать, на что вы способны и найти баланс между полётом фантазии и реальностью при выполнении задач.

Целью данного хакатона было создать ровно за 24 часа игру с нуля, используя только JavaScript, Node.js, Soket.io. и два ящика энергетиков.

Я очень легко соглашаюсь на разную движуху. И мне совершенно не обязательно знать, что из этого выйдет. Уже в процессе меня одергивает разум: «Чувак, зачем ты в это вписался?». Но раз пути назад нет — погнали. Этот раз тоже не стал исключением. Не успел я оглянуться — и вот уже полностью погружен в процесс разработки игры.

Почему JavaScript?

Сегодня игрушку можно сделать практически на любом языке программирования, но мы решили остановиться на JS. Выбор стека был обусловлен в основном нашими знаниями по определенным технологиям. Мы решили использовать библиотеку Soket.io, так как она поддерживает постоянную связь клиента с сервером и имеет возможность создавать кастомные эвенты между ними, что необходимо при построении мультиплеерной игры. На мой взгляд, это было идеальным решением в рамках времени, которым мы располагали.

Процесс разработки или сутки, которые я не забуду никогда

Мне казалось нереально сложным иметь только общее представление о том, что должно получиться в итоге, и ни малейшего представления о том, как это сделать. Спустя сутки я понял, что в данном случае главная фича для крутого результата — это именно свобода действий. Ведь тебя практически ничего не ограничивает (ну, кроме времени, само собой) — фантазируй, придумывай, воплощай.

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

const gameLoop = (game, io) => < io.sockets.emit('state', game); >; setInterval(() => < if (game.players && io) < gameLoop(game, io); >>, engineTimeConnect); 

Серверный движок

socket.on('state', (game) => < GAME = game; PLAYER = game.players[socket.id]; dt = 0; >); const drawLoop = () => < if (GAME) < now = performance.now(); dt = dt + (now - last); const dtPercent = dt / engineTimeConnect; last = now; context.clearRect(0, 0, WINDOW_WIDTH, WINDOW_HIGHT); // Рисуем игроков for (const id in GAME.players) < const player = GAME.players[id]; if (player.state !== 'DEATH') < drawPlayer(context, player, dtPercent); >> > window.requestAnimationFrame(drawLoop); >; window.requestAnimationFrame(drawLoop); 

Клиентский движок

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

const movement = < up: false, down: false, left: false, right: false, >document.addEventListener("keydown", (event) => < switch (event.keyCode) < case 65: // A movement.left = true; socket.emit("movement", movement); break; case 87: // W movement.up = true; socket.emit("movement", movement); break; case 68: // D movement.right = true; socket.emit("movement", movement); break; case 83: // S movement.down = true; socket.emit("movement", movement); break; >>); document.addEventListener("keyup", (event) => < switch (event.keyCode) < case 65: // A movement.left = false; socket.emit("movement", movement); break; case 87: // W movement.up = false; socket.emit("movement", movement); break; case 68: // D movement.right = false; socket.emit("movement", movement); break; case 83: // S movement.down = false; socket.emit("movement", movement); break; >>); 

Клиентский код

const movement = < up: false, down: false, left: false, right: false, >; socket.on('movement', (move) => < movement.up = move.up; movement.down = move.down; movement.left = move.left; movement.right = move.right; >); setInterval(() => < if (movement.down||movement.left||movement.right||movement.up) < const player = players[socket.id] || <>; if (movement.left && player.positionX > 0) < player.moveTo('left'); >if (movement.up && player.positionY > 0) < player.moveTo('up'); >if (movement.right && player.positionX < map.size.x) < player.moveTo('right'); >if (movement.down && player.positionY < map.size.y) < player.moveTo('down'); >> else < const player = players[socket.id] || <>; player.moveTo && player.moveTo('stop'); > >, engineTimeConnect); 

Серверный код

Это весь цикл перемещения игрока. Кроме того, для удобства в дальнейших кейсах мы решили задавать игроку состояние. Ниже пример метода перемещения игрока.

moveTo(direction)

Когда мы поняли, что движущиеся точки — это конечно круто, но недостаточно, решили пуститься «во все тяжкие» и делать мультиплеерный шутер. Первое, что мы сделали — проработали концепцию, отбросив все лишнее. После — упростили графику ( от того, что нарисовало богатое воображение в наших головах до реализуемого варианта). Затем перешли к тому, что создали персонажей и их способности к стрельбе.

Создать JS-игру с мультиплеером за 24 часа и выжить 2

Было много спорных моментов, обсуждений, далеко не всегда получалось прийти к компромиссу. И, конечно, были эпизоды, в которых спорить было не о чем, потому что мы просто не знали, как это воплотить.

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

Еще пример: мы не знали, что делать с ФПС ( наша бравая лошадка-сервер вывозила не больше 4 человек, а после грустно ложилась помирать). Происходило это по нескольким причинам: чем больше клиентов, тем больше данных нужно отправлять, а данные отправлялись 60 раз в секунду, на 8 игроках игровой цикл замедлялся до 15 циклов в секунду. Однако для оптимизации процессов было еще слишком рано, готовой игровой модели еще не было, и мы продолжили разработку.

Мы круто упростили модель передачи данных для выстрелов с помощью линейной интерполяции и сделали, в целом, много всего интересного (в первую очередь, для улучшения игрового процесса). Вот первый этап оптимизации для нашего серверного движка.

Создать JS-игру с мультиплеером за 24 часа и выжить 3

// линейная интерполяция, piece = 0.0 -> 1.0 const lerp = (start, finish, piece) => < return start + (finish - start) * piece; >; const drawProjectile = (ctx, bullet, dt) =>

Отрисовка снарядов на клиенте

Также мы решили использовать пулинг для снарядов на сервере, хранили готовые инстансы снарядов в массиве и добавляли их при каждом выстреле, а после возвращали в пул для хранения. Это положительным образом влияло на нагрузку сервера.

Как я написал кастомный шрифт ради одного символа. Но сначала неделю страдал

Следующим этапом стала обработка столкновений. Первая наша попытка была просто ужасной: была куча блоков if/else, но все работало, однако глядя на такой код, хотелось плакать. Поэтому мы решили сделать все области столкновений в игре круговыми и обратиться к геометрии.

Создать JS-игру с мультиплеером за 24 часа и выжить 4

const getCollision = (obj1, obj2) => < const r = obj1.r + obj2.r; const dX = obj1.x - obj2.x; const dY = obj1.y - obj2.y; const xSq = dX * dX; const ySq = dY * dY; const dSq = xSq + ySq; const d = Math.sqrt(dSq); return r >d; >; 

Реализация с помощью кода

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

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

Самым эмоциональным для меня стал момент записи звуков для игры. За неимением других источников нам пришлось имитировать их самим. Мы бегали вокруг стола, стучали кружками и делали что-то еще. К тому моменту прошло уже много часов хакатона, мозг немного был затуманен, что в некоторых моментах даже сыграло нам на руку. Особенно смешным и немного нелепым получился звук попадания снаряда — представьте, как рыба пытается сказать букву «П».

А что в результате?

В нашем случае результатом стал мультиплеерный 2D шутер с видом сверху. Игроки сражались каждый сам за себя, количество патронов было ограничено, но на на карте постоянно появлялись случайные объекты в виде (дополнительных патронов, усиления урона, аптечки), эти объекты создавали точки интереса на карте и вынуждали игроков постоянно двигаться, чтобы выиграть бой, от этого игра становилась более динамичной и веселой. При поражении игрок выбывал с карты на некоторое время, а после опять мог вступить в бой. На следующий день после хакатона, мы рубились в эту игрой с ребятами из офиса, и, как оказалось, шутер получился веселым и залипательным, что нас очень сильно порадовало.

Создать JS-игру с мультиплеером за 24 часа и выжить 5

Простые игры на Canvas в браузере могут сделать ваше приложение более интерактивным. Например, простой игрой вы можете заменить скучные и долгие экраны загрузок. А написание полноценных браузерных игр на JS может стать отличной альтернативой разработке однотипных, скучных приложений. Вердикт: геймдеву на JS быть!

Следите за новыми постами по любимым темам

Подпишитесь на интересующие вас теги, чтобы следить за новыми постами и быть в курсе событий.

Игра на чистом JavaScript за 20 минут

Игра на чистом JavaScript за 20 минут

На JS можно создавать сложные и простые игры любых жанров. Мы расскажем как создать 2D игру на JavaScript и HTML5 всего за 20 минут.

Для создания веб игр на языке JavaScript используется технология Canvas , которая позволяет выполнять JavaScript код в HTML5 документе. Вы можете более детально ознакомиться с этой технологией посмотрев видео ниже:

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

      Flappy Bird!    

В JS файле необходимо найти нужный канвас по id и указать способ работы с ним.

var cvs = document.getElementById("canvas"); var ctx = cvs.getContext("2d");

Добавление изображений и аудио

Далее необходимо загрузить все изображения, а также аудио файлы, которые будут использоваться в игре. Для этого используйте класс Image и Audio соответсвенно. Ниже вы можете скачать все необходимые картинки, а также аудиофайлы к игре.

  • Скачать аудио файлы можно по этой ссылке ;

Код добавления изображений и аудио в игру:

var bird = new Image(); var bg = new Image(); // Создание объекта var fg = new Image(); // Создание объекта var pipeUp = new Image(); // Создание объекта var pipeBottom = new Image(); // Создание объекта bird.src = "img/bird.png"; // Указание нужного изображения bg.src = "img/bg.png"; // Аналогично fg.src = "img/fg.png"; // Аналогично pipeUp.src = "img/pipeUp.png"; // Аналогично pipeBottom.src = "img/pipeBottom.png"; // Аналогично // Звуковые файлы var fly = new Audio(); // Создание аудио объекта var score_audio = new Audio(); // Создание аудио объекта fly.src = "audio/fly.mp3"; // Указание нужной записи score_audio.src = "audio/score.mp3"; // Аналогично

Рисование объектов

Чтобы нарисовать объекты, а также добавить функционал к игре необходимо прописать функцию, которая будет постоянно вызываться. Такую функцию вы можете назвать как вам будет угодно. Главное, вам нужно вызвать эту функцию из вне её хотя бы один раз, а внутри неё прописать метод requestAnimationFrame , который будет вызывать функцию постоянно.

function draw() < // Какой-либо код requestAnimationFrame(draw); // Вызов функции постоянно >draw(); // Вызов функции из вне

Весь код игры стоит помещать в этот метод, ведь в нем он будет постоянно обрабатываться и игра будет выглядеть живой и анимированной.

Чтобы отследить нажатие игрока на какую-либо клавишу, необходимо использовать отслеживание событий — addEventListener . К примеру, чтобы отследить нажатие на любую клавишу на клавиатуре надо прописать следующий код:

// При нажатии на какую-либо кнопку document.addEventListener("keydown", someMethod); // Вызывается метод someMethod function someMethod() < // Изменяем что-то в коде >

Видео урок

Это были лишь небольшие азы перед созданием самой игры. Предлагаем вам ознакомиться с небольшим видео уроком, в ходе которого вы создадите небольшую 2D игру на чистом JavaScript’е.

Весь JS код игры

Ниже вы можете посмотреть на полностью весь код JavaScript файла, который был создан в ходе видео урока выше:

var cvs = document.getElementById("canvas"); var ctx = cvs.getContext("2d"); var bird = new Image(); var bg = new Image(); var fg = new Image(); var pipeUp = new Image(); var pipeBottom = new Image(); bird.src = "img/bird.png"; bg.src = "img/bg.png"; fg.src = "img/fg.png"; pipeUp.src = "img/pipeUp.png"; pipeBottom.src = "img/pipeBottom.png"; // Звуковые файлы var fly = new Audio(); var score_audio = new Audio(); fly.src = "audio/fly.mp3"; score_audio.src = "audio/score.mp3"; var gap = 90; // При нажатии на какую-либо кнопку document.addEventListener("keydown", moveUp); function moveUp() < yPos -= 25; fly.play(); >// Создание блоков var pipe = []; pipe[0] = < x : cvs.width, y : 0 >var score = 0; // Позиция птички var xPos = 10; var yPos = 150; var grav = 1.5; function draw() < ctx.drawImage(bg, 0, 0); for(var i = 0; i < pipe.length; i++) < ctx.drawImage(pipeUp, pipe[i].x, pipe[i].y); ctx.drawImage(pipeBottom, pipe[i].x, pipe[i].y + pipeUp.height + gap); pipe[i].x--; if(pipe[i].x == 125) < pipe.push(< x : cvs.width, y : Math.floor(Math.random() * pipeUp.height) - pipeUp.height >); > // Отслеживание прикосновений if(xPos + bird.width >= pipe[i].x && xPos = pipe[i].y + pipeUp.height + gap) || yPos + bird.height >= cvs.height - fg.height) < location.reload(); // Перезагрузка страницы >if(pipe[i].x == 5) < score++; score_audio.play(); >> ctx.drawImage(fg, 0, cvs.height - fg.height); ctx.drawImage(bird, xPos, yPos); yPos += grav; ctx.fillStyle = "#000"; ctx.font = "24px Verdana"; ctx.fillText("Счет: " + score, 10, cvs.height - 20); requestAnimationFrame(draw); > pipeBottom.onload = draw; 

Больше интересных новостей

Проблема специфичности CSS и ключевое слово !important

Проблема специфичности CSS и ключевое слово !important

ТОП 10 полезных возможностей Google Карт

ТОП 10 полезных возможностей Google Карт

7 ошибок, которые мешают разработчику построить успешную карьеру

7 ошибок, которые мешают разработчику построить успешную карьеру

Продвижение в соц сетях: SMM, SMO и SMM-специалисты

Продвижение в соц сетях: SMM, SMO и SMM-специалисты

Комментарии (2)

RInat 05 мая 2023 в 17:32

Создание игр на JavaScript с нуля?

Очень сильно хочу научиться делать игры. Просто очень сильно. Чисто для себя, в качестве маленького хобби. Начиная с самого маленького, с совершенных азов — каких-нибудь 2d мини платформеров в несколько действий. JavaScript знаю достаточно слабо, в основном использую jQuery для работы. Исходя из этих данных, я прошу вас подсказать материалы, каналы на ютубе, что угодно, где люди рассказывают, как С НУЛЯ делать игрушки на JS. Применяя инструменты языка и объясняя, как у них это все происходит. Я ничего адекватного не нашел, везде или просто общая информация по методологии написания игр, или уже сложные алгоритмы, в которых мне например, вот так сразу, разобраться нет никакой возможности. Короче парни, большое вам спасибо заранее, надеюсь, что у вас что-то есть интересное)

  • Вопрос задан более трёх лет назад
  • 16417 просмотров

Комментировать
Решения вопроса 4

Dit81

Security researcher, pentester, internet-marketer

Лучше начать с изучения Canvas и простой анимации. Типа отскока и перемещений кругов и прямоугольников. Затем посмотреть в сторону HTML5 фреймворков, типа pixi.js, panda.js, phaser. Последний включает почти все, что нужно для создания аркадных платформеров. Но мне показался слишком большим и сложным. 🙂 Сам сейчас пишу свою основу для платформеров и естественно свой велосипед. Буду рад обмену опытом и идеями! ))

Ответ написан более трёх лет назад
Нравится 1 1 комментарий

Dit81

Вот небольшое пошаговое введение в создание простой игры (англ.) 🙂 www.iguanademos.com/Jare/docs/html5/Lessons

Open Source enthusiast

При достаточно слабых знаниях JS вам нечего даже сунуться делать игры.
Почитайте лучше сначала про JS, а потом всё остальное.
Рекомендую JavaScript. Подробное руководство Дэвида Флэнагана.

Ответ написан более трёх лет назад
Джон Голт @Fargal_1 Автор вопроса

Ну слабое в том плане, что я сам с нуля не могу сделать что-то рабочее в плане игр. Пишу в основном скрипты для работы с DOM. И, если так, то я знаю синтаксис, принципы ООП и как они в общем-то реализованы в JS. Флэнагана периодически и так открываю, разумеется.

Джон Голт: Тогда я бы рекомендовал для начала всё-таки углубиться в JS, можно поиграться с canvas, например, в fabric.js хорошая документация и достаточно функций для чего-то не очень сложного.

Ketch

Полная чушь. Не понимаю зачем так пугают людей? «При достаточно слабых знаниях JS вам нечего даже сунуться делать игры.» Основ вполне достаточно. Тем более что есть программы, которые сильно упрощают процесс создании.. и такие вещи как определения столкновений, поиск пути, физика в них уже заложены и самостоятельного описания не требуют. Вот вам к примеру — Tulullo Game Maker, абсолютно бесплатный и легкий в освоении, но не кем не развивается уже. Game Maker Studio 2: HTML5 уже платный (но в стиме можно купить дешевле чем на оф. сайте)

Помню как то читал статью на хабре по созданию простого платформера на js, так вот, там парень мучался.. куча строк кода, супер-вычисления.. формулы по просчету пути между двумя точками, растянул все это дело на 3-4 статьи, а результат — прыгающий квадрат, собирающий бонусы)) То же самое, можно реализовать на Tulullo Game Maker примерно за 15 минут))) За 15 минут, Карл!

Не забывайте, что важна сама идея игры, а не способ ее реализации.
Писать с нуля игру на js и html5 без фреймворков, конструкторов. — гиблое и неблагородное дело. Время будет затрачено уйма — как на обучение так и написание, а результат будет не ясно какой.

Представьте, пока вы будете с чувством собственного удовлетворения разрабатывать с нуля очередной «велосипед», потратив на него месяц, два.. три.. Кто-то другой, за это время, реализует 3-4 идеи на игровом движке, делая упор на сюжет, идею игры. А вы, неясно допишите ли еще свой «шедевр», ведь за такое время интерес к проекту может пропасть, что неудивительно когда разработка затягивается на длительный срок.

www.stencyl.com — вот вам еще, не требует программирования. Только визуальное.

P.S. Развитие всех технологий, языков программирования приводит неизбежно к шаблонизации и автоматизации рутинных процессов.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *