Создание простой веб-игры за 10 шагов
Когда вы начинаете заниматься веб-разработкой, перед вами встают многоуровневые задачи, и покорение javascript - одна из них! По моему опыту, изучать javascript лучше всего на практике. Можно просмотреть тонну обучающих видео, думать, что все понял, а в итоге получить очень неправильный код.
В этой статье мы рассмотрим пример создания простой игры на JS с нуля. В этой задаче вам предстоит отработать некоторые начальные и основные принципы программирования на javascript. В качестве бонуса вы даже получите небольшой урок по HTML и CSS.
Давайте сразу перейдем к тому, что мы будем строить!
Сегодня мы будем собирать популярную британскую игру под названием Simon.
На собственном опыте я убедился, что секрет решения задач кодирования заключается в том, чтобы, прежде всего, понять, что от тебя требуется. Для этого нам необходимо понять, как работает игра Simon. Найти обучающее видео на youtube можно здесь.
Давайте я постараюсь объяснить.
Это, прежде всего, игра на запоминание деталей. Игра построена таким образом, что есть четыре коробки. Каждая коробка разного цвета. Игра начинается с заголовка "Нажмите любую клавишу, чтобы играть". После этого коробка (определенного цвета) подсвечивается, и через миллисекунду подсветка исчезает. Это первый паттерн. Остается щелкнуть на выделенном квадратике. Вы успешно запомнили первую деталь.
В игре выделяется ещё один цвет...
Но помните, что все дело в закономерностях. Если вы нажмете на следующий выделенный шаблон, вы потерпите неудачу! (Я понял это на собственном опыте). Поскольку это игра с узорами, вы должны запомнить первый выделенный цвет (квадрат) и начать с него.
Пример: Шаблоны отображаются в таком порядке:[Синий] 1-е выделение: играть [синий 🔵]
[Красный] 2-е выделение: играть [синий 🔵][красный 🔴]
[Зелёный] 3-е выделение [синий 🔵][красный 🔴][зеленый 🟢]
[Синий] 4-я игра [синий 🔵][красный 🔴][зеленый 🟢][синий 🔵]....
Игра продолжается в непрерывном цикле до тех пор, пока вы не пропустите паттерн, после чего она перезапускается.
Ознакомиться с игрой можно здесь.
Так как это не руководство по HTML или CSS, я просто оставлю ссылки на HTML и CSS коды. Вы можете взять их, запустить в удобном для вас редакторе кода, открыть файл javascript и приступить к работе!
Шаг 1
Первое, о чем мы должны подумать, это то, что нам необходимо определить цвета кнопок. В моем HTML-файле вы можете видеть, что у нас есть четыре div с идентификаторами разных цветов (красный, синий, зеленый и желтый), чтобы идентифицировать каждый блок отдельно. Мы можем сделать это в нашем javascript, прежде всего создав массив:
var buttonColors = ["red", "blue", "green", "yellow"];
Шаг 2
Нам нужен способ хранения паттернов, которые будет придумывать игра, а также паттернов, которые будет создавать наш пользователь (играя в игру), чтобы мы могли их отслеживать:
var gamePattern = []; var userClickedPattern = [];
Шаг 3
Нам необходимо создать функцию, позволяющую игре выбирать, какую из кнопок она хочет добавить в последовательность. Из объяснения игры мы помним, что это не жесткая структура, то есть компьютер выдает случайные паттерны. Для этого создадим нашу функцию и получим случайную переменную.
function nextSequence() { var randomNumber = Math.floor(Math.random()*4);}
Мы умножаем наше случайное число на 4, чтобы получить значения от 0 до 3. Используем метод Math.floor
для удаления плавающей точки из нашего числа.
Шаг 4
Нам необходимо использовать переменную randomized
для выбора случайного индекса из массива buttonColors
. Также необходимо найти способ добавления значения выбранного индекса (первой последовательности в игре) в массив шаблонов игры.
var randomChosenColor = buttonColors[randomNumber]; gamePattern.push(randomChosenColor);
Шаг 5
Теперь мы добавим немного анимации, которая будет служить визуальным сигналом, указывающим на то, какой цвет (квадрат) был выбран компьютером.
Для этого создадим функцию затухания и выключения.
function fadeOut(randomChosenColor) {
var opacity = 1; // Initial opacity
var interval = setInterval(function() {
if (opacity > 0) {
opacity -= 0.1;
document.querySelector('#'
+randomChosenColor).style.opacity = opacity;
} else {
clearInterval(interval); // Stop the interval
when opacity reaches 0
document.querySelector('#'
+randomChosenColor).style.display = 'none'; //
Hide the element
}
}, 50);
}
fadeOut(randomChosenColor);
Мы использовали селектор document.querySelector
для указания нужного нам HTML-элемента. То, что нам нужно, идентифицируется с помощью id, поэтому мы использовали селектор id '#'
. Кроме того, поскольку мы не задаем жестко определенное значение, а позволяем компьютеру выбирать его случайным образом, нам пришлось написать код таким образом, чтобы выбор осуществлялся из нашей переменной chosenRandomColor
.
Наша функция nextSequence
должна выглядеть следующим образом:
function nextSequence() {
userClickedPattern = [];
var randomNumber = Math.floor(Math.random()*4);
var randomChosenColor = buttonColors[randomNumber];
gamePattern.push(randomChosenColor)
function fadeOut(randomChosenColor) {
var opacity = 1; // Initial opacity
var interval = setInterval(function() {
if (opacity > 0) {
opacity -= 0.1;
document.querySelector('#'
+randomChosenColor).style.opacity = opacity;
} else {
clearInterval(interval); // Stop the interval
when opacity reaches 0
document.querySelector('#'
+randomChosenColor).style.display = 'none'; //
Hide the element
}
}, 50);
}
fadeOut(randomChosenColor);
}
Шаг 6
В дополнение к визуальному сопровождению, представленному в предыдущей функции, мы можем добавить звуковые подсказки. Мы будем делать это в функции playSound()
. Звук, используемый в данном проекте, можно найти в репозитории github. Мы будем использовать стандартный класс audio
в javascript.
function playSound(audioName) {
var audio = new Audio("sounds/" + audioName + ".mp3");
audio.play();
}
*Наша функция принимает параметр audioName
, и с помощью этого параметра мы передаем значение имени звука, который хотим использовать. Получив в свое распоряжение стандартный класс audio
в javascript, мы перешли к получению различных звуков, задав ему "филер" с помощью параметра audioName
. Реализацию этого мы увидим в следующих функциях.*
Шаг 7
Нам необходимо создать функцию, которая поможет пользователю понять, какую кнопку он нажал. Для этого необходимо добавить некую визуальную подсказку о том, какая кнопка была нажата пользователем.
function animatePress(currentColor) {
document.querySelector("#" + currentColor).classList.add("pressed");
setTimeout(function () {
document.querySelector("#" + currentColor).classList.remove("pressed");
}, 100);
}
*В нашем файле styles.css
есть класс с именем 'pressed
'. Здесь мы использовали javascript для отключения и включения класса pressed
. Переключение этого класса просто увеличивает и уменьшает непрозрачность. Обратите внимание, что мы использовали функцию setTimeout
для установки длительности выключения и включения.*
Шаг 8
Пока что наша игра выглядит хорошо, но нет способа отследить, следует ли пользователь заданному компьютером шаблону, и именно для этого предназначена следующая функция. Мы пишем наш первый оператор if
.
if (gamePattern[currentLevel] === userClickedPattern[currentLevel]) {
if (userClickedPattern.length === gamePattern.length){
setTimeout(function () {
nextSequence();
}, 1000);
}
}
*В этом операторе if
мы проверяем совпадение индекса шаблона игры с индексом шаблона пользователя. Это позволит нам узнать, когда пользователь перебрал или недобрал последовательность. Также проверяется, что длина каждого из массивов одинакова. Если оба случая оказываются верными, то срабатывает наша предыдущая функция nextSequence
.*
Разумеется, нам необходимо завершить этот процесс оператором else
, который будет проверять, не получил ли пользователь правильную последовательность.
else {
playSound("wrong");
document.querySelector("body").classList.add("game-over");
setTimeout(function() {
document.querySelector("body").classList.remove("game-over");
}, 200);
document.querySelector("h1").innerText("Game over! Press Any Key To Restart");
//startOver()
}
*В этом операторе else
мы запускаем еще один игровой класс CSS game-over
, выключая и включая его. Здесь присутствует закомментированная функция. Вы поймете ее позже, так как она будет объяснена вкратце.*
Наша конечная функция должна выглядеть следующим образом:
function checkAnswer(currentLevel) {
if (gamePattern[currentLevel] === userClickedPattern[currentLevel]) {
if (userClickedPattern.length === gamePattern.length){
setTimeout(function () {
nextSequence();
}, 1000);
}
} else {
playSound("wrong");
document.querySelector("body").classList.add("game-over");
setTimeout(function() {
document.querySelector("body").classList.remove("game-over");
}, 200);
document.querySelector("h1").innerText("Game over! Press Any Key To Restart");
//startOver();
}
}
Шаг 9
Нам нужно, чтобы пользователь мог играть в игру. То есть мы должны добавить функциональность нашим кнопкам. Для этого мы будем использовать метод .click
. В функции, которая будет включена в этот метод, нужно указать список того, что мы хотим, чтобы происходило с помощью функций, которые мы уже сделали.
document.querySelector(".btn").addEventListener('click', function() {
var userChosenColour = document.querySelector(this).getAttribute("id");
userClickedPattern.push(userChosenColour);
playSound(userChosenColour);
animatePress(userChosenColour);
checkAnswer(userClickedPattern.length-1)
});
*Когда мы нажмем эту кнопку, произойдет множество событий. Первое, что мы делаем, - это перехватываем id нажатой кнопки и сохраняем его в userChosenColor
нашей нажатой кнопки. Для этого используется ключевое слово 'this'. Затем мы заполняем наш массив userClickedPattern
, конечно же, тем цветом, который выбрал пользователь. Приведем несколько уже определенных функций, которые принимают в качестве аргументов цвет UserChosenColor
.*
Шаг 10
Наконец-то! Нам нужен способ сделать так, чтобы пользователь мог перезапустить игру, если он пропустил какую-либо последовательность. Этого мы добьемся с помощью функции startOver
. Сначала нам нужно создать переменную в начале нашего файла, которая будет отслеживать, началась игра или нет: var started = false;
.
Тогда наша функция приобретает следующий вид:
function startOver() {
gamePattern = [];
started = false;
}
Здесь видно, что в нашей функции мы просто перезапускаем всё и убеждаемся, что всё начинается с чистого листа. Пожалуйста, вернитесь к функции проверки ответа (check answer
) и откомментируйте нашу функцию startOver()
.
Мы уже на финишной прямой, ребята!!!
И последнее, что нам нужно, - это способ отслеживать момент начала игры.
document.querySelector(document).addEventListener('keyDown', function() {
if (!started) {
document.querySelector("h1").innerText("Level " + level);
nextSequence();
started = true;
}
});
Ура!!! Мы закончили наш первый проект на javascript! Написание этой статьи было очень увлекательным занятием. Я надеюсь, что вы почувствуете то же самое, когда создадите эту игру и покажете её своим друзьям.
Спасибо, что заглянули!