Для создания веб игр на языке  используется технология Canvas, которая позволяет выполнять JavaScript код в  документе. Вы можете более детально ознакомиться с этой технологией посмотрев видео ниже:
На html странице прописывается лишь тег канвас, а также подключение JS файла, в котором будет происходить обработка всей функциональности. К примеру, HTML файл может выглядеть следующим образом:
<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Flappy Bird!</title>
</head>
<body>
 <canvas id="canvas"  ></canvas>
 <script src="js/game.js"></script>
</body>
</html>
В 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'е.
Ниже вы можете посмотреть на полностью весь код 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].x + pipeUp.width
 && (yPos <= pipe[i].y + pipeUp.height
 || yPos + bird.height >= 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;