Мини-задание 52. Flabby bird
В этом мини-задании будет реализована игра Flabby bird на базе библиотеки из задания про фракталы.
Должна получиться игра аналогичная этой.
Предполагается, что перед этим заданием было выполнено и полностью понято задание про фракталы.
1) Обновление состояния
Тривиальная заготовка с фоном цвета неба и линией нарисованной по центру под углом:
function setup() {
createCanvas(640, 480); // Указываем размер холста
background(54, 187, 205); // Указываем цвет фона
}
function draw() {
translate(320, 240); // Смещаем центр системы координат в центр экрана
rotate(PI/6); // Поворачиваем систему координат вокруг ее текущей точки отсчета
line(-50, 0, 50, 0); // Рисуем линию в текущей системе координат
}
Игра предполагает что птица летит, а значит требуется обновлять состояние мира с некоторой периодичностью. В используемой библиотеке есть функция frameRate(N);
с единственным аргументом - желаемое число кадров в секунду.
Ее вызов на этапе настройки игры (внутри функции setup
) приведет к тому, что draw
будет вызываться в секунду столько раз, сколько сказано в вызове функции frameRate
.
Чтобы проверить это предлагается вращать линию в центре холста. Для увеличения угла наклона от отрисовки к отрисовке потребуется глобальная переменная:
var angle = 0;
function draw() {
...
angle = angle + PI/30;
rotate(angle);
...
}
P.S. альтернативный пример обновления состояния.
Чтобы очищать экран от отрисовки к отрисовке - надо перенести вызов background
из функции setup
(которая вызывается один раз при запуске программы) в функцию draw
.
Теперь отрезок вращается.
2) Состояние и отрисовка птички
Птица немного сложнее вращающегося отрезка. Подумаем из чего состоит описание состояния птицы:
- Высота положения птицы
- Вертикальная скорость птицы
Еще для определения гравитации потребуется константа ускорения свободного падения:
var birdHeight = 240.0;
var birdVerticalSpeed = 0.0;
var gravityAcceleration = 1.0;
Создайте функцию отрисовки положения птицы drawBird
, которая на основе значения birdHeight
нарисует круг (что-то вроде ellipse(0, 0, 20, 20);
), который представляет нашу условную птицу. И вызовите эту функцию из функции draw
.
3) Управление птицей
Хочется как-то управлять происходящим - нажатием кнопки/мышки придавать птице толчек вверх.
В документации обработка нажатия кнопок описана здесь.
Достаточно наряду с setup()
и draw()
реализовать функцию обработки нажатия кнопки keyPressed()
:
function keyPressed() {
var spaceKeyCode = 32; // Это кодовое число соответствующее кнопке пробел
if (keyCode === spaceKeyCode) { // Есть специальная переменная keyCode, в которой хранится код нажатой кнопки. Пусть птица поднимается выше только когда нажимается пробел
birdHeight -= 10; // Выше птица - меньше координата, т.к. в системе координат графики y-ось направлена вниз
}
}
Но заметим, что на самом деле положение птицы в этой функции мы не должны менять. Обновление положения происходит с каждым кадром, поэтому давайте заведем функцию updateBird()
и будем вызывать ее при каждом выполнении draw
:
function updateBird() {
birdHeight = birdHeight + birdVerticalSpeed;
birdVerticalSpeed += gravityAcceleration;
}
Теперь птица падает с некоторым ускорением. Подгоните константы так, чтобы это выглядело естественно.
Чем же мы управляем, если не высотой птицы? Нажатие пробела должно приводить к “толчку” птицы вверх, птица начинает лететь вверх когда ее скорость направлена вверх. Т.е. нажатие пробела должно влиять на значение birdVerticalSpeed
.
4) Препятствия
Надо сделать так, чтобы одна за другой справа набегали стены с дырами. Для упрощения реализуем сначала так, чтобы на экране была видна ровно одна стена.
Она описывается:
- Размер дыры в стене, в которую хочет проскочить птица
- Высота дыры в стене
- Координата стены по x-оси
Заводим для этих параметров аналогично описанию птицы глобальные переменные (вида var someName = 239;
).
Теперь надо реализовать отрисовку стены в функции drawWall()
:
Воспользуемся функцией rect(fromX, fromY, width, height)
. Первые два аргумента - координаты начала прямоугольника. Последние два аргумента - знаковые ширина и высота прямоугольника.
Т.е. указав положительную высоту прямоугольник будет рисоваться “вниз” от начальных координат (т.к. система координат так ориентирована),
указав же отрицательную высоту - прямоугольник будет рисоваться “вверх” от начальных координат.
P.S.
Чтобы не смешать изменения системы координат отрисовки птицы и отрисовки стены пригодятся push()
и pop()
использованные в прошлом задании.
Итак рисование стены было сделано. Теперь необходимо двигать стену. Для этого надо реализовать updateWall()
, который будет уменьшать координату стены по x-оси, но кроме этого: когда стена пройдет весь экран необходимо создать новую случайную стену.
Чтобы создать новую случайную стену полезен вызов Math.random()
, который вернет случайное число от 0.0 до 1.0.
Итого updateWall()
принимает приблизительно такой вид:
function updateWall() {
if (x < ...) { // Если координата x стены вышла за пределы экрана
nextWallX = ...; // крайнее правое положение
nextHoleY = 50.0 + Math.random() * 240.0;
} else {
nextWallX -= wallSpeed; // двигаем стену влево
}
}
5) Коллизии
При обновлении положения птицы надо так же проверить, не врезалась ли она в стену, и если врезалась - можно например менять цвет эллипса-птицы на другой.
6) Развитие
Можно добавить следующие вспомогательные вещи:
- Счет
- Перезапуск игры при коллизии
- Сделать эллипс немного вытянутым и рисовать его под углом пропорциональным вертикальной скорости (скорость вниз - эллипс смотрит вниз, скорость вверх - эллипс смотрит вверх)
- Больше одной стены
5) Отправка задания
Отправляйте в приложении к письму .js
файл который вы редактировали. Если gmail не возволит вам отправить js файл из соображений безопасности - то переименуйте расширение файла в что-нибудь вроде .js_
:
Тему письма называйте правильно, например: Задание 52 16-1 Полярный Коля