Вводное задание 1. Рисуем человечка и единорога (введение в for/if)
В этом задании вы нарисуете человечка и единорога с помощью языка программирования JavaScript, блокнота, браузера и удобной библиотеки.
Сдавать задание нужно на уроке.
0) Поднятие окружения
Скачайте архив библиотечки отсюда и разархивируйте его в какую-нибудь папку.
Там куда вы разархивировали библиотечку зайдите в подпапку p5-zip/empty-example
. Откройте sketch.js
любым текстовым редактором, например Notepad++ или Sublime Text:
function setup() {
}
function draw() {
}
Это две пока что пустые функции:
- Первая функция
setup
выполняется в начале работы приложения, например она может что-то настроить или подготовить для работы вашей программы (setup переводится как “настроить”). - Вторая функция
draw
- выполняется каждый раз для отображения нового кадра вашей программы, т.е. эта функция рисует новый кадр (draw переводится как “рисовать”).
Итак, в setup
хочется настроить экран (так называемый холст, на котором будем рисовать) и зарисовать весь фон одним цветом. А в draw
нарисовать какие-нибудь геометрические фигуры:
function setup() {
createCanvas(640, 480); // Указываем размер холста на котором будем рисовать
background(50, 50, 100); // Зарисовываем фон одним цветом
}
function draw() {
var ellipseColor = color(255, 255, 0); // Создаем переменную хранящую цвет
fill(ellipseColor); // Указываем цветом заливки - цвет из переменной ellipseColor
var centerX = 320; // Пример того, как можно объявлять переменные
var centerY = 240; // Ключевое слово var перед названием переменной - от слова variable (в переводе - переменная)
ellipse(centerX, centerY, 200, 100); // Рисуем эллипс с центром в точке (centerX, centerY)=(320, 240) и размером 200x100
}
Это уже полноценная программа, которая создает холст размера 640x480 и рисует на нем эллипс.
Чтобы увидеть результат - достаточно открыть p5-zip/empty-example/index.html
в браузере (например дважды кликнув по этому файлу). По мере редактирования sketch.js
чтобы увидеть новый результат: нужно сохранить файл sketch.js
и обновить страничку в браузере (Ctrl+R
или F5
).
Обратите внимание, что в системе координат холста ось абсцисс (X) идет вправо, а ось ординат (Y) - вниз:
1) Функции
Допустим мы хотим сделать функцию “нарисовать человечка”:
function setup() {
// Здесь нужно указать размер холста на котором вы будете рисовать
// А так же заполнить холст одним фоновым цветом
}
function draw() {
drawHuman(320, 240); // Рисуем человечка вызовом функции, которая объявлена ниже, при этом мы передаем в функцию два аргумента - координаты центра человечка
}
function drawHuman(x, y) {
translate(x, y); // Смещаем начало отсчета координат из текущего положения (верхний левый угол) на x пикселей вправо и y пикселей вниз
ellipse(0, -40, 20, 20); // Голова относительно текущей системы координат в точке (0, -40), т.е. на 40 пикселей выше чем (x, y) и с диаметром 20
line(0, -30, 0, 30); // Тело идет от нижней точки головы (0, -30) до точки (0, 30)
line(0, -20, -20, -10); // Рука слева
// Доделайте эти вызовы:
// line(...); // Рука справа
// line(...); // Нога слева
// line(...); // Нога справа
}
Доделайте функцию drawHuman
, чтобы получился человечек.
Если добавить после вызова translate
вызов rotate(PI / 4)
, то текущая система координат повернется на 45 градусов по часовой стрелке, а значит и дальнейшая отрисовка человечка в этой системе приведет к тому, что человечек повернулся на эти же 45 градусов по часовой стрелке.
Убедитесь что вы поняли, как работает translate
и rotate
. Что будет если отрисовка частей человечка не симметрична относительно точки (0, 0)? Как он будет крутиться в таком случае?
2) Единорог
Теперь создайте функцию drawUnicorn
, которая рисует Единорога из палочек и эллипсов, похожего на этого:
Т.е. у вас должны быть нарисованы:
- Тело
- Шея и голова
- Рог
- Четыре ноги
- Хвост
Если вы добавите больше деталей, чтобы было больше похоже на картинку выше или любое другое изображение единорога в интернете - будет еще лучше.
3) Много людей, много единорогов
Теперь когда у вас есть функция рисующая человека и функция рисующая единорога, попробуйте нарисовать обоих примерно таким образом:
function draw() {
var canvasWidth = 640; // Ширина холста
var canvasHeight = 480; // Высота холста
drawHuman(canvasWidth/4, canvasHeight/2); // Рисуем человечка слева
drawUnicorn(canvasWidth*3/4, canvasHeight/2); // Рисуем единорога справа
}
Что произойдет если вы поменяете местами вызовы drawHuman
и drawUnicorn
?
Что произойдет если вы оставите лишь вызов drawUnicorn
-функции?
Почему так произошло?
Дело в том, что когда вы в функции делаете вызов translate(...)
, то сдвигается весь холст. И не только на время выполнения этой функции, но и на все остальное время работы программы.
Поэтому чтобы функция не двигала холст и не мешала таким образом другой функции - нужно вернуть холст в изначальное положение. Т.е. если в начале функции было сделано например translate(x, y)
, то в конце функции надо сдвинуть холст обратно: translate(-x, -y)
.
Но т.к. менять и откатывать изменения в состоянии холста (точка отсчета, поворот) нужно часто, то есть более удобный способ:
для сохранения и восстановления состояния есть метод push и pop соответственно:
push(); // Сохраняем текущую систему координат
translate(239, 478); // Сдвигаем точку отсчета системы координат
rotate(PI / 2); // Поворачиваем систему координат на 90 градусов (т.к. PI радиан = 180 градусов)
...
Какое-то рисование с текущей системой координат
...
pop(); // Восстанавливаем состояние системы координат (точку отсчета и ориентацию) к моменту вызова соответсвующего push()
4) Очень много людей и единорогов (введение в for)
Чтобы создать очень много людей и единорогов - можно воспользоваться циклами. Вот пример простейшего цикла:
var canvasWidth = 640;
var canvasHeight = 480;
function setup() {
createCanvas(canvasWidth, canvasHeight);
background(50, 50, 100);
}
function draw() {
var i;
for (i = 1; i <= 10; i++) {
line(i*10, canvasHeight*1/4, i*10, canvasHeight*3/4);
}
}
Сделайте так, чтобы линии занимали холст равномерно (подсказка: используйте переменную canvasWidth по аналогии с canvasHeight*1/4).
Создайте по хотя бы два ряда из людей и единорогов.
5) Бегущий единорог (введение в if)
Давайте теперь добавим анимации. Вот простой вариант
var canvasWidth = 640;
var canvasHeight = 480;
function setup() {
createCanvas(canvasWidth, canvasHeight);
background(50, 50, 100);
x = 10; // Изначальное положение шарика
}
var x; // Так как положение шарика от кадра к кадру будет меняться, то нужно хранить его в глобальной переменной
function draw() {
ellipse(x, canvasHeight/2, 24, 24);
x += 1;
}
Возникло две проблемы:
- Шарик оставляет за собой след
- Шарик уходит за пределы холста
-
Чтобы очищать экран каждый раз - нужно перед тем как рисовать эллипс вызывать функцию
background
(она заливает весь экран цветом и пока что вызывалась лишь на этапе настройки программы, но теперь она нужна нам в начале каждого кадра чтобы очищать экран от предыдущего кадра). -
Чтобы возвращать шарик в начало как только он выходит за пределы экрана, можно добавить в конец
draw
:
if (x > canvasWidth) {
x = 0;
}
Сделайте теперь:
- Бегущего человечка
- Бегущего единорога
- Сценку в которой бежит много единорогов и человечков в разные стороны