Перейти к содержимому

Как написать игру на javascript

  • автор:

Разработка игры на JavaScript «Найди Пару»

JavaScript — это мощный язык программирования, который стал фундаментом современной веб-разработки. Он позволяет разработчикам создавать интерактивные и динамичные веб-страницы. JavaScript работает на клиентской стороне браузера, обеспечивая возможность взаимодействия пользователя с веб-страницей без перезагрузки страницы.

Основные области применения JavaScript включают:

  1. Управление Элементами HTML: JavaScript может изменять содержимое HTML, стили и даже структуру документа (DOM).
  2. Реакция на Пользовательские События: Язык позволяет обрабатывать действия пользователя, такие как клики, наведение курсора, ввод текста и многое другое.
  3. Анимации и Графика: JavaScript используется для создания анимаций и игровой графики, что делает веб-страницы более привлекательными и интерактивными.
  4. Формы и Валидация Данных: Проверка вводимых данных на стороне клиента выполняется с помощью JavaScript, что улучшает пользовательский опыт и безопасность.
  5. Веб-Приложения: JavaScript лежит в основе многих современных веб-приложений, включая одностраничные приложения (SPA), использующие фреймворки вроде React, Angular, Vue.js.

Общее Представление о Проекте Игры «Найди Пару»

Игра «Найди пару» — это простой, но увлекательный проект, который поможет начинающим веб-разработчикам понять основы JavaScript, HTML и CSS. Игра состоит из игрового поля с картами, которые нужно переворачивать, чтобы найти пары одинаковых изображений.

Основные особенности проекта:

  • Интерактивность: Игрок кликает на карты, чтобы перевернуть их и найти пары.
  • Логика JavaScript: Скрипт контролирует игровую механику, включая случайное распределение карт, обработку переворота карт и проверку на совпадение.
  • Стили CSS: Визуальное оформление игры, включая расположение карт на игровом поле и анимации переворота.
  • HTML-структура: Основа игры, определяющая размещение элементов на странице.

Цель данного руководства — научить начинающих разработчиков созданию игры «Найди пару», объяснив ключевые концепции и методы работы в области веб-разработки. Вы узнаете, как применять JavaScript для создания интерактивной игры, стилизовать элементы с помощью CSS и строить структуру страницы с использованием HTML. Этот проект является отличным стартом в мир веб-разработки и программирования.

Настройка Рабочего Окружения

Выбор и Установка Подходящего Редактора Кода

Visual Studio Code (VS Code)

Visual Studio Code, разработанный Microsoft, является одним из самых популярных редакторов кода среди веб-разработчиков. Он бесплатный, легкий и поддерживает широкий спектр языков программирования, включая JavaScript.

Шаги Установки:

  1. Скачивание: Перейдите на официальный сайт VS Code и скачайте версию редактора, соответствующую вашей операционной системе (Windows, MacOS, Linux).
  2. Установка: Запустите скачанный установочный файл и следуйте инструкциям мастера установки.
  3. Настройка: После установки вы можете настроить VS Code под свои нужды, установив различные расширения и темы оформления. Например, расширение Live Server позволяет запускать локальный сервер для быстрой загрузки ваших веб-страниц.

Обзор Основных Инструментов Разработчика в Браузере

Инструменты разработчика в Google Chrome

Браузер Google Chrome предлагает мощный набор инструментов для веб-разработчиков, позволяя быстро диагностировать проблемы и тестировать код.

  1. Открытие Инструментов Разработчика:
    • Нажмите Ctrl+Shift+I на Windows/Linux или Cmd+Opt+I на MacOS.
    • Или кликните правой кнопкой мыши на странице и выберите «Inspect» («Исследовать»).
  2. Основные Вкладки:
    • Elements: Позволяет просматривать и изменять HTML и CSS в реальном времени.
    • Console: Используется для просмотра сообщений об ошибках JavaScript и выполнения скриптов.
    • Sources: Позволяет просматривать, редактировать и отлаживать код JS.
    • Network: Показывает информацию о сетевой активности, что полезно для оптимизации производительности.
    • Performance: Предоставляет инструменты для анализа производительности веб-страницы.
  3. Практическое Применение:
    • Используйте Elements для экспериментов с стилями и разметкой.
    • Во вкладке Console вы можете тестировать куски JavaScript кода.
    • Network поможет вам понять, какие ресурсы загружаются и как быстро.
    • С помощью Performance вы можете выявить проблемы, связанные с медленной загрузкой страницы или запуском скриптов.

Эти инструменты являются неотъемлемой частью работы веб-разработчика, поэтому важно овладеть ими для эффективной разработки и отладки ваших веб-приложений.

Основы HTML и CSS

Разбор Структуры HTML-Документа Игры

HTML (HyperText Markup Language) является основой любой веб-страницы. Давайте разберем структуру HTML-документа нашей игры «Найди пару».

Структурные Элементы
  1. Doctype и Язык: Документ начинается с , указывающего на стандарт HTML5. Элемент определяет язык содержимого страницы, в данном случае русский.
  2. Head: Внутри , мы указываем мета-теги, такие как для установки кодировки символов. Также здесь находится , задающий название страницы, и ссылка на внешний CSS-файл через .
  3. Body: В содержится основное содержимое вашей веб-страницы.
    • Секции: Используются теги для разделения контента на логические блоки.
    • Контейнеры: Класс wrapper обертывает содержимое, позволяя центрировать и управлять шириной секций.
    • Заголовки и Текст: Заголовки , и параграфы

      используются для описания правил и целей игры.

    • Игровое Поле: Элемент представляет собой контейнер для игровых карточек.
    • Сообщения и Кнопки: Изображения и блоки для сообщений о выигрыше/проигрыше, а также кнопка для перезапуска игры.

Объяснение CSS-Стилей, Используемых в Игре

CSS (Cascading Style Sheets) отвечает за внешний вид веб-страницы. Рассмотрим ключевые стили, используемые в нашей игре.

  1. Сетка (Grid):
    • .grid определяет сетку с четырьмя колонками ( grid-template-columns: repeat(4, 1fr) ) и интервалом между элементами ( gap: 10px ).
  2. Карточки (Cards):
    • .card задает стили для каждой игровой карточки: размеры, фон, выравнивание содержимого, размер шрифта и курсор в виде указателя.
  3. Обертка (Wrapper) и Секции:
    • .wrapper устанавливает максимальную ширину и автоматические отступы для центрирования содержимого.
    • section задает отступы сверху и снизу для каждой секции.
  4. Стили Текста и Кнопок:
    • #errorCount отображает количество оставшихся попыток, выделяя текст красным цветом и увеличенным шрифтом.
    • .button определяет внешний вид кнопки, включая выравнивание текста, шрифт и отступы.
  5. Сообщения Игры (Game Message):
    • .game-message используется для стилизации текста сообщений о выигрыше или проигрыше, задавая размер шрифта и жирность.

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

Подробный Разбор JavaScript Кода

Объяснение DOM (Document Object Model) и Его Роли в JavaScript

Для начала, поговорим о Document Object Model (DOM). DOM – это программный интерфейс, который позволяет скриптам изменять содержимое, структуру и стиль веб-страниц. В JavaScript, DOM предоставляет доступ к HTML- и XML-документам как к древовидной структуре, где каждый узел является объектом. Это означает, что мы можем использовать JavaScript для чтения и изменения элементов веб-страницы динамически.

Инициализация Переменных и Элементов DOM

Давайте теперь рассмотрим начало нашего скрипта:

document.addEventListener('DOMContentLoaded', () => < const gameBoard = document.getElementById('gameBoard'); const errorCountElement = document.getElementById('errorCount'); const restartButton = document.getElementById('restartButton'); . >);

Здесь мы используем document.addEventListener(‘DOMContentLoaded’, . ) , чтобы убедиться, что наш скрипт начнёт выполняться только после полной загрузки DOM. Внутри этого обработчика событий, мы инициализируем переменные, такие как gameBoard , errorCountElement , и restartButton , ссылаясь на соответствующие элементы DOM через их идентификаторы. Это дает нам возможность взаимодействовать с этими элементами в последующем коде.

Функция Создания Игрового Поля ( createBoard )

Функция createBoard отвечает за создание игрового поля:

function createBoard() < for (let i = 0; i < cards.length; i++) < const card = document.createElement('div'); card.classList.add('card'); card.setAttribute('data-id', i); card.addEventListener('click', flipCard); gameBoard.appendChild(card); >>

В этой функции мы создаём HTML-элементы для каждой карточки игры. Используя цикл for , мы проходим по массиву cards , создаём для каждой карточки div элемент, присваиваем ему класс card , устанавливаем атрибут data-id и добавляем обработчик события клика, который вызовет функцию flipCard . В конце, каждая карточка добавляется на игровое поле ( gameBoard ).

Функция Переворота Карты ( flipCard )

Функция flipCard вызывается при клике на карточку:

function flipCard() < let cardId = this.getAttribute('data-id'); chosenCards.push(cards[cardId]); chosenCardsId.push(cardId); this.innerHTML = cards[cardId]; if (chosenCards.length === 2) < setTimeout(checkForMatch, 500); >>

Эта функция получает data-id текущей карточки, добавляет выбранную карту и её идентификатор в массивы chosenCards и chosenCardsId , а затем отображает символ карточки. Если открыто две карточки, вызывается setTimeout(checkForMatch, 500) , чтобы проверить их на совпадение после краткой задержки.

Функция Проверки Совпадения Карт ( checkForMatch )
function checkForMatch() < const allCards = document.querySelectorAll('.card'); const firstCardId = chosenCardsId[0]; const secondCardId = chosenCardsId[1]; if (chosenCards[0] === chosenCards[1] && firstCardId !== secondCardId) < . >else < . >chosenCards = []; chosenCardsId = []; if (matches === cards.length / 2) < gameOver(true); >>

checkForMatch проверяет, совпадают ли символы на двух выбранных карточках. Если карточки совпадают и не являются одной и той же карточкой, они скрываются. Если карточки не совпадают, они переворачиваются обратно. После каждой попытки массивы chosenCards и chosenCardsId очищаются. Если найдены все пары, вызывается gameOver(true) .

Функция Обработки Окончания Игры ( gameOver )
function gameOver(isWin) < gameBoard.style.display = 'none'; errorCountElement.style.display = 'none'; restartButton.style.display = 'block'; if (isWin) < winImage.style.display = 'block'; winMessage.style.display = 'block'; >else < loseImage.style.display = 'block'; loseMessage.style.display = 'block'; >restartButton.addEventListener('click', () => location.reload()); >

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

Шаги Разработки Игры

Шаг 1: Создание структуры HTML и базовых CSS стилей

1.1 Структура HTML
  • Создайте новый HTML файл.
  • Введите базовую структуру HTML: DOCTYPE , html , head , и body теги.
  • Внутри head , добавьте meta тег для указания кодировки ( charset=»UTF-8″ ) и title для названия вашей страницы.
  • Подключите ваш CSS файл с помощью link тега.
  • В теле ( body ) вашего документа, создайте section элементы, в которых будет размещаться игровое поле и информация о игре.
  • В первом section , добавьте div с классом wrapper , который будет содержать игровое поле, сообщения о выигрыше/проигрыше, счётчик попыток и кнопку перезапуска игры.
  • Во втором section , расположите правила игры и инструкции.
1.2 Базовые CSS Стили
  • Создайте новый CSS файл.
  • Определите стили для класса .grid , установите display в grid , задайте колонки и промежутки ( gap ).
  • Для класса .card , установите размеры, фон, выравнивание текста и курсор.
  • Стилизуйте секции, обертки, счётчик ошибок и кнопки для лучшего визуального представления.

Шаг 2: Написание логики игры на JavaScript

2.1 Инициализация переменных и элементов DOM
  • Создайте файл JavaScript.
  • Используя document.getElementById и document.querySelector , получите доступ к элементам DOM, таким как игровое поле, счётчик ошибок, кнопка перезапуска и т.д.
  • Объявите массив cards с парами эмодзи, которые будут играть роль карт.
  • Инициализируйте переменные для отслеживания выбранных карт, их ID, количества ошибок и найденных пар.
2.2 Функции JavaScript
  • Реализуйте функцию createBoard , которая будет создавать карточки на игровом поле.
  • Напишите функцию flipCard для обработки клика по карте и показа ее значения.
  • Разработайте функцию checkForMatch , чтобы проверять, совпадают ли перевернутые карты.
  • Создайте функцию gameOver для определения конца игры и отображения соответствующих сообщений.

Шаг 3: Тестирование и отладка игры

3.1 Тестирование функций
  • Проверьте каждую функцию отдельно. Убедитесь, что карточки правильно создаются и переворачиваются.
  • Проверьте механизм сопоставления карт: правильно ли исчезают совпадающие карты и уменьшается ли количество попыток при несовпадении.
  • Убедитесь, что игра корректно реагирует на выигрыш и проигрыш.
3.2 Отладка
  • Используйте инструменты разработчика в браузере для отслеживания и исправления ошибок.
  • Проверьте корректность отображения на различных устройствах и браузерах.
  • Убедитесь, что все элементы интерфейса отображаются корректно и соответствуют заданному дизайну.
3.3 Финальное Тестирование
  • Проведите полное тестирование игры, играя в нее несколько раз.
  • Попросите друзей или коллег протестировать игру и дать обратную связь.

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

Дополнительные Функции и Улучшения

Добавление Таймера или Счетчика Очков

1. Добавление Таймера
  • Цель: Добавление таймера увеличивает сложность игры и делает ее более захватывающей.
  • Реализация:
    • В HTML добавьте элемент для отображения времени:
      00:00

      .

    • В JavaScript создайте переменные для учета времени и инициализируйте таймер с помощью setInterval .
    • Напишите функцию для обновления времени на экране и остановки таймера при окончании игры.
    2. Добавление Счетчика Очков
    • Цель: Счетчик очков мотивирует игроков улучшать свои результаты.
    • Реализация:
      • В HTML добавьте элемент для счетчика:
        Очки: 0

        .

      • В JavaScript обновляйте счет при каждом правильном совпадении карт.

      Изменение Дизайна и Темы Игры

      1. Изменение Цветовой Схемы и Фона
      • Используйте CSS для изменения цветовой схемы и фона игрового поля и карточек.
      • Рассмотрите добавление фоновых изображений или градиентов для более привлекательного вида.
      2. Изменение Шрифтов и Стилей Текста
      • Выберите и примените различные шрифты для заголовков и текстовых элементов.
      • Используйте CSS для добавления теней, изменения цвета и размера шрифтов.

      Добавление Звуковых Эффектов и анимаций

      1. Звуковые Эффекты
      • Цель: Звуковые эффекты при перевороте карты и нахождении пары повышают интерактивность игры.
      • Реализация:
        • Добавьте аудиофайлы для различных действий.
        • В JavaScript напишите функции для воспроизведения звуков в соответствующие моменты игры.
        2. Анимации
        • Цель: Анимации делают игру более динамичной и привлекательной.
        • Реализация:
          • Используйте CSS для добавления анимаций переворота карт.
          • Рассмотрите возможность добавления анимаций для эффектов выигрыша или проигрыша.

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

          Тестирование и деплой

          Обзор процесса тестирования JavaScript-приложений

          1. Введение в Тестирование
          • Тестирование – это ключевой этап в разработке приложений, включая JavaScript-проекты. Оно помогает обнаружить ошибки и убедиться в правильности работы приложения перед его запуском в производство.
          2. Типы Тестирования
          • Юнит-тестирование (Unit Testing): Проверка отдельных функций или компонентов кода.
          • Интеграционное тестирование (Integration Testing): Проверка взаимодействия между разными частями приложения.
          • Функциональное тестирование (Functional Testing): Проверка конкретных функций приложения в условиях, максимально приближенных к реальным.
          • Тестирование пользовательского интерфейса (UI Testing): Проверка визуальных элементов и взаимодействия пользователя с приложением.
          3. Инструменты для Тестирования
          • Для JavaScript существуют различные инструменты тестирования, такие как Jest, Mocha, Jasmine и другие. Они позволяют автоматизировать процесс тестирования и обеспечивают эффективное обнаружение ошибок.
          4. Пример Тестирования
          • Примером может служить написание юнит-тестов для функций flipCard и checkForMatch в нашем проекте игры. Тесты должны проверять, правильно ли функции обрабатывают данные и возвращают ожидаемый результат.

          Развертывание игры на веб-сервере или платформе хостинга

          1. Выбор Платформы для Деплоя
          • Существуют различные платформы для хостинга веб-приложений, такие как GitHub Pages, Netlify, Vercel, и Heroku. Выбор платформы зависит от требований к проекту и личных предпочтений.
          2. Подготовка к Деплою
          • Перед деплоем убедитесь, что все файлы проекта организованы и не содержат ошибок. Это включает проверку HTML, CSS и JavaScript файлов, а также удаление ненужных комментариев и оптимизацию кода.
          3. Процесс Деплоя
          • Процесс деплоя обычно включает загрузку файлов проекта на выбранную платформу хостинга. Например, при использовании GitHub Pages, это может быть реализовано путем создания репозитория на GitHub и активации функции GitHub Pages в настройках.
          4. Тестирование после Деплоя
          • После развертывания проекта важно провести финальное тестирование, чтобы убедиться, что все работает корректно в реальных условиях использования.
          5. Обновление и Поддержка
          • После деплоя проекта важно регулярно обновлять его и исправлять возникающие проблемы. Это обеспечивает стабильную работу приложения и хороший пользовательский опыт.

          Промежуточный итог

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

          Подведение итогов проекта

          Поздравляем! Вы только что завершили создание своей первой игры на JavaScript — «Найди пару». Этот проект не только помог вам познакомиться с основами веб-разработки, но и показал, как JavaScript может оживить страницы HTML и создать интерактивный пользовательский интерфейс.

          В ходе этого руководства, вы:

          1. Научились основам HTML и CSS: Вы создали структуру вашей игры, используя HTML, и добавили стили с помощью CSS. Это основа любого веб-сайта или приложения.
          2. Разобрались в JavaScript: Вы написали код, который отвечает за логику игры. Это включает в себя создание игрового поля, обработку кликов по карточкам, проверку на совпадение и отслеживание состояния игры.
          3. Применили концепции DOM: Вы узнали, как JavaScript взаимодействует с HTML через DOM, позволяя манипулировать элементами страницы в реальном времени.
          4. Тестировали и отлаживали вашу игру: Вы убедились, что игра работает без ошибок, и познакомились с процессом отладки.

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

          Добавление советов и рекомендаций для дальнейшего развития навыков веб-разработки после завершения проекта игры на JavaScript является отличным способом обогатить ваше руководство. Вот несколько идей, которые могут быть полезны для читателей, стремящихся улучшить свои навыки и разнообразить свои проекты:

          Расширение Функционала Игры

          1. Добавление Сложных Уровней
            • Разработка разных уровней сложности, например, увеличивая количество карт или уменьшая время на игру.
            • Как это помогает: Улучшает навыки в области алгоритмов и логики, а также понимание управления состоянием в JavaScript.
          2. Интеграция Системы Рейтинга и Счета
            • Введение системы очков за быстрое нахождение пар или штрафов за ошибки.
            • Как это помогает: Развивает способности работы с математическими и логическими операциями, а также понимание UX/UI дизайна.
          3. Добавление Мультиплеерной Функции
            • Реализация возможности игры для двух игроков, где каждый игрок ходит по очереди.
            • Как это помогает: Углубляет знания в области обработки событий и управления состоянием в приложениях.

          Улучшение Внешнего Вида Игры

          1. Адаптивный Дизайн
            • Создание адаптивной верстки, чтобы игра корректно отображалась на различных устройствах.
            • Как это помогает: Усиливает понимание CSS и принципов адаптивного веб-дизайна.
          2. Кастомизация Темы
            • Позволить пользователю выбирать тему оформления из нескольких предложенных вариантов.
            • Как это помогает: Расширяет знания в области работы с DOM и CSS, а также в пользовательском интерфейсе.
          3. Добавление Анимаций
            • Использование CSS анимаций или JavaScript для создания эффектов при перевороте карт и их исчезновении.
            • Как это помогает: Улучшает навыки работы с CSS и JavaScript, а также понимание динамического взаимодействия с пользователем.

          Продвинутые Техники Разработки

          1. Использование Фреймворков
            • Переписать игру с использованием популярного JavaScript фреймворка, например, React или Vue.js.
            • Как это помогает: Помогает освоить современные фреймворки и паттерны разработки.
          2. Работа с API
            • Добавить функциональность для загрузки изображений или данных для карт через внешние API.
            • Как это помогает: Расширяет понимание работы с внешними данными и асинхронным программированием.
          3. Оптимизация производительности
            • Анализ и улучшение производительности игры, например, через оптимизацию алгоритмов и управления памятью.
            • Как это помогает: Улучшает глубокое понимание принципов оптимизации и производительности веб-приложений.

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

          Юрий Савченко

          Привет, моё имя Юрий, и мне 39 лет. Родом из Грозного. Сейчас живу и работаю в Краснодаре, в одном из крупнейших маркетинговых агентств города. Я являюсь основным автором статей на проекте Code4web.

          В основном пишу в такие категории как Javascript, HTML и Офтопик.

          В свободное время я — лютый геймер. Обожаю игры серии Dark Souls и RPG. Это такой мой способ расслабиться и отдохнуть от повседневной рутины.

          Своя игра: создаём собственную «Змейку»

          Не так давно мы разбирали, как искусственный интеллект учится играть в змейку. А теперь мы сами сделаем такую игру, чтобы ей могли насладиться обычные люди. Что нам понадобится:

          • HTML, чтобы можно было играть прямо в браузере;
          • CSS для украшений;
          • JavaScript для самой игры.

          Логика игры

          У классической змейки правила простые:

          • есть поле из клеточек, где случайным образом появляется еда;
          • есть змейка, которая всё время двигается и которой мы можем управлять;
          • если змейка на своём пути встречает еду — еда исчезает, появляется в новом месте, а сама змейка удлиняется на одну клеточку;
          • если змейка врежется в стену или в саму себя, игра заканчивается.

          Чтобы играть было проще, мы сделаем так, чтобы змейка не врезалась в стенки, а проходила сквозь них. Если что — сможете это сами потом настроить в коде, когда захотите посложнее.

          Последовательность наших действий будет такой:

          1. Делаем пустую HTML-страницу.
          2. Настраиваем внешний вид с помощью CSS.
          3. Рисуем игровое поле.
          4. Пишем скрипт, который и будет отвечать за всю игру.

          Делаем HTML-страницу

          С этим всё просто: берём стандартный код и сохраняем его как файл snake.html .

             Змейка  

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

          Настраиваем внешний вид

          За внешний вид на странице у нас отвечает раздел , поэтому мы просто добавим в него CSS-код:

          html, body < height: 100%; margin: 0; >/*Задаём глобальные параметры*/ body < background: black; display: flex; align-items: center; justify-content: center; >/*Делаем границу вокруг игрового поля*/ canvas

          Теперь у нас на странице нет лишних отступов, зато всё по центру, есть чёрный фон и граница вокруг игрового поля. Самое время создать само игровое поле.

          Рисуем игровое поле

          Поле делается очень просто:

          400 пикселей в ширину, столько же в высоту, название поля — game. Этого достаточно, чтобы браузер отобразил холст с такими размерами и позволил нам на нём рисовать.

          Пишем скрипт

          1. Зададим все переменные, которые нам понадобятся.

          // Поле, на котором всё будет происходить, — тоже как бы переменная var canvas = document.getElementById('game'); // Классическая змейка — двухмерная, сделаем такую же var context = canvas.getContext('2d'); // Размер одной клеточки на поле — 16 пикселей var grid = 16; // Служебная переменная, которая отвечает за скорость змейки var count = 0; // А вот и сама змейка var snake = < // Начальные координаты x: 160, y: 160, // Скорость змейки — в каждом новом кадре змейка смещается по оси Х или У. На старте будет двигаться горизонтально, поэтому скорость по игреку равна нулю. dx: grid, dy: 0, // Тащим за собой хвост, который пока пустой cells: [], // Стартовая длина змейки — 4 клеточки maxCells: 4 >; // А это — еда. Представим, что это красные яблоки. var apple = < // Начальные координаты яблока x: 320, y: 320 >;

          2. Сделаем генератор случайных чисел. Он нам понадобится, чтобы размещать еду на поле случайным образом.

          // Делаем генератор случайных чисел в заданном диапазоне

          function getRandomInt(min, max) < return Math.floor(Math.random() * (max - min)) + min;

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

          // Игровой цикл — основной процесс, внутри которого будет всё происходить function loop() < // Дальше будет хитрая функция, которая замедляет скорость игры с 60 кадров в секунду до 15. Для этого она пропускает три кадра из четырёх, то есть срабатывает каждый четвёртый кадр игры. Было 60 кадров в секунду, станет 15. requestAnimationFrame(loop); // Игровой код выполнится только один раз из четырёх, в этом и суть замедления кадров, а пока переменная count меньше четырёх, код выполняться не будет. if (++count < 4) < return; >// Обнуляем переменную скорости count = 0; // Очищаем игровое поле context.clearRect(0, 0, canvas.width, canvas.height); // Двигаем змейку с нужной скоростью snake.x += snake.dx; snake.y += snake.dy; // Если змейка достигла края поля по горизонтали — продолжаем её движение с противоположной стороны if (snake.x < 0) < snake.x = canvas.width - grid; >else if (snake.x >= canvas.width) < snake.x = 0; >// Делаем то же самое для движения по вертикали if (snake.y < 0) < snake.y = canvas.height - grid; >else if (snake.y >= canvas.height) < snake.y = 0; >// Продолжаем двигаться в выбранном направлении. Голова всегда впереди, поэтому добавляем её координаты в начало массива, который отвечает за всю змейку. snake.cells.unshift(< x: snake.x, y: snake.y >); // Сразу после этого удаляем последний элемент из массива змейки, потому что она движется и постоянно особождает клетки после себя if (snake.cells.length > snake.maxCells) < snake.cells.pop(); >// Рисуем еду — красное яблоко context.fillStyle = 'red'; context.fillRect(apple.x, apple.y, grid - 1, grid - 1); // Одно движение змейки — один новый нарисованный квадратик context.fillStyle = 'green'; // Обрабатываем каждый элемент змейки snake.cells.forEach(function (cell, index) < // Чтобы создать эффект клеточек, делаем зелёные квадратики меньше на один пиксель, чтобы вокруг них образовалась чёрная граница context.fillRect(cell.x, cell.y, grid - 1, grid - 1); // Если змейка добралась до яблока. if (cell.x === apple.x && cell.y === apple.y) < // увеличиваем длину змейки snake.maxCells++; // Рисуем новое яблочко // Помним, что размер холста у нас 400x400, при этом он разбит на ячейки — 25 в каждую сторону apple.x = getRandomInt(0, 25) * grid; apple.y = getRandomInt(0, 25) * grid; >// Проверяем, не столкнулась ли змея сама с собой // Для этого перебираем весь массив и смотрим, есть ли у нас в массиве змейки две клетки с одинаковыми координатами for (var i = index + 1; i < snake.cells.length; i++) < // Если такие клетки есть — начинаем игру заново if (cell.x === snake.cells[i].x && cell.y === snake.cells[i].y) < // Задаём стартовые параметры основным переменным snake.x = 160; snake.y = 160; snake.cells = []; snake.maxCells = 4; snake.dx = grid; snake.dy = 0; // Ставим яблочко в случайное место apple.x = getRandomInt(0, 25) * grid; apple.y = getRandomInt(0, 25) * grid; >> >); >

          4. Сделаем управление стрелочками на клавиатуре.

          // Смотрим, какие нажимаются клавиши, и реагируем на них нужным образом document.addEventListener('keydown', function (e) < // Дополнительно проверяем такой момент: если змейка движется, например, влево, то ещё одно нажатие влево или вправо ничего не поменяет — змейка продолжит двигаться в ту же сторону, что и раньше. Это сделано для того, чтобы не разворачивать весь массив со змейкой на лету и не усложнять код игры. // Стрелка влево // Если нажата стрелка влево, и при этом змейка никуда не движется по горизонтали… if (e.which === 37 && snake.dx === 0) < // то даём ей движение по горизонтали, влево, а вертикальное — останавливаем // Та же самая логика будет и в остальных кнопках snake.dx = -grid; snake.dy = 0; >// Стрелка вверх else if (e.which === 38 && snake.dy === 0) < snake.dy = -grid; snake.dx = 0; >// Стрелка вправо else if (e.which === 39 && snake.dx === 0) < snake.dx = grid; snake.dy = 0; >// Стрелка вниз else if (e.which === 40 && snake.dy === 0) < snake.dy = grid; snake.dx = 0; >>);

          5. Запускаем игру. Для этого достаточно запустить предыдущий бесконечный цикл, поэтому пишем:

          6. Наслаждаемся результатом:

          Чтобы у вас тоже получилось такое, просто скопируйте готовый код, сохраните его как HTML-файл и откройте в браузере.

          Готовый код

             Змейка html, body < height: 100%; margin: 0; >/*Задаём глобальные параметры*/ body < background: black; display: flex; align-items: center; justify-content: center; >/*Делаем границу вокруг игрового поля*/ canvas      

          Как улучшить

          Этот код — самая простая реализация змейки, и игру можно сделать ещё лучше:

          • выводить количество набранных очков;
          • сделать так, чтобы нельзя было проходить сквозь стены;
          • добавить препятствия;
          • поставить таймер — кто больше соберёт еды за 5 минут;
          • добавить вторую змейку и играть вдвоём.

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

          Апскиллинг, как говорится

          Апскиллинг — это, например, переход с уровня junior на уровень middle, а потом — senior. У «Яндекс Практикума» есть курсы ровно для этого: от алгоритмов и типов данных до модных фреймворков.

          Пишем свою игру на JavaScript

          JavaScript – очень гибкий язык, поскольку начиная с JavaScript ES5 каждый новый стандарт добавляет в язык все больше функциональности. За это приходится платить некоторыми старыми костылями, вокруг которых нужно «плясать», но преимущества все равно перевешивают – на чистом JavaScript можно написать практически что угодно, и гайд ниже вам это продемонстрирует, поскольку мы будем писать 2d игру «Змейку». Заметим, что выучить JavaScript с нуля на этом гайде не получится – все же нужны некоторые предварительные знания. Кроме того, предупредим, что нам понадобится чистый HTML (включая HTML5 canvas) и CSS, хотя 95% времени все же будет посвящено языку JavaScript.

          Подготовка: HTML и CSS
          Шаг предварительный: дизайн
          Шаг 2: размещаем еду, перехватываем нажатия клавиш
          Шаг 3: пишем основную функцию
          Шаг 4: тестируем
          Где взять гайды по разработке игр?

          Подготовка: HTML и CSS

          Перед тем, как размещать код, нам нужно создать стандартный HTML-файл index.html. Выглядеть он должен следующим образом:

          Здесь нет никакой магии: в head мы указываем всю мета-информацию, выставляем правильную ширину и подключаем CSS и скрипт, в котором будет расположена игра. В теле создаем канву, которая и будет основой нашей игры.

          CSS выглядит вот так:

          body

          Это позволяет разместить нашу канву по центру экрана.

          Шаг предварительный: дизайн

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

          У нас есть некоторое поле с клетками, представляющее собой двухмерный массив. Изначально в случайных ячейках появляется еда, игрок появляется в фиксированной ячейке. Для простоты примера не будем делать отдельную кнопку «Старт», игра начнется при первом нажатии на любую стрелочку. Змейка управляется через стрелочки, она двигается в направлении, соответствующем стрелочке, нажатой последней. Змейка двигается с определенной скоростью и не может остановиться. Если змейка сталкивается с едой – она «съедает» ее: еда удаляется с экрана, змейка «прирастает» на 1 сегмент, на экране в незанятой клетке появляется новая еда. Если голова змейки сталкивается с другим сегментом змейки, игра заканчивается. Если голова змейки сталкивается с краем экрана, игра заканчивается.

          Окончание игры сопровождается надписью «Вы проиграли!».

          Шаг 1: создаем глобальные переменные и функцию main

          Учитывая, что у нас – небольшой проект, будет очень удобно создать все необходимые переменные в глобальной области видимости, после чего обращаться к ним напрямую (в больших проектах так делать не стоит, потому что может случиться так, что вы случайно перекроете область видимости). Что нам нужно? Нам нужны переменные для: размера блока в пикселях, количества рядов и строк, служебные переменные для доступа к канве и ее содержимому, размеры и скорость змейки, массив для частей змейки, координаты еды, флаг окончания игры.

          var blockSize = 25; var rows = 20; var cols = 20; var board; var context; var snakeX = blockSize * 5; var snakeY = blockSize * 5; var velocityX = 0; var velocityY = 0; var snakeBody = []; var foodX; var foodY; var gameOver = false;

          Опять же, с учетом того, что наш проект – маленький, будет неплохой идеей начать разработку с самой главной функции, в ней написать всю последовательность действий, после чего уже реализовывать функции более низкого уровня (вызываемые этой главной функцией). Начинать функцию будем по триггеру window.onload, в самой функции будем: 1) захватывать канву; 2) задавать размеры игрового поля в пикселях; 3) размещать еду; 4) подключать listener для нажатия кнопки; 5) реализовывать игровую механику с обработкой по фреймам. Код:

          window.onload = function() < board = document.getElementById("board"); board.height = rows * blockSize; board.width = cols * blockSize; context = board.getContext("2d"); placeFood(); document.addEventListener("keyup", changeDirection); // update(); setInterval(update, 1000/10); //100 milliseconds >

          1000/10 означает, что игра будет обновляться 10 раз в секунду, если хотите уменьшить/увеличить скорость – поиграйте с этим параметром.

          Шаг 2: размещаем еду, перехватываем нажатия клавиш

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

          function placeFood() < //(0-1) * cols ->(0-19.9999) -> (0-19) * 25 foodX = Math.floor(Math.random() * cols) * blockSize; foodY = Math.floor(Math.random() * rows) * blockSize; >

          Вызываем функцию генерации случайных чисел, через нее получаем номер блока, умножаем на ширину блока – получаем x и y новой еды.

          С направлением все чуть сложнее:

          function changeDirection(e) < if (e.code == "ArrowUp" && velocityY != 1) < velocityX = 0; velocityY = -1; >else if (e.code == "ArrowDown" && velocityY != -1) < velocityX = 0; velocityY = 1; >else if (e.code == "ArrowLeft" && velocityX != 1) < velocityX = -1; velocityY = 0; >else if (e.code == "ArrowRight" && velocityX != -1) < velocityX = 1; velocityY = 0; >>

          Мы считаем ускорение как смещение относительно текущей точки на координатной оси на 1 или -1 (1 – это вправо или вниз, -1 – влево или вверх). Мы анализируем ввод и для каждой стрелочки меняем ускорение тем или иным образом. Проверка после && в условии нужна для того, чтобы исключить случаи, когда, например, змейка движется вправо, а мы нажали стрелочку влево – если позволить змейке поменять направление движения таким образом, то она тут же наткнется сама на себя.

          Поэтому мы проверяем, что нажата стрелочка влево и при этом змейка не движется вправо.

          Шаг 3: пишем основную функцию

          В серьезных игровых движках, типа Unity и UE, функция update доступна для каждого элемента, и update исполняется каждый фрейм. Мы же хотим создать браузерную игру своими силами, поэтому используем

          setInterval(update, 1000/10);

          После чего пишем основной код в update(). Сначала отрисовываем игровое поле и блок еды:

          context.fillStyle="black"; context.fillRect(0, 0, board.width, board.height); context.fillStyle="red"; context.fillRect(foodX, foodY, blockSize, blockSize); Теперь проверяем, находится ли голова змейки и еда на одной точке, если находится – еду нужно «съесть» и сгенерировать новую: if (snakeX == foodX && snakeY == foodY)

          Теперь нам нужно решить проблему перемещения: каждый раз, когда змейка перемещается на блок куда-либо, ее тело должно перемещаться вместе с ней. Решается это просто – поскольку у нас все тело задано в массиве координатами каждого сегмента, нам нужно пройтись по всему массиву и сместить все элементы на 1, а нулевому элементу присвоить координаты головы в текущий момент:

          for (let i = snakeBody.length-1; i > 0; i--) < snakeBody[i] = snakeBody[i-1]; >if (snakeBody.length)

          Теперь реализовываем саму змейку:

          context.fillStyle="lime"; snakeX += velocityX * blockSize; snakeY += velocityY * blockSize; context.fillRect(snakeX, snakeY, blockSize, blockSize); for (let i = 0; i

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

          if (snakeX < 0 || snakeX >cols*blockSize -1 || snakeY < 0 || snakeY >rows*blockSize - 1) < gameOver = true; alert("Game Over"); >for (let i = 0; i < snakeBody.length; i++) < if (snakeX == snakeBody[i][0] && snakeY == snakeBody[i][1]) < gameOver = true; alert("Game Over"); >>

          Наконец, в самое начало функции нужно добавить проверку геймовера – если значение равно true, то нужно закончить игру и ничего больше не делать.

          if (gameOver)

          Все, имеем полностью работоспособную игру.

          Шаг 4: тестируем

          Все файлы нужно собрать в одной папке, после чего – открыть html-файл. Нажмите любую стрелочку – и увидите следующее:

          Где взять гайды по разработке игр?

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

          • Канал ChrisCourses – огромное количество длинных и детальных гайдов по разработке самых сложных игр (вплоть до RPG про Покемонов)
          • Мультиплеерная игра на JavaScript с дополнительной библиотекой
          • Простой гайд по созданию игры на русском языке
          • Аналог Flappy Bird на JS
          • Игра, код которой умещается в 100 символов

          Вывод

          • JS хорошо подходит для создания простых браузерных игр.
          • Вы можете самостоятельно по гайдам создавать такие простые игры, как змейку, гонки, Aliens Invaders, PacMan и другие.
          • Более сложные игры могут потребовать от вас пользоваться сторонними библиотеками.
          • В любом случае вам нужно хорошо знать JS, без этих знаний вы не сможете разрабатывать игры самостоятельно.

          Крестики нолики на JavaScript

          Есть такой код игры крестики нолики, но здесь каждый выбор клетки делаю я сам, а каким образом можно сделать, чтобы против меня компьютер играл? Т.е один ход делаю я, один компьютер. Вот код:

          var pos = [ [ [0, 0], [0, 1], [0, 2] ], //1 строка [ [1, 0], [1, 1], [1, 2] ], //2 строка [ [2, 0], [2, 1], [2, 2] ], //3 строка [ [0, 0], [1, 0], [2, 0] ], //1 столбец [ [0, 1], [1, 1], [2, 1] ], //2 столбец [ [0, 2], [1, 2], [2, 2] ], //3 столбец ]; function check() < var table = document.getElementById("myTable"); var flag; for (var i = 0; i < pos.length; i++) < var win = true; for (var k = 0; k < pos[i].length; k++) < if (table.rows[pos[i][k][0]].cells[pos[i][k][1]].innerHTML !== 'X' && table.rows[pos[i][k][0]].cells[pos[i][k][1]].innerHTML !== 'O') win = false; >if (win) < flag = true; break; >> if (flag) < alert("победа"); >> var tds = document.getElementsByTagName('td'); for (var i = 0; i < tds.length; i++) < tds[i].addEventListener('click', function() < if (this.innerHTML !== 'X') < this.innerHTML = 'X'; >else < this.innerHTML = ''; >check(); >) > for (var i = 0; i < tds.length; i++) < tds[i].addEventListener('click', function() < if (this.innerHTML !== 'O') < this.innerHTML = 'O'; >else < this.innerHTML = ''; >check(); >) >

          Отслеживать
          81.8k 9 9 золотых знаков 78 78 серебряных знаков 136 136 бронзовых знаков
          задан 22 окт 2018 в 10:29
          109 6 6 бронзовых знаков
          нужно добавить ход компьютера просто
          Commented 22 окт 2018 в 10:41
          @Grundy я добавлял, но не работает так. Все кнопки отключатся. Можете на данном примере показать?
          Commented 22 окт 2018 в 10:45
          Лучше покажи как добавлял 🙂
          Commented 22 окт 2018 в 10:46
          Добавь это непосредственно в вопрос, в комментариях код тяжело смотреть
          Commented 22 окт 2018 в 10:50
          @Grundy добавил. Посмотрите.
          Commented 22 окт 2018 в 10:54

          1 ответ 1

          Сортировка: Сброс на вариант по умолчанию

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

          tds[i].addEventListener('click', function() < if (this.innerHTML == '') < this.innerHTML = 'X'; check(); stepComp(tds); >>) 

          В данном примере функция принимает список ячеек, чтобы сделать ход.

          Сама функция может выглядеть следующим образом:

          function stepComp(tds) < for (var i = 0; i < tds.length; i++) < if (tds[i].innerHTML == '') < tds[i].innerHTML = 'O'; check(); break; >> > 

          То есть, ищет первую свободную ячейку, ставит в нее ‘O’ и запускает проверку. Алгоритм выбора ячейки может меняться, но суть остается та же.

          Пример в сборе: (не корректно работает метод проверки, так как проверяет просто отсутствие пустых ячеек, а не наличие конкретных символов)

          var pos = [ [ [0, 0], [0, 1], [0, 2] ], //1 строка [ [1, 0], [1, 1], [1, 2] ], //2 строка [ [2, 0], [2, 1], [2, 2] ], //3 строка [ [0, 0], [1, 0], [2, 0] ], //1 столбец [ [0, 1], [1, 1], [2, 1] ], //2 столбец [ [0, 2], [1, 2], [2, 2] ], //3 столбец ]; function check() < var table = document.getElementById("myTable"); var flag; for (var i = 0; i < pos.length; i++) < var win = true; for (var k = 0; k < pos[i].length; k++) < if (table.rows[pos[i][k][0]].cells[pos[i][k][1]].innerHTML !== 'X' && table.rows[pos[i][k][0]].cells[pos[i][k][1]].innerHTML !== 'O') win = false; >if (win) < flag = true; break; >> if (flag) < console.log("победа"); >> var tds = document.getElementsByTagName('td'); for (var i = 0; i < tds.length; i++) < tds[i].addEventListener('click', function() < if (this.innerHTML == '') < this.innerHTML = 'X'; check(); stepComp(tds); >>) > function stepComp(tds) < for (var i = 0; i < tds.length; i++) < if (tds[i].innerHTML == '') < tds[i].innerHTML = 'O'; check(); break; >> >

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

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