Пишем игру змейка с помощью JavaScript + Canvas
Подготовка
Пожалуй, стоит вообще начать с подготовки к созданию игры и написанию кода. Мы будем использовать простой редактор Sublime Text. Впрочем, это не важно. Все делаем в одном документе, чтобы было быстрее.
Первым делом, напишем сам код для встраивания canvas в документ. Напомню, что canvas поддерживается только в HTML5.
Подготовка завершена, теперь мы можем приступать к созданию самой игры.
Начинаем
Для начала, я хотел бы вам вообще объяснить как будет работать змейка, так будет гораздо понятнее. Наша змейка — это массив. Массив элементов, элементы — это ее части, на которые она делиться. Это всего лишь квадратики, которые имеют координаты X и Y. Как вы знаете, X — горизонталь, Y — вертикаль. В обычном виде мы представляем себе координатную плоскость вот так:
Она абсолютно правильная, в этом нет сомнения, но на мониторе компьютера (в частности, canvas) она выглядит по-другому, вот так:
Это нужно знать, если вы вдруг в первый раз столкнулись с canvas. Я, когда столкнулся с этим, сначала вообще не понял где точка (0,0), благо я быстро разобрался. Надеюсь и у вас проблем не возникло.
Вернемся к элементам змейки, ее частям. Представим, что каждый элемент имеет свои координаты, но одинаковую высоту и одинаковую ширину. Это квадратики, не более. А теперь представим, что мы вот нарисовали змейку, все квадратики, они идут друг за другом, одинаковые такие. И тут мы решили, что нам нужно подвинуть змейку вправо. Как бы вы поступили?
Некоторые люди ответили бы, что нам нужно первый элемент подвинуть вправо, затем второй, затем третий и так далее. Но для меня этот вариант не является правильным, так как в случае, если вдруг змейка огромная, а компьютер слабый, мы можем заметить, что змейка иногда разрывается, что вообще не должно быть. Да и вообще, данный способ требует слишком много команд, когда можно обойтись гораздо меньшим количеством, не потеряв качество. А теперь мой способ: Мы берем последний элемент змейки, и ставим его в начало, изменяя его координаты так, чтобы он был после головы. Теперь этот элемент — голова. Всего-то! И да, эффект движения будет присутствовать, а на компьютере вообще не будет заметно, как мы спрятали хвост, а потом его поставили в начало. именно так мы и будем поступать во время создания движения змейки.
Вот тут точно начинаем
Сначала нам нужно объявить некоторые переменные, которые мы в дальнейшем будем использовать.
И так, вообще, нужно чуть-чуть пояснить зачем нам нужно в функции возвращения случайного числа, умножать и делить на переменную s, которая хранит в себе ни что иное, как ширину, по совместительству и высоту элементов змейки. На самом деле, это нужно, чтобы не было смещений во время движения, так как у нас ширина элемента — 30, то если мы хотим двигать ее без разрывов, то все координаты должны делиться на 30 без остатка. Именно поэтому я делю на число, округляю, а потом умножаю. Таким образом, число возвращается таким, что его можно разделить без остатка на 30.
Вы могли бы возразить, сказав, что ты мог бы просто холсту сделать ширину и высоту, кратную 30. Но на самом деле, это не лучший вариант. Так как я лично привык использовать всю ширину экрана. И в случае, если ширина = 320, то мне пришлось бы аж целых 20 пикселей забирать у пользователя, что могло бы доставить дискомфорт. Именно поэтому в нашей змейки все координаты объектов делятся на 30, чтобы не было никаких неожиданных моментов. Было бы даже правильнее вынести это как отдельную функцию, так как она достаточно часто используется в коде. Но к этому выводу я пришел поздно. (Но возможно это даже не нужно).
Теперь сделаем так, чтобы картинка имела четкое качество отображения. По ходу статьи, я буду дописывать код, в некоторых местах возвращаться к началу, так что при себе имейте полную картину кода.
Если что, то переменные innerWidth и innerHeight хранятся в глобальном пространстве имен.
Поэтому к ним можно обратиться именно так. Правда, я не знаю правильно ли так делать.
Ну что же, теперь начинаем писать код змейки.
Чтобы было движение, нам нужна анимация, мы будем использовать функцию setInterval, вторым параметром которой будет число 60. Можно чуть больше, 75 на пример, но мне нравится 60. Функция всего на всего каждые 60 мс. рисует змейку «заново». Дальнейшее написание кода — это только этот интервал.
Покажу вообще простую отрисовку нашей змейки, пока что без движения.
Чтобы проверить, что наша змейка не сталкивается сама с собой, нам нужно сделать некоторую проверку для каждого элемента, кроме последнего. Мы будем проверять, не равны ли координаты последнего элемента (головы) змейки любым из… То есть проще говоря: не произошло ли столкновение. Эта строчка кода была единой строкой, но вам сделал ее понятной. Напоминаю, что все это добавляется в функцию интервала.
А теперь, вы наверное заметили, что во время того, как мы изменяем координаты, мы вечно что-то «сохраняем», сначала поделив, а потом округлив и умножив на число s. Это все тот же самый способ выравнивания змейки относительно яблока. Движение в данном случае строгое, простое, поэтому и есть змейка яблоко может строго по определенным правилам, которые задан в самом начале интервала. И если бы координаты головы змейки хоть на 1px сместились бы, то яблоко нельзя было бы съесть. И да, это простой вариант, поэтому все так сильно ограничено.
Ну а нам же осталось что сделать? Правильно, удалить из массива хвост (первый элемент), добавить новый элемент в самый конец и отрисовать всю змейку. Сделаем это, добавив в конец интервала вот такие строчки кода.
В добавок к отрисовке змейки, я добавил код, который делает ощущение, что конец экрана — это его начало. И если змейка выходит за границы, то она потом выходит из начала, на погибая.
Вы можете заменить обнуление координат, на пример, на сбрасывание игры, если у вас все очень жестко. Но мне нравится больше так. Ну а теперь, осталось только по нажатию кнопок изменять направление змейки. Делает за считанные секунды. Нужно лишь написать этот код сразу после setInterval. Примерно так:
Тут мы сделали так, что если змейка двигается вправо, то она не может изменить направление налево. Это логично, на самом деле.
Вот и все, друзья. Моя первая статья, написанная новичком для новичков. Надеюсь, все было понятно и кому-то это пригодилось. Змейку можно усовершенствовать, добавив на пример, счетчик очков, рекорды, дополнительные фишки, но это все уже дополнения, которые вы можете сделать сами. На этом все, всем удачи!
Создаем игру — змейка на языке javascript и наслаждаемся игрой в браузере
Приветствую всех, кто читает данную статью и загорелся желанием написать свою собственную игру. Сегодня я расскажу вам, как создается игра змейка на JavaScript. Я приведу код для html-разметки, после мы проработаем с вами стили оформления элементов и в конце пропишем логику работы приложения при помощи JavaScript. Давайте приступим!
Создаем свою игру «Змейка»
Займемся разметкой игрового поля
Для начала необходимо прописать разметку игры. В первую очередь на странице выделим отдельное пространство под рабочую область:
Я хочу, чтобы в моем приложении было несколько уровней сложности: легкий, средний и сложный. Также я хочу обеспечить пользователя возможностью сбросить игру и выбранный уровень сложности для того, чтобы он смог начать игру заново. Поэтому я создаю четыре кнопки, которые помещаю в отдельный блок buttons.
Как вы уже заметили, на каждую кнопку я навешиваю событие. Поэтому при нажатии на какую-либо из них будет запускаться определенная функция обработки.
Ну и в конце я хочу, чтобы у меня выводился счет.
Зададим правильное отображение элементов
Пока что ничего симпатичного в редакторах кода не отображается. Для этого стоит задать стилевые правила. Если вы пишете программу полотном, то внутри тега пропишите парный элемент и далее в него вносите css.
Или же создайте файл style.css и без указания style вставляйте описание стилей.
Итак, для начала сбросим стандартные параметры браузера, т.е. обнулим внутренние и внешние отступы:
Теперь создадим подложку под игровое поле:
Перейдем к кнопкам. Я хочу сделать их объемными и разместить сверху по центру поля. Поэтому для соответствующего класса я описываю внешние отступы. А после для самого элемента определяю стилевые характеристики.
Что-то уже прорисовывается, но описание счета «убежало» непонятно куда. Поэтому переместим его в нужную нам позицию и облагородим.
Вот мы и описали классы и теги, которые были перечислены в гипертекстовой разметке. Однако у вас наверняка возникли вопросы: «А где же само игровое поле? Где змея и что она должна собирать?»
Остальная разметка будет добавляться в скрипте. А пока подготовим для этого стили.
Само игровое поле мы опишем при помощи класса .field, а внешний вид клеток – с помощью класса .cell.
Далее нам нужна змея. Поэтому задаем ее классом .snake и указываем:
Ну и наконец змея должна что-то собирать. Поэтому описываем еду. В моей программе это будет квадрат красного цвета.
Дизайн игры готов. Теперь переходим к самому главному!
Заставим игру работать!
Вот теперь пришло время прописать логику работы «Змейки». Для этого после разметки html вставьте ниже прикрепленный код. Внимательно просмотрите его, если хотите разобраться во всех деталях реализации игры. По мере прочтения коды вы будете находить мои комментарии.
Ну вот игра готова!
Вступайте в ряды моих верных подписчиков и делитесь интересными статьями с друзьями. Приятной игры! Пока-пока!
Как написать змейку на javascript
HTML5 Canvas позволяет создавать 2D приложения любой сложности. Удобство этой технологии заключается в её кроссплатформенности, ибо любое устройство, где есть современный браузер, может запустить подобное приложение.
В этой статье я покажу как создать игру-змейку, на примере своей реализации этой игры (демо, GitHub).
Подготовка
Для начала создадим файловую структуру проекта, в моём случае она выглядит таким образом:
Информация о файлах:
index.html
Здесь всё просто, обычный HTML код с подключением всех JavaScript файлов.
client/app.js — приложение
Файл приложения — это файл, в котором инициализируется приложение и запускается бесконечный таймер.
Инициализация
Код инициализации приложения выглядит следующим образом:
Здесь мы инициализируем объект Game и создаём функцию init(), в которой запускается метод game.init() и запускается бесконечный таймер.
Бесконечный таймер
Функция main() — это функция которая будет вызываться постоянно, выглядит она следующим образом:
Здесь мы вызываем методы игры — метод обновления, а потом метод для рендеринга.
Обработка клавиш
Добавляем обработчик события keydown, который будет вызывать метод game.handleInput(e);
Запуск
Здесь всё просто — в самом конце мы вызываем функцию init(), что повлечёт за собой запуск всего приложения.
Полный код client/app.js выглядит так:
client/input.js — определение нажатой клавиши
Эта маленькая библиотека была создана для удобного определения нажатых клавиш.
Функция isKey(key) проверяет наличие key в объекте keys, чтобы заменить слово на код клавиши и если его там нет, то считается, что была введена какая-то буква. Потом полученный код сравнивается с введённым.
Для удобства здесь создаётся метод объекта window — input, который позволяет использовать библиотеку следующим образом: input.isKey(‘SPACE’).
client/game.js — тело игры
В этом файле объединяются все части игры, создаётся Canvas, обновляются и перерисовываются данные.
Объект Game создаётся следующим образом:
В блоке // default settings определяются параметры игры по умолчанию, создаются константы, которые будут использовать остальные файлы.
Далее мы создаём объект Canvas стандартными методами Javascript и располагаем его по центру страницы. Настраиваем его ширину и высоту, задаём стиль рамке.
Потом, на основе параметров высоты, ширины и размера ячейки мы высчитываем количество ячеек на поле в ширину и высоту.
И в самом конце мы подключаем объекты Snake и Apple, чтобы использовать их в методах объекта Game.
Сброс игры
Функция сброса игры нужна для её первоначальной инициализации и сброса игры, если игрок пожелает сыграть заново.
Функция reset выглядит таким образом:
Здесь мы заново инициализируем объекты Snake и Apple для сброса их значений в Game и обнуляем переменную this.score.
Инициализация игры
Приложение должно запускать функцию инициализации, поэтому объявим её:
«Умная» змейка на JavaScript используя QLearning
Здравствуйте, сегодня я хочу вам поведать о том как быстро написать ИИ на JavaScript.
Для начала напишем основу сайта на HTML.
Загружаем bootstrap, и фавиконку(иконку сайта):
Создаем «Контейнер» и заголовок.
Закрываем теги и загружаем скрипты:
Отлично, с самым простым разобрались…
теперь время JavaScript…
Я просто вставлю код с комментариями вы же не против?
Кстати, для упрощения жизни себе и вам, я использовал JQuery.
Те, кто просто хотел код, вы можете идти, а тем, кому интересны подробности, прошу останьтесь.
Есть две популярные модели обучения:
Qlearning
NEAT
Первое обозначает обучение путём “пряника и кнута”.
То есть когда ИИ делает что то хорошее, например, в моей программе – змейка не врезается в стену; в другой программе — отличает кекс от собаки, то мы “поощряем” его, давая ему “Пряник” (хорошее число). И такой алгоритм помечается как “Хороший” и его следует придерживается.
А если же ИИ делает что то плохое, например, врезается в себя или ошибается в ответе, то мы “наказываем” его, давая “Кнут” (плохое число). И такие действия помечаются как плохие и их повторять не стоит.
NEAT в свою очередь, это скорее симуляция естественного отбора, чем обучение, так что мы ее не используем в нашей программке.
Информация о проекте
Для создания змейки я использовал следующие:
JavaScript – Описание алгоритма принятия решений для змейки.
HTML – Описание интерфейса пользователя:
Задержку скорости движения змейки, скорости обучения и силу поощрения/наказания
СSS – А именно Bootstrap, необходим для создания приятного глазу интерфейса.
Jquery – Для упрощения работы с JavаScript.
ВЫВОДЫ
Змейка после(при скорости 100):
1 эпохи – погибает почти сразу
10 эпох – живет 1-2 секунды
100 эпох – живет 10 секунд
1000 эпох – живет больше минуты
10000 эпох — Она живет очень долго.
после большого количества эпох(попыток), перестает врезаться в стену и себя, и быстро обнаруживает еду, незамедлительно её поедая
Как написать свою змейку на Java за 15 минут
В предыдущей статье мы писали сапёра за 15 минут, теперь займёмся классической змейкой.
В этот раз нам снова понадобятся:
Подключение библиотек
В прошлый раз у многих возникли с этим вопросом проблемы, поэтому мне показалось уместным посвятить этому немного времени. Во-первых, выше я дал ссылку на скачивание архива с библиотеками, которые использую я, чтобы не было путаницы с версиями и вопросов, где найти что-то. Папку из архива требуется поместить в папку проекта и подключить через вашу IDE.
Во-вторых, у многих пользователей InteliJ IDEA возникли проблемы как раз с их подключением. Я нашёл в сети следующий видеогайд:
После того, как я сделал всё в точности по нему, у меня библиотеки подключились корректно и всё заработало.
Работа с графикой
С этой стороны наша задача мало отличается от той, что мы выполняли при написании Сапёра. Снова создаём класс GUI, который будет хранить и обновлять состояние всех графических элементов. Если точнее:
Как вы можете видеть, здесь я уже использовал несколько констант. Для них был создан отдельный класс Constants с public static полями. Вот он целиком:
Механика игры
Самое время поговорить о том, как наша змея будет, собственно, перемещаться. Вам наверняка доводилось видеть вывески, вокруг которых по кругу бегают огоньки? Разумеется, сами лампочки в них не перемещаются, просто каждый тик последняя гаснет, а первая зажигается. Таким же образом будет перемещаться и наша змея.