Рисуем первые формы
Любая картинка на экране — от мема до заставки твоей любимой игры — это набор простых форм, которые кто-то расставил в нужных местах. Сегодня ты научишься делать то же самое кодом.
Главная мысль урока: точка, линия, прямоугольник и круг — это четыре кирпичика, из которых складывается вообще всё. Когда ты поймёшь, как их ставить на холст, ты сможешь нарисовать что угодно — в том числе нашего цыплёнка CodeChick.
Зачем вообще рисовать формы по отдельности
Представь, что ты собираешь персонажа в редакторе вроде того, что есть в Roblox или The Sims. Ты не лепишь его одним движением — ты ставишь голову, потом туловище, потом глаза по одному. В p5.js всё то же самое, только вместо мышки у тебя команды. Ты говоришь холсту: «нарисуй круг вот здесь», «проведи линию отсюда сюда» — и из этих кусочков постепенно вырастает картинка.
В прошлом уроке про холст и координаты ты разобрался, как устроена система координат: начало (0, 0) сидит в левом верхнем углу, x растёт вправо, а y — вниз. Это как клетки в тетради, только считать строки начинаем сверху. Сегодня мы наконец используем эти клетки по назначению: будем ставить в них формы.
К концу урока у тебя на холсте появится вот это: жёлтый кружок-тело, кружок поменьше — голова, маленькая точка-глаз и треугольный... нет, пока что прямоугольный клювик. Первый силуэт CodeChick, собранный из четырёх типов форм. Поехали по одной.
Почему именно эти четыре формы, а не что-то посложнее? Потому что они — алфавит. Как из 33 букв складываются все книги на свете, так из точки, линии, прямоугольника и круга складывается любая графика: иконки в телефоне, спрайты в пиксельных играх, логотипы брендов на футболках. Даже плавные кривые внутри устроены как множество крошечных прямых отрезков, поставленных встык, — глаз просто не замечает стыков. Освоишь алфавит — дальше уже дело техники и фантазии.
И ещё важная деталь про устройство кода. Весь сегодняшний код мы пишем внутри функции setup() — той самой, что выполняется один раз при запуске скетча. Нам пока не нужна анимация, нужна статичная картинка, поэтому функцию draw() мы сегодня вообще не трогаем. Нарисовали форму — и она спокойно лежит на холсте, пока мы её не перерисуем.
Четыре кирпичика: point, line, rect, ellipse
Точка — point()
Самая простая форма — это точка. Один пиксель на холсте. Чтобы её поставить, нужен всего один адрес — пара координат (x, y):
function setup() {
createCanvas(400, 400);
background(240);
strokeWeight(8);
point(200, 200);
}Результат: на светло-сером холсте ровно по центру — одна жирная чёрная точка. Без strokeWeight(8) точка была бы размером в один пиксель, и ты бы её еле разглядел; восьмёрка делает её толстой и заметной.
Запомни: point(x, y) принимает два числа — это координаты единственной точки. Никакого размера у точки нет, кроме толщины обводки.
Кажется, что одна точка — это бесполезно. Зачем вообще такая команда? А представь дождь из тысячи капель, звёздное небо или след кисти, который рассыпается на пиксели. Всё это — точки, расставленные в нужных местах. Чуть позже, когда мы дойдём до циклов и случайности, ты будешь сыпать сотнями точек одной строкой кода и раскидывать пёрышки нашего цыплёнка по всему холсту. А пока запомни главное: точка — это просто адрес на холсте, отмеченный видимой меткой.
Линия — line()
Чтобы провести линию, одной точки мало — нужны две: откуда и куда. Значит, и чисел будет четыре:
function setup() {
createCanvas(400, 400);
background(240);
strokeWeight(4);
line(50, 50, 350, 350);
}Результат: по холсту наискосок — от левого верхнего угла к правому нижнему — протянута толстая диагональная линия. Первая пара (50, 50) — это начало, вторая пара (350, 350) — конец.
Думай об этом как о том, как ты соединяешь две точки в тетради линейкой: ставишь карандаш в первую точку и ведёшь ко второй. line(x1, y1, x2, y2) — ровно это и делает.
Маленький фокус для понимания: поменяй местами концы — напиши line(350, 350, 50, 50) вместо прежнего. Картинка не изменится ни на пиксель! Линии всё равно, в каком порядке ты назвал её концы, ведь отрезок между двумя точками один и тот же. А вот если сдвинуть только один конец, например line(50, 50, 350, 50), линия станет горизонтальной: у обоих концов одинаковый y = 50, значит, высота не меняется, и отрезок ложится ровно поперёк. Это удобный способ рисовать прямые горизонтали и вертикали — следи, чтобы у концов совпадала одна из координат.
Прямоугольник — rect()
С прямоугольником интереснее. Ему нужны четыре числа, но смысл у них другой: где находится угол и какого размера сама фигура.
function setup() {
createCanvas(400, 400);
background(240);
rect(100, 80, 200, 120);
}Результат: в верхней половине холста — прямоугольник с белой заливкой и чёрным контуром. Его левый верхний угол стоит в точке (100, 80), ширина — 200 пикселей, высота — 120.
Вот это важно не перепутать: rect(x, y, w, h) — это не «от угла до угла», как было у линии. Первые два числа — координаты верхнего левого угла, а третье и четвёртое — это ширина и высота. Если хочешь квадрат — просто сделай ширину и высоту одинаковыми: rect(100, 100, 80, 80).
Эллипс — ellipse()
И, наконец, эллипс — то, чем мы рисуем круги, овалы и тело цыплёнка. Тут есть приятный сюрприз: эллипс рисуется от центра.
function setup() {
createCanvas(400, 400);
background(240);
ellipse(200, 200, 160, 160);
}Результат: ровно по центру холста — большой круг диаметром 160 пикселей с белой заливкой и тонким контуром. Центр круга стоит в точке (200, 200).
ellipse(x, y, w, h): первые два числа — координаты центра, а w и h — ширина и высота (то есть диаметры по горизонтали и вертикали). Если они равны — получается круг. Если разные, например ellipse(200, 200, 200, 100), выйдет вытянутый овал — приплюснутый, как яйцо, лежащее на боку. Кстати, circle(x, y, d) — это сокращённая запись для ровного круга: центр и один диаметр.
То, что эллипс рисуется от центра, — это огромное удобство, и сейчас поймёшь почему. Когда ты хочешь поставить что-то «вот сюда, по центру», ты обычно думаешь именно о центре предмета, а не о его угле. Глаз цыплёнка, солнце на небе, мячик в игре — у всего этого есть естественная серединка. С эллипсом ты задаёшь её напрямую: «центр здесь, диаметр такой» — и форма сама раскидывается симметрично во все стороны. Поэтому круги и овалы в p5.js ставить интуитивно проще, чем прямоугольники, и большую часть нашего цыплёнка мы соберём именно из эллипсов.
Маленькая, но важная разница: где «якорь» формы
Самое частое, на чём спотыкаются новички, — это разница в том, от какой точки рисуется форма. Давай сведём в таблицу, чтобы запомнить раз и навсегда:
| Форма | Команда | Что значат числа |
| Точка | point(x, y) | координаты самой точки |
| Линия | line(x1, y1, x2, y2) | начало и конец |
| Прямоугольник | rect(x, y, w, h) | верхний левый угол, ширина, высота |
| Эллипс | ellipse(x, y, w, h) | центр, ширина, высота |
Видишь подвох? У прямоугольника (x, y) — это угол, а у эллипса то же самое (x, y) — это центр. Поэтому если поставить рядом rect(200, 200, 100, 100) и ellipse(200, 200, 100, 100), они окажутся в разных местах: квадрат уйдёт вправо-вниз от точки 200/200, а круг будет ровно вокруг неё. Это не баг, это просто два разных способа «привязки», и их полезно держать в голове.
Хорошая новость: поведение прямоугольника можно переключить командой rectMode(CENTER) — тогда rect тоже начнёт рисоваться от центра, как эллипс. Но пока мы оставим всё по умолчанию, чтобы не запутаться.
Собираем фигуру: первый силуэт CodeChick
Теперь самое вкусное. По отдельности формы — это скучные кружочки. Магия начинается, когда ты комбинируешь их в одну фигуру, как лепишь снеговика из трёх снежных комьев. Соберём силуэт нашего цыплёнка.
План простой, рисуем сверху вниз по слоям: сначала большое тело, потом голову поменьше сверху, потом глаз и клюв. Порядок важен — в p5.js каждая следующая форма ложится поверх предыдущей, как наклейки в стикерпаке.
function setup() {
createCanvas(400, 400);
background(200, 230, 255);
// тело — большой круг внизу
ellipse(200, 250, 180, 180);
// голова — круг поменьше сверху
ellipse(200, 150, 120, 120);
// глаз — маленькая жирная точка
strokeWeight(10);
point(230, 135);
// клюв — пока простой прямоугольник
strokeWeight(1);
rect(250, 145, 40, 18);
}Результат: на голубом фоне (наше небо) стоит снеговик-цыплёнок: большой круг-тело внизу, круг-голова сверху, на голове справа — чёрная точка-глаз, а сбоку торчит маленький прямоугольный клювик. Ещё не красавец, но это уже узнаваемый CodeChick, собранный из четырёх типов форм.
Разберём по шагам, что здесь происходит:
background(200, 230, 255)заливает весь холст светло-голубым — это небо, мир нашего героя. Заодно стирает всё, что было.- Первый
ellipseрисует тело: центр в точке(200, 250)(нижняя половина холста), диаметр 180. - Второй
ellipse— голова: центр выше, в(200, 150), и он меньше, 120 пикселей. Поскольку он нарисован позже, он ложится поверх тела и немного перекрывает его — получается единый силуэт. strokeWeight(10)делает точку толстой, иpoint(230, 135)ставит глаз чуть правее и выше центра головы.- Мы возвращаем
strokeWeight(1), чтобы контур клюва был тонким, и рисуемrectсбоку от головы.
Попробуй сам поменять числа и посмотри, что будет: сдвинь глаз в point(170, 135) — он переедет на другую сторону. Увеличь клюв до rect(250, 145, 60, 25) — цыплёнок станет носатее. Это и есть творческое программирование: меняешь число — меняется картинка.
Заметь ещё одну вещь, которая пригодится дальше. Голова и тело — это два круга, которые перекрываются. Граница между ними не видна как чёткая линия — они сливаются в общий контур, потому что нарисованы одним цветом и стоят впритык. Этот приём — складывать большую форму из нескольких пересекающихся простых — лежит в основе почти всей рисованной графики. Снеговик, гусеница, облако, гроздь винограда — всё это перекрывающиеся круги. Ты только что научился главному трюку иллюстратора, даже не заметив этого.
Частые ошибки и подводные камни
На этих граблях прыгают почти все новички. Лучше узнать о них заранее.
1. Путать «угол» и «центр» у rect и ellipse
Ты задаёшь rect(200, 200, ...), ждёшь фигуру по центру, а она уезжает вправо-вниз. Помни: у прямоугольника (x, y) — это верхний левый угол, а у эллипса — центр. Если хочешь рисовать прямоугольник от центра, включи rectMode(CENTER).
2. Путать «размер» и «вторую точку»
У линии четыре числа — это две точки (начало и конец). У прямоугольника четыре числа — это угол плюс размер. Если написать rect(50, 50, 350, 350), думая «от угла до угла», получишь огромный прямоугольник шириной и высотой 350 пикселей, который вылезет за холст. Команды выглядят похоже, а смысл чисел разный.
3. Точка размером в один пиксель
Поставил point(200, 200) и не видишь ничего? Точка по умолчанию — это один-единственный пиксель, его легко пропустить. Добавь strokeWeight(8) перед ней, чтобы сделать заметной.
4. Рисовать в неправильном порядке
Если нарисовать глаз до головы, голова закрасит его сверху, и глаз пропадёт. p5.js кладёт формы слоями в том порядке, в каком ты их пишешь. Сначала — то, что снизу (тело, голова), потом — то, что сверху (глаз, клюв).
5. Забыть, что y растёт вниз
Хочешь поднять голову выше — и увеличиваешь y? Голова уедет вниз. В системе координат холста ось y направлена вниз: чем больше число, тем ниже. Чтобы поднять форму, y нужно уменьшать.
Мини-практика: доделай цыплёнка сам
Теперь твоя очередь. Возьми код силуэта CodeChick и доведи его до ума. Вот задания по нарастающей:
- Лапки. Добавь цыплёнку две лапки внизу с помощью
line(). Подсказка: проведи короткие линии от низа тела (примерноy = 335) ещё ниже. Например,line(180, 335, 180, 370)— и вторую такую же чуть правее. - Второй глаз. Сейчас глаз один. Добавь симметричный второй слева от центра головы. Помни про
strokeWeightдо и после. - Земля. Нарисуй под цыплёнком длинный тонкий
rectчерез весь низ холста — пусть стоит на земле, а не висит в небе. - Эксперимент со взглядом. Сделай глаз больше или меньше, меняя
strokeWeight. Найди размер, при котором цыплёнок выглядит самым милым, — это субъективно, и в этом весь кайф.
Не бойся ломать. Поменял число, картинка поехала не туда — просто верни обратно или подбери новое. Именно так художники кодом и работают: маленькими шагами, постоянно глядя на результат.
Когда справишься с заданиями, попробуй задачу со звёздочкой: нарисуй цыплёнку гнездо. Это просто широкий низкий эллипс под телом — например, ellipse(200, 320, 220, 70), поставленный до тела, чтобы цыплёнок сидел в нём, а не за ним. Помнишь про порядок слоёв? Гнездо рисуем первым, тело — поверх. Получится, будто наш герой устроился в своём домике. И вот тут, кстати, особенно ясно видно, зачем эллипсу центр: ты ставишь точку (200, 320) прямо под цыплёнком и просто расширяешь её вширь — гнездо само раскидывается симметрично влево и вправо.
Не существует одного правильного цыплёнка. Сдвинул глаз на пару пикселей — характер поменялся: то удивлённый, то хитрый, то сонный. В этом и смысл: код — это твой инструмент, а каким будет результат, решаешь ты.
Итоги
Сегодня ты освоил четыре кирпичика, из которых строится любая картинка на холсте:
point(x, y)— точка по координатам;line(x1, y1, x2, y2)— линия от точки к точке;rect(x, y, w, h)— прямоугольник от верхнего левого угла;ellipse(x, y, w, h)— эллипс от центра (аcircle(x, y, d)— ровный круг).
Главное, что ты понял: у разных форм числа значат разное — где-то это вторая точка, где-то размер, где-то угол, а где-то центр. И ещё ты впервые скомбинировал формы в одну фигуру и получил узнаваемый силуэт CodeChick. Пока он чёрно-белый и немного угловатый, но скелет уже есть.
В следующем уроке мы возьмёмся за цвет: научимся управлять заливкой и обводкой, разберёмся с моделью RGB — и наш цыплёнок наконец станет жёлтым, с оранжевым клювом и настоящими глазами. Тот самый CodeChick, которого ты узнаешь из тысячи. До встречи на холсте!