Cегодня мы проведем тебя через создание игры "Крестики-нолики" на JavaScript. Эта игра отлично подходит для того, чтобы потренироваться в программировании и понять, как взаимодействовать с HTML, CSS и JavaScript! ⭐
Если ты уже немного знаком с программированием и хочешь создать что-то своё, эта статья поможет тебе разобраться в основах. А для полного исходного кода можешь перейти на GitHub и увидеть проект в действии. Давай начнем!
Для полного исходного кода и, возможно, дополнительных улучшений, загляни на наш GitHub.
Чтобы создать игру, нам потребуется три файла:
HTML (index.html) - для создания структуры страницы.
CSS (style.css) - для оформления страницы.
JavaScript (script.js) - для написания логики игры.
HTML отвечает за структуру, CSS добавляет стиль и делает интерфейс приятным, а JavaScript наполняет игру логикой и интерактивностью. В первую очередь, давай взглянем на HTML-файл, который создает основу нашей игры.
HTML-файл создаёт основу пользовательского интерфейса. Вот так выглядит код (часть файла index.html
):
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Игра "Крестики-нолики" | Coursme</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- окно выбора -->
<div class="select-box">
<header>Крестики-нолики</header>
<div class="content">
<div class="title">Выберите, кем вы хотите быть?</div>
<div class="options">
<button class="playerX">Игрок (X)</button>
<button class="playerO">Игрок (O)</button>
</div>
</div>
</div>
<!-- игровое поле -->
<div class="play-board">
<div class="details">
<div class="players">
<span class="Xturn">Ход X</span>
<span class="Oturn">Ход O</span>
<div class="slider"></div>
</div>
</div>
<div class="play-area">
<section>
<span class="box1"></span>
<span class="box2"></span>
<span class="box3"></span>
</section>
<section>
<span class="box4"></span>
<span class="box5"></span>
<span class="box6"></span>
</section>
<section>
<span class="box7"></span>
<span class="box8"></span>
<span class="box9"></span>
</section>
</div>
</div>
<!-- окно результата -->
<div class="result-box">
<div class="won-text"></div>
<div class="btn"><button>Играть снова</button></div>
</div>
<script src="script.js"></script>
</body>
</html>
В этом HTML-коде создаются три основных раздела:
Окно выбора игрока - где игрок выбирает, будет ли он X или O.
Игровое поле - основной интерфейс, где игроки делают свои ходы.
Окно результата - отображает победителя или ничью.
Эти три раздела создают основу нашего игрового процесса и делают интерфейс понятным и простым для использования.
Файл style.css
отвечает за внешний вид игры. Вот несколько ключевых моментов:
Фон игры окрашен в приятный фиолетовый цвет, что делает интерфейс ярким и приятным.
Кнопки выбора игрока имеют плавную анимацию при наведении, что делает взаимодействие с игрой более увлекательным.
Игровое поле разделено на ячейки, каждая из которых подсвечивается при наведении, что помогает игрокам интуитивно понимать, куда они могут сделать ход.
Пример кода из style.css
:
body{
background: #6563FF;
color: #e0e0e0;
}
.play-area section span{
display: block;
height: 90px;
width: 90px;
margin: 2px;
color: #fff;
font-size: 40px;
line-height: 80px;
text-align: center;
border-radius: 5px;
background: #1e1e1e;
}
Этот стиль делает нашу игру визуально привлекательной и удобной для использования. Ячейки игрового поля аккуратно оформлены, чтобы каждый ход был четко виден, и игроки могли легко ориентироваться на игровом поле.
Теперь переходим к самому интересному - JavaScript!
JavaScript - это то, что делает нашу игру интерактивной. Посмотрим, как работает наш script.js
файл, начиная с простого выбора игрока до определения победителя.
Когда игра загружается, мы сразу инициализируем некоторые элементы и добавляем события для кнопок выбора игрока. Вот как это делается:
// выбор всех необходимых элементов
const selectBox = document.querySelector(".select-box"),
selectBtnX = selectBox.querySelector(".options .playerX"),
selectBtnO = selectBox.querySelector(".options .playerO"),
playBoard = document.querySelector(".play-board"),
players = document.querySelector(".players"),
allBox = document.querySelectorAll("section span"),
resultBox = document.querySelector(".result-box"),
wonText = resultBox.querySelector(".won-text"),
replayBtn = resultBox.querySelector("button");
window.onload = ()=>{ // после загрузки окна
for (let i = 0; i < allBox.length; i++) { // добавляем атрибут onclick для всех доступных span
allBox[i].setAttribute("onclick", "clickedBox(this)");
}
}
Здесь мы находим все элементы, необходимые для управления игрой, и добавляем события клика для каждой ячейки игрового поля. Это означает, что каждая ячейка становится интерактивной и может реагировать на действия пользователя.
Далее идет выбор игрока:
selectBtnX.onclick = ()=>{
selectBox.classList.add("hide"); // Скрываем окно выбора
playBoard.classList.add("show"); // Показываем игровое поле
}
selectBtnO.onclick = ()=>{
selectBox.classList.add("hide");
playBoard.classList.add("show");
players.setAttribute("class", "players active player"); // Устанавливаем атрибут для игроков
}
Этот код отвечает за то, чтобы показать или скрыть разные части интерфейса в зависимости от того, какой игрок был выбран. Когда выбор сделан, окно выбора исчезает, а игровое поле появляется на экране.
Когда игрок выбирает ячейку на игровом поле, мы хотим, чтобы в этой ячейке появился значок (X или O). Вот как мы реализуем это:
let playerXIcon = "fas fa-times"; // имя класса иконки крестика из FontAwesome
let playerOIcon = "far fa-circle"; // имя класса иконки круга из FontAwesome
let playerSign = "X"; // глобальная переменная, так как мы используем ее в нескольких функциях
let runBot = true; // глобальная переменная с булевым значением, чтобы остановить бота, когда кто-то выиграет или будет ничья
function clickedBox(element){
if(players.classList.contains("player")){
playerSign = "O"; // Если игрок выбрал O
element.innerHTML = `<i class="${playerOIcon}"></i>`;
players.classList.remove("active");
}else{
element.innerHTML = `<i class="${playerXIcon}"></i>`;
players.classList.add("active");
}
element.setAttribute("id", playerSign); // Устанавливаем атрибут id в span/ячейке с выбранным знаком игрока
selectWinner(); // Проверяем, есть ли победитель
element.style.pointerEvents = "none"; // Ячейка больше не может быть выбрана
playBoard.style.pointerEvents = "none"; // Блокируем игровое поле, пока бот не сделает ход
let randomTimeDelay = ((Math.random() * 1000) + 200).toFixed(); // Генерируем случайное время задержки
setTimeout(()=>{
bot(runBot); // Вызываем функцию бота
}, randomTimeDelay);
}
Здесь игрок выбирает ячейку, и она становится недоступной для повторного выбора. Затем происходит переключение хода к боту с небольшой задержкой для создания эффекта реальной игры. Таким образом, игра становится динамичной и интересной.
Функция бота автоматически выбирает следующую доступную ячейку. Бот делает ход после игрока, и его действия также создают впечатление взаимодействия с реальным соперником:
function bot(){
let array = []; // создаем пустой массив...будем хранить индексы невыбранных ячеек
if(runBot){ // если runBot true
playerSign = "O"; // меняем playerSign на O, если игрок выбрал X
for (let i = 0; i < allBox.length; i++) {
if(allBox[i].childElementCount == 0){ // если ячейка не содержит дочерних элементов
array.push(i); // вставляем индекс невыбранных ячеек в массив
}
}
let randomBox = array[Math.floor(Math.random() * array.length)]; // выбираем случайную ячейку
if(array.length > 0){
if(players.classList.contains("player")){
playerSign = "X"; // Если игрок выбрал O, значит бот будет X
allBox[randomBox].innerHTML = `<i class="${playerXIcon}"></i>`;
allBox[randomBox].setAttribute("id", playerSign);
players.classList.add("active");
}else{
allBox[randomBox].innerHTML = `<i class="${playerOIcon}"></i>`;
players.classList.remove("active");
allBox[randomBox].setAttribute("id", playerSign);
}
selectWinner(); // Проверяем, есть ли победитель
}
allBox[randomBox].style.pointerEvents = "none"; // Ячейка больше не может быть выбрана
playBoard.style.pointerEvents = "auto"; // Разрешаем игроку снова кликнуть на ячейку
playerSign = "X"; // Смена хода обратно к игроку
}
}
Функция bot()
добавляет реалистичности игре, так как бот делает выбор автоматически, создавая впечатление живого соперника. Бот выбирает случайную доступную ячейку, и это добавляет элемент неожиданности в игру.
После каждого хода нужно проверять, есть ли победитель. Для этого используется функция selectWinner
:
function selectWinner(){
if(checkIdSign(1,2,3,playerSign) || checkIdSign(4,5,6, playerSign) || checkIdSign(7,8,9, playerSign) || checkIdSign(1,4,7, playerSign) || checkIdSign(2,5,8, playerSign) || checkIdSign(3,6,9, playerSign) || checkIdSign(1,5,9, playerSign) || checkIdSign(3,5,7, playerSign)){
runBot = false; // Останавливаем бота, если кто-то выиграл
setTimeout(()=>{ // Показ результата через 700 мс
resultBox.classList.add("show");
playBoard.classList.remove("show");
}, 700);
wonText.innerHTML = `Игрок <p>${playerSign}</p> выиграл игру!`;
}else{
if(getIdVal(1) != "" && getIdVal(2) != "" && getIdVal(3) != "" && getIdVal(4) != "" && getIdVal(5) != "" && getIdVal(6) != "" && getIdVal(7) != "" && getIdVal(8) != "" && getIdVal(9) != ""){
runBot = false; // Останавливаем бота, если ничья
setTimeout(()=>{ // Показ результата через 700 мс
resultBox.classList.add("show");
playBoard.classList.remove("show");
}, 700);
wonText.textContent = "Матч закончился вничью!";
}
}
}
Функция selectWinner()
проверяет все возможные выигрышные комбинации и определяет, есть ли победитель. Если все ячейки заполнены и никто не выиграл, игра завершается вничью. Это делает игру завершенной и логически завершает каждый раунд.
Поздравляю! Теперь ты знаешь, как создать простую игру "Крестики-нолики" с использованием HTML, CSS и JavaScript. Мы прошли через каждый шаг, чтобы создать приятный пользовательский интерфейс, добавить стили и создать логику игры. Теперь ты понимаешь, как работают взаимодействия между HTML, CSS и JavaScript, и как они могут совместно создавать полноценное веб-приложение.
Ты можешь использовать этот проект как основу для создания более сложных игр или даже расширить функциональность этой игры. Например, добавить счётчик побед, улучшить графику или сделать игру многопользовательской. Возможности бесконечны, и всё зависит только от твоей фантазии и креативности!
Для полного исходного кода и, возможно, дополнительных улучшений, загляни на наш GitHub.
Если у тебя возникнут вопросы, не стесняйся задавать их. Удачи в программировании, и пусть твои проекты всегда будут такими же интересными и увлекательными! 👊🌟
Не нашли нужной статьи?
Напишите нам и ее сделаем!