Первый скетч: setup() и draw()
Сегодня ты напишешь свой самый первый скетч на p5.js и поймёшь, как из двух функций — setup() и draw() — рождается живая картинка на холсте.
Скетч — одна программа на p5.js, отдельный набросок, который рисует и анимирует картинку.
Представь, что ты открыл пустой лист в скетчбуке. Ничего не нарисовано — только белая бумага и желание что-то на ней оставить. В прошлом уроке мы говорили о том, что такое креативное кодирование и зачем вообще рисовать кодом. Теперь хватит разговоров — берём карандаш. Точнее, открываем редактор и пишем первые строчки, после которых на экране появится холст, а на нём — крошечная точка. Эта точка не просто так: с неё начнётся наш сквозной герой, цыплёнок CodeChick, который будет расти вместе с тобой весь курс.
Зачем тебе вообще эти две функции
Любая игра, которую ты запускал на телефоне, внутри устроена примерно так: один раз игра загружается (подтягивает картинки, расставляет уровень, заводит счёт на ноль), а потом много-много раз в секунду перерисовывает экран — двигает персонажа, считает очки, проверяет, не врезался ли ты в стену. Глаз видит плавное движение, а на самом деле это сотни отдельных картинок, мелькающих одна за другой.
В p5.js этот же принцип уложен ровно в две функции. Одна отвечает за «загрузку» — она называется setup. Вторая отвечает за «много раз в секунду перерисовать» — она называется draw. Если ты поймёшь, чем они отличаются, ты поймёшь вообще всё устройство p5: остальное будет наращиваться поверх этих двух кирпичей.
setup() — функция p5.js, которая выполняется один раз в начале и настраивает скетч (например, создаёт холст).
draw() — функция p5.js, которая повторяется много раз в секунду и отрисовывает каждый новый кадр.
К концу урока у тебя будет работающий скетч, в котором есть холст нужного размера, фон и первая деталь будущего цыплёнка. А ещё ты на пальцах поймёшь разницу между «сделать один раз» и «делать постоянно» — это пригодится не только в p5, но и почти в любой программе с экраном.
Главная идея: декорации и актёр
Чтобы не запутаться, держи в голове простую сцену в театре. Перед спектаклем рабочие один раз расставляют декорации: вешают задник, ставят стол, кладут реквизит. Это долго и делается заранее — но только один раз. А когда спектакль начался, актёр выходит и снова и снова играет своё действие: шаг, реплика, жест, шаг, реплика, жест.
Так вот, setup — это рабочие сцены. Здесь ты один раз настраиваешь всё, что не должно меняться каждую секунду: создаёшь холст, задаёшь его размер. А draw — это актёр: всё, что внутри неё, p5 проигрывает снова и снова, кадр за кадром, пока скетч запущен.
Вот самый маленький скетч, который вообще можно написать. Разберём его построчно.
function setup() {
createCanvas(400, 400);
}
function draw() {
background(220);
}Результат: на странице появляется квадратный холст 400 на 400 пикселей, залитый ровным светло-серым цветом. Картинка статичная — она не двигается, но на самом деле p5 перерисовывает этот серый фон десятки раз в секунду.
Разберём, что здесь происходит:
function setup() { ... }— мы объявляем функцию настройки. p5 сам найдёт её по имени и вызовет один раз при старте.createCanvas(400, 400)— создаём холст шириной 400 и высотой 400 пикселей. Два числа в скобках — это ширина и высота.function draw() { ... }— функция кадра. p5 будет вызывать её снова и снова, примерно 60 раз в секунду.background(220)— заливаем весь холст серым цветом. Число 220 — это яркость от 0 (чёрный) до 255 (белый); 220 — светло-серый.
Холст (canvas) — прямоугольная область на странице, внутри которой p5.js рисует всё изображение.
createCanvas() создаёт этот холст. Без него рисовать просто негде — это как пытаться рисовать в воздухе без листа бумаги.
Почему createCanvas стоит именно в setup
Логика простая: холст тебе нужен один и тот же на весь скетч. Незачем создавать новый лист бумаги 60 раз в секунду — это всё равно что на каждом кадре спектакля заново строить декорации. Поэтому всё «разовое» — размер холста, его создание — живёт в setup. А всё «повторяющееся» — рисование фигур, движение — живёт в draw.
Разбираем на примерах
Пример 1. Холст и фон — самый минимум
Мы его уже видели выше, но давай задержимся и поэкспериментируем. Поменяй число в background и представь результат.
function setup() {
createCanvas(400, 400);
}
function draw() {
background(135, 206, 235);
}Результат: холст 400 на 400 заливается голубым цветом неба. Три числа в background — это уже не яркость, а доли красного, зелёного и синего (модель RGB), и вместе они дают небесно-голубой. Подробно про цвет будет отдельный модуль, а пока просто запомни: одно число — это серый, три числа — это полноцветный оттенок.
Вот тебе первое поле для эксперимента: попробуй мысленно поставить background(0) (получишь чёрный холст) или background(255) (белый). Поменял число — поменялась сцена. Это и есть кайф креативного кодирования: ты крутишь параметры и сразу видишь отклик.
Пример 2. Первая деталь цыплёнка
Серый прямоугольник — это, конечно, скучно. Давай нарисуем на нём первую деталь нашего героя — кружок-тело будущего цыплёнка CodeChick.
function setup() {
createCanvas(400, 400);
}
function draw() {
background(135, 206, 235);
circle(200, 200, 120);
}Результат: на голубом небе в самом центре холста появляется белый кружок диаметром 120 пикселей — пока без цвета и клюва, просто тельце. Это первая клеточка нашего цыплёнка: дальше по курсу он обзаведётся жёлтой заливкой, клювом и научится прыгать.
Разберём circle(200, 200, 120):
- Первое число — координата
xцентра кружка, то есть отступ слева. 200 — это ровно половина от 400, значит центр по горизонтали. - Второе число — координата
yцентра, отступ сверху. Тоже 200 — центр по вертикали. - Третье число — диаметр кружка в пикселях.
Тут важная деталь, на которой спотыкаются все новички: на холсте точка (0, 0) находится в левом верхнем углу, а не внизу, как на уроках математики. Ось x растёт вправо, а ось y — вниз. Представь клетки в тетради, только нумерация строк идёт сверху вниз. Поэтому центр холста 400 на 400 — это точка (200, 200).
Система координат — способ задавать точку на холсте парой чисел (x, y), где начало (0, 0) находится в левом верхнем углу.
Пример 3. Проверяем, что setup действительно срабатывает один раз
Давай докажем себе, что setup выполняется ровно один раз, а draw — постоянно. Используем функцию print, которая пишет сообщение в консоль (это служебное окошко, куда программа выводит текст для разработчика).
function setup() {
createCanvas(400, 400);
print("setup сработал");
}
function draw() {
background(220);
print("draw сработал");
}Результат: в консоли строчка «setup сработал» появляется ровно один раз, а строчка «draw сработал» печатается снова и снова без остановки, десятки раз в секунду, пока скетч работает. Это наглядно показывает разницу: одна функция — про старт, другая — про бесконечный поток кадров.
Кадр (frame) — одно изображение анимации; draw() рисует кадры подряд, создавая иллюзию движения.
Каждый вызов draw рисует новый кадр поверх предыдущего. Пока картинка не двигается, ты этого не замечаешь, но именно эта повторяемость в следующих модулях оживит нашего цыплёнка.
Пример 4. Что будет без background в draw
А теперь хитрый момент, который многих сбивает. Зачем вообще каждый кадр перерисовывать фон? Давай посмотрим, что выйдет, если фон оставить в setup, а в draw рисовать кружок в случайном месте.
function setup() {
createCanvas(400, 400);
background(135, 206, 235);
}
function draw() {
circle(random(400), random(400), 30);
}Результат: голубое небо заливается один раз, а потом по нему начинают рассыпаться белые кружочки — каждый кадр добавляет новый, и старые никуда не деваются. За пару секунд весь холст покрывается белыми пятнами, как будто кто-то щедро сыпет конфетти. Так происходит, потому что фон не стирается: каждый новый кружок ложится поверх всего нарисованного раньше.
Запомни это поведение — оно не баг, а инструмент. Иногда тебе нужно, чтобы рисунок накапливался (так делают красивые узоры), а иногда — чтобы каждый кадр был чистым (так делают анимацию). Управляешь этим ты, ставя или убирая background внутри draw.
Частые ошибки и подводные камни
Вот грабли, на которые наступают почти все в первый день. Пробежись по ним заранее — сэкономишь себе кучу нервов.
1. Забыть createCanvas
Если не вызвать createCanvas в setup, p5 создаст крошечный холст по умолчанию (100 на 100), и ты будешь недоумевать, почему твой кружок с координатой 200 вообще не виден — он просто за краем малюсенького холста. Правило: первым делом в setup создавай холст нужного размера.
2. Путать порядок: фигура раньше фона
Команды рисования выполняются сверху вниз, и каждая следующая ложится поверх предыдущей, как слои краски. Если ты сначала нарисуешь кружок, а потом зальёшь background, фон закрасит твой кружок целиком, и ты увидишь пустой холст. Правило: background почти всегда идёт первой строкой в draw.
3. Думать, что (0, 0) внизу
На математике начало координат внизу слева, а ось y растёт вверх. На холсте всё наоборот: (0, 0) сверху слева, а y растёт вниз. Поэтому circle(200, 350, 40) нарисует кружок не вверху, а почти у нижнего края. Держи это в голове, иначе фигуры будут улетать не туда, куда ты ждёшь.
4. Лишние или пропущенные скобки и точки с запятой
Тело функции обязано быть в фигурных скобках { }, а аргументы — в круглых ( ). Если потеряешь закрывающую скобку, скетч просто не запустится и выдаст ошибку. Пиши скобки парами сразу, а потом заполняй внутри — так сложнее забыть закрывающую.
5. Писать createCanvas внутри draw
Если по ошибке поставить createCanvas в draw, p5 будет создавать новый холст 60 раз в секунду. В лучшем случае скетч начнёт тормозить, в худшем — насоздаёт кучу холстов друг под другом. Холст — это разовая настройка, ему место строго в setup.
Мини-проект: посади цыплёнка в гнездо
Пора рисовать самому. Возьми скетч из примера 2 и доведи его до маленькой сценки. Задание собирается из шагов, каждый следующий чуть сложнее.
- Создай холст 500 на 400 и залей его светло-голубым фоном неба (подбери три числа в
backgroundна свой вкус). - Нарисуй тельце цыплёнка — кружок диаметром около 120 примерно в центре холста. Посчитай координаты центра сам: для холста 500 на 400 это (250, 200).
- Добавь второй кружок поменьше, диаметром около 60, чуть выше и правее тельца — это будет голова. Прикинь координаты так, чтобы голова касалась тела.
- Под цыплёнком нарисуй ещё один широкий и низкий кружок (или используй
ellipseс разной шириной и высотой) тёмного цвета — это гнездо, на котором он сидит. - Когда всё встанет на места, поэкспериментируй: подвигай числа координат и понаблюдай, как деталь переезжает по холсту. Попробуй сдвинуть голову на пару десятков пикселей и почувствуй систему координат руками.
Подсказка по последнему шагу: чтобы голова была выше тела, её координата y должна быть меньше, чем у тела (помни — вверх это меньшие значения y). Если запутался, вернись к примеру 2 и разделу про координаты.
Не гонись за идеальной картинкой. Цель этого мини-проекта — почувствовать, как из простых кружков и пары чисел складывается узнаваемая сценка, и закрепить, что вся отрисовка живёт в draw, а размер холста задаётся один раз в setup.
Итоги
Соберём всё, что ты сегодня узнал, в одну картину:
- Скетч в p5.js держится на двух функциях:
setupиdraw. - setup() выполняется один раз при старте — здесь ты создаёшь холст через
createCanvas(ширина, высота)и задаёшь всё разовое. - draw() выполняется снова и снова, десятки раз в секунду, рисуя каждый новый кадр; здесь живёт вся отрисовка и будущая анимация.
- Холст — это твой лист бумаги; без
createCanvasрисовать негде. - В системе координат точка (0, 0) находится в левом верхнем углу, x растёт вправо, y — вниз.
backgroundвdrawстирает прошлый кадр; убери его — и рисунок начнёт накапливаться.- Первая деталь нашего цыплёнка CodeChick — простой кружок-тельце — уже на холсте.
В следующем уроке мы разберём систему координат глубже и научимся точно ставить фигуры в нужные точки — это нужно, чтобы цыплёнок не разъезжался по холсту, а собирался аккуратно из деталей. А дальше его ждут цвет, движение и характер. Ты только что сделал самый важный шаг — написал первый работающий скетч. Дальше будет только интереснее.