В этом мини-задании будет реализована игра 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 Полярный Коля