Menu
Classic Snake базовое движение

Управление: w,a,s,d

Обновите страницу, если хотите сыграть ещё раз.

Красивая анимая на изгибах змейки во второй части статьи.

Как сделать игру «Змейка». Часть первая.

Я думаю, все знают игру «Змейка». Где нужно собирать какую нибудь точку (или что там ест эта змейка?), которая появляется в случайном месте. Змея становится длиннее с каждой съеденной точкой. Змейка движется не останавливаясь и можно лишь сменить направление. Если голова змеи сталкивается с хвостом или с препятствием, то игра заканчивается.
Так игра выглядит со стороны игрока, но давайте подробно разберем логику игры со стороны геймдева.

Статья написана на основе примера из clickteam — скачать пример.

Логика создания игры «Змейка»

Если вы играли в «Змейку», то знаете, что она движется, как бы прерывисто, с шагом в какой-то момент времени. Так же, наверняка понятно, что хвост змеи состоит из отдельных объектов и когда собираешь точку, хвост становится длиннее на один такой объект.
С каждым перемещением (шагом) головы змеи, на её месте создается «кусочек хвоста», а последний «кусочек» удаляется. Создается впечатление, что змея ползет. Но на самом деле перемешается только голова змеи, а объекты из которых состоит хвост просто создаются в нужном месте и остаются нужное время, и всё!
Игровое поле, как бы, состоит из клеток. На одной из клеток всегда находится съедобная точка, а змейка проходит одну клетку за один шаг. Но для создания игры нам не нужно строить клеточное поле, нам лишь нужно определиться с размером одной клетки. Это важный момент, который нужно продумать в самом начале. Размер этой воображаемой клетки будет являться расстоянием шага змеи и размером объекта съедобной точки ( ну и размеры объектов головы и хвоста змеи тоже не должны превышать эти размеры клетки). К тому же размер сцены должен быть таким, что бы делился на размер клетки без остатка.
В нашем случае размер клетки составляет 32×32 при стандартных размерах сцены 640×480 получается 20 клеток в ширину и 15 клеток в высоту сцены.
Змейка будет перемещаться с шагом 32, а размер точки-вкусняшки будет 32х32. Если нарушить это правило и сделать размер точки отличным от расстояния шага змеи, произойдет баг когда змея и точка находятся на разных линиях. Типа того:
Snake змея вскользь с точкой
Ширина хвоста змеи должна быть равна шагу змеи в нашем случае — 32. Иначе, возникнет баг «пунктирной змейки»:
Snake баг пунктирной змейки
Логика станет понятнее в процессе. Теперь давайте делать «Змейку»!

Подготовка объектов.

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

В отношении объекта хвоста змеи это не обязательно особенно если у вас этот объект квадратный.

Внимание: Точку привязки координат у всех трех объектов нужно сделать слева вверху. Формулы и логика представленные в данном примере будут работать корректно только с таким положением точки привязки координат для всех трех объектов.

Snake точка привязки объекта

Ширина хвоста змеи должна быть равна шагу змеи в нашем случае — 32.

Snake ширина хвоста - 32

Активный объект являющейся головой змеи должен быть статического типа.

Snake тип объекта голова

Голова змеи. Управление и движение.

По кнопке вверх, вниз, влево и вправо соответственно меняется свойство направления (Direction) объекта головы змеи. Создаем 4 события нажатия кнопок для 4-х сторон движения.

Snake события установка кнопок
Snake клавиша для события

Лично мне нравиться использовать кнопки W, S, A, D.

Snake меняем направление головы змеи

В следующем событии устанавливается событие таймера для регулярного отслеживания какого-то временного промежутка для одного шага, скажем, каждые 30 миллисекунд. И еще устанавливается второе событие с направлением головы змеи. Этим событиям дается действие, которое изменяет координату головы змеи в зависимости от направления. Так, например, если движение вправо, то координата X устанавливается в значение: текущая координата X головы змеи плюс шаг( 32).

Snake изменение координаты движения

Общий алгоритм движения и управления выглядит так:

Snake управление головой

Создание хвоста.

В каждом из последних четырех событий добавляем еще одно действие — создание части хвоста в координатах головы. Голова змеи перемещается на один шаг, а на её месте появляется хвост. Так же можно добавить изменение свойства направления у объекта хвоста, если у вас он не квадратный, а прямоугольный как в данном случае.

Snake создать объект
Snake создать часть хвоста змеи
Snake тело от головы
Snake код создания частей хвоста. меняем направление хвоста змеи
Теперь если вы запустите игру, то увидите, что за змеёй тянется хвост.

Snake хвост тянется за головой

Единственной загвоздкой остается сохранение нужного количества частей хвоста.

Сохранение длинны хвоста.

Что бы хвост сохранял нужную длину надо считать сколько шагов часть хвоста находится в игре, и если это количество превышает общее количество частей хвоста то удалять эту часть.
Для этого создается переменная у объекта хвоста. Назвать переменную можно например «Продолжительность».
Snake создание переменной у хвоста
Далее создается событие отслеживания такого же временного интервала как и интервал шага, в нашем случае — 30 миллисекунд. В нем создается действие прибавления единицы к переменной «Продолжительность». А в следующем событии происходит сравнение переменной «Продолжительность» с числом которое мы будем считать количеством длины хвоста, например 3. И если «Продолжительность» хвоста превышает это число то удалять этот хвост.
Snake удаление лишнего хвоста

После очередного шага появляется новый объект хвоста и с каждым шагом его «Продолжительность» увеличивается на 1. Каждый объект хвоста будет существовать столько шагов сколько мы установим как число для сравнения, которое в свою очередь должно пониматься как количество частей хвоста. По этому очень важно, что бы переменная «Продолжительность» была переменной именно объекта хвоста.

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

Snake сохраняя три хвоста

Съел вкусняшку — стал длиннее

Следующий шаг сделать увеличение змеи когда собирается съедобная точка. Для этого нужно использовать изменяемое значение для сравнения с переменной «Продолжительность». В этом качестве мы можем взять счетчикCounter. В настройках счетчика указываем значение по умолчанию 3.
Snake настройка счетчика
И в событии сравнения заменяем число 3 на значение счетчика.
Snake сравнение со значением счетчика
Snake продолжительность больше счетчика

Я думаю вы уже догадались, что теперь по событию подбора точки надо просто прибавлять счетчик на 1.
Разместите где нибудь объект точки и создайте событие столкновения головы с точкой. И не забудьте удалять точку.
Snake съел точку и вырос
Теперь змейка растет!
Snake почти собрал точку
Snake уже собрал

Появление точки в случайном месте

Диапазоном возможных координат у нас будет вся сцена. Так минимальная координата находится в левом верхнем углу и равна нулю (помните, точка привязки координат у объекта слева вверху).
Snake минимальная координата

А максимальная координата будет справа внизу. Вычислить значение максимальной координаты очень просто надо от размеров сцены отнять размеры объекта.

X координата: 640 (ширина Сцены) — 32 (ширина точки) = 608,

Y координата: 480 (высота сцены) — 32 (высота точки) = 448.
Snake максимальная координата

Таким образом нам нужно генерировать возможные координаты в диапазоне от 0 до 608 по X и от 0 до 448 по Y. И вы также должны помнить, что точка может появляться только на воображаемой клетке поля, про которые шла речь в начале статьи. Получается, что для точки есть 20 возможных координат по ширине и 15 возможных координат по высоте сцены из всего возможного диапазона.
Для генерации случайных координат появления точки нужно использовать генератор случайных чисел — это функция Random(n). Где n — это количественное значение начинающееся с нуля. Допустим выражение Random(3) будет генерировать числа: 0, 1, 2, но не 3!
Итак, что бы сгенерировать координаты в диапазоне всей сцены нужна следующая формула:

Random (Размер сцены / Размер Объекта) * Размер Объекта

Таким образом формула для X-координаты:
Random (Ширина сцены / Ширина Объекта) * Ширина Объекта
или
Random (20) * 32

640/32 получается 20, значит максимум Random может выдать 19, что в свою очередь означает что максимально мы сможем получить значение 608 (т.к. 19*32=608), а 608 и является максимально допустимым значением. Если же Random выдаст минимальное значение-0, то вся формула будет 0, это минимальная координата. В остальных вариантах (от 0 до 19) мы будем получать координату в пределах диапазона с шагом в 32. И в итоге получим 20 ПРАВИЛЬНЫХ случайных варианта для создания съедобной точки в координате X.

Формула для Y-координаты:
Random (Высота сцены / Высота Объекта) * Высота Объекта
или
Random (15) * 32

Если в вашем варианте минимальная координата начинается не с нуля, то формула корректируется простым прибавлением минимального значения координаты:
Минимальная координата + (Random (Размер сцены / Размер Объекта) * Размер Объекта)

Теперь код.

Нам нужно событие для проверки отсутствия точки на сцене. Я буду использовать событие «Количество точек = 0». В этом событии создается новая точка и генерируются случайные координаты.
Snake генерируем координаты точки

Что бы событие работало нужно удалить объект точки из области редактирования кадра, даже если объект находится не на самой сцене. Объект останется в игре благодаря событию Create Object, только сначала создайте его.
Либо можете сделать проще — удалять точку при запуске игры:
Snake отчищать от точки при старте

Теперь можете запустить игру и пособирать точки. Если у вас происходит баг того, что точка и змея на разных линиях,
Snake змея вскользь с точкой
значит голова змеи изначально находится в не соответствующих координатах, поставьте объект в координату кратную 32 (например 160х96).

Но это еще не все! Точка может появится в недопустимых местах: на хвосте змеи или на препятствии.
Snake точка появилась на хвосте
Нужно создать событие переопределения координат если такое происходит.
Snake переопределение координат
Условие OR (logical) означает, что для выполнения достаточно произойти какому-то одному из двух событий.

Игрок может увидеть момент когда точка на какой-то миг появляется на хвосте или на декорации, а это все таки баг. Нужно сделать точку невидимой пока она не найдет правильное место.
При создании точки задаем действие — сделать точку невидимой:
Snake невидимая точка
Snake при генерации точка не видна
Делаем событие обратное событию столкновений точки с хвостом либо препятствием, и возвращаем видимость:
Snake точка становится видимой
Negate — означает противоположное действие (есть не у всех событий). Иными словами, если не происходит столкновения точки с чем либо, то сделать её видимой.

Укусил за хвост или врезался в препятствие — проиграл

Ну тут все просто. Создаете событие столкновения головы с хвостом или с препятствием и включаете флаг №1 у объекта головы, а затем ставите условие, что змея движется только при отключенном флаге.

Столкновения головы с хвостом или с препятствием — включаем «флаг смерти»:
Snake укусил себя проиграл
Вставляем условие в события движения, что они могут работать только если выключен «флаг смерти» (все флаги по умолчанию изначально выключены):
Snake змейка ползет пока жива
Что бы змейка не вертела головой после смерти, добавьте это условие в события управления:
Snake управлять только живой змейкой
Ну и когда змейка кусает себя или препятствие, меняем анимацию головы со статической на анимацию дохлой змеи. И удаляем хвост:
Snake анимация дохлой змеи
Snake змейка сдохла

Препятствия

Далее стоит сделать препятствия, хотя бы для того, что бы создать границу уровня. Заранее предупреждаю, что событие ухода за сцену работать не будет.
Вам стоит делать препятствие размером 32×32 или какой там у вас размер клетки. Препятствие должно быть объектом backdropBackdrop и иметь тип Obstacle.
Snake тип obstacle

C препятствиями вы сможете строить различные уровни.

В игре осталось доделать что бы хвост на повороте сменял анимацию и выглядел красиво с изгибом, а не так:
Snake хвост тянется за головой

И еще. Сейчас змея может повернуть направо из движения влево и наоборот, и так же может повернуть вниз из движения вверх и наоборот. Конечно, это баг и его надо исправить. Об этом пойдет речь во второй части. Продолжение следует…

Скачать исходный файл

Задавайте вопросы в комментариях).

Я думаю, все знают игру «Змейка». Где нужно собирать какую нибудь точку (или что там ест эта змейка?), которая появляется в случайном месте. Змея становится длиннее с каждой съеденной точкой. Змейка движется не останавливаясь и можно лишь сменить направление. Если голова змеи сталкивается с хвостом или с препятствием, то игра заканчивается. Так игра выглядит со стороны игрока, но давайте подробно разберем логику игры со стороны геймдева. Статья написана на основе примера из clickteam - скачать пример. Логика создания игры «Змейка» Если вы играли в «Змейку», то знаете, что она движется, как бы прерывисто, с шагом в какой-то момент времени. Так же, наверняка…

7

Рейтинг: 5 ( 1 голосов)

    Рейтинг: 5,00 ( голосов - 5 )
Загрузка...
Комментариев: 8
  1. PACIFIC:

    Почему хвост создаётся прямо поверх головы?
    В этом случае поедание объекта становится невозможным, т.к. при соприкосновении тела и еды запускается алгоритм создания новой еды в рандомном месте. Что за дела

    • GQ:

      Но хвост не создаётся поверх головы. Скачайте и проверьте исходник

      • PACIFIC:

        он создаётся прямо на голове, а вот если установить координаты появления относительно головы, т.е. тело появляется на расстоянии 32 по Х или У с плюсом или минусом (смотря в какую сторону поворачивать), то всё будет норм))

  2. Костя:

    Очень полезный и понятный урок.Спасибо вам большое за вашу работу.Жду новых уроков

  3. Mr Jay:

    Спасибо за подробность. Очень полезно, что бы разобраться в принципе работы программы.)

  4. niks:

    Seyanis, полностью согласен.

  5. Seyanis:

    отличный гайд, не думал что будет на столько подробно,огромное спасибо!!! :wink: :wink: :wink: Очень ценный урок, которых очень мало по CTF2.5 :cry: :cry:

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

Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.

:wink: :twisted: :roll: :oops: :mrgreen: :lol: :idea: :evil: :cry: :arrow: :?: :-| :-x :-o :-P :-D :-? :) :( :!: 8-O 8)

Вступай в группу!