Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Book2v1

.pdf
Скачиваний:
23
Добавлен:
21.03.2016
Размер:
17.8 Mб
Скачать

Рис. 25: Результат работы Листинга 22. Прямоугольники, отрисованные в цикле, без обводки.

для заливки и отрисовывам прямоугольник в зависимости от значения переменной i.

Задание 8. Измените код Листинга 22, так, чтобы прямоугольники отрисовывались на холсте в виде сетки, как на Рисунке 26

Рассмотрим пример, когда один цикл работает внутри другого цилка. Такая необходимость может возникнуть, например,если требуется построить двухмерную сетку геометрических форм с определенным шагом, как на Рисунке 27, где показан результат работы кода Листинга 23.

Листинг 23: Рисуем сетку из эллипсов

1

void setup ()

{

2

size (500 ,

500) ;

3smooth () ;

4noLoop () ;

5noStroke () ;

6ellipseMode ( CENTER );

7}

8

9void draw () {

10background (255) ;

11float border = 50;

51

12

float

nw

=

width -2* border ;

13

float

nh

=

height -2* border ;

14

float

number

=

5;

15

float nWstep = nw / number ;

16

float

nHstep

=

nh / number ;

17

for ( int i = 0; i

<

number ; i ++) {

 

18

for ( int j = 0;

j < number ; j ++) {

19

float

x

=

border

+

j* nWstep

+

nWstep /2;

20

float

y

=

border

+

i* nHstep

+

nHstep /2;

21

float size = 5 + (j+i) *10;

 

 

22

float

mColor

= size *1.5;

 

 

23

fill ( mColor , 20 , 50) ;

 

 

24

ellipse (x , y ,

size ,

size );

 

 

25

fill (250) ;

 

 

 

 

 

 

26

ellipse (x ,

y ,

3,

3) ;

 

 

27}

28}

29}

Рис. 26: Результат задания 8. Сетка из прямоугольников разных тонов.

Начнем разбирать код Листинга 23 с метода draw(). В 11-й строке мы определяем переменную border, где будут храниться значения полей вокруг нашей будущей сетки. Например,нужно, чтобы сетка отступала на 50 пикселей от каждой стороны окна. Значит, оставшееся поле для сетки будет равно ширине окна за вычетом размера двух полей. Эти рассуждения записаны в 12-ю строку. Переменная nw отвечает за ширину сетки, соответственно, переменная nh отвечает за высоту сетки (строка 13).

52

Количество ячеек мы объявили в строке 14, в нашем случае их будет пять и это значение будет храниться в переменной number. Далее мы определяем габариты ячейки в строках 15 и 16, записываем их значения в соответствующие переменные nWstep и nHstep.

Рис. 27: Результат работы Листинга 23. Сетка из эллипсов.

Теперь у нас все готово для того, чтобы нарисовать сетку. Как показано на Рисунке 27, нам нужно отрисовать в центрах ячеек эллипсы разного размера и цвета: очевидно, что для этого придется определить две новые переменные. Но и отрисовка эллипса требует определения его координат, значит, нужны еще две переменные.

В строке 17 мы пишем цикл for, от 0 до number (количество ячеек) для того, чтобы указать ряд будущих ячеек. Как только мы указали ряд, нам требуется обойти все ячейки этого ряда и отрисовать в них эллипсы.

53

Итак, переменная i будет отвечать за смещение по оси Y (т.е. выбор номера ряда), переменная j будет отвечать за смещение по оси X (т.е. за выбор ячейки внутри ряда). Рассмотрим определение этих переменных.

Задание 9. Измените код Листинга 23 так, чтобы эллипсы отрисовывались от большего к меньшему и были раскрашены в тона другого цвета, например синего.

Начнем определять координаты наших эллипсов. При каждой итерации внутреннего цикла у нас есть в наличии значения переменных i и j, размер полей отступа – border и размер ячейки. Этого материала достаточно, чтобы определить центр текущий ячейки. Так мы определяем переменные центра ячейки X и Y в строках 19 и 20. Размер эллипса будем определять в зависимости от расположения его ячейки, а именно, от переменных i и j в 22-й строке. В этой же строке будем определять цвет как переменную mColor.

Как только мы определили все необходимые нам переменные, мы занимаемся отрисовкой эллипса (строки 23 и 24). В нашем случае удобно воспользоваться отрисовкой не от левого верхнего угла, а от центра, поэтому мы в еще в строке 6 вызвали метод ellipseMode() с аргументом CENTER, что «включило» нам требуемый режим. Чтобы показать, что эллипсы находятся в строгой прямоугольной сетке, мы отрисовываем в центре каждого эллипса еще один поменьше и белого цвета (строки 25, 26).

В этом параграфе мы рассмотрели работу циклами с ритмом. Мы использовали цикл for, однако в Processing существуют и другие возможности для работы с циклами: while и for each. О них мы будем говорить далее, но не так подробно. Информацию о них вы можете найти на официальном сайте https://processing.org/reference/ в разделе Iteration. Там же, в разделе Conditionals, дано описание возможности остановки работы цикла и пропуска текущей итерации.

5.3Движение и анимация

Описывая процесс рисования на языке Processing, мы подразумеваем, что при каждом запуске программы (скетча) наш холст является пустым, как, впрочем, пуст холст и перед классическим художником, готовящимся к созданию своего произведения. Однако если с помощью карандашей и красок художник создает свой шедевр на одном холсте один

54

раз, то цифровой холст используется совсем иначе: при каждом запуске программы картина создается заново, даже если в код не были внесены никакие изменения. Таким образом, у цифрового художника появляется выбор: он может остаться в привычных рамках статического произведения, сохранив и распечатав созданную им на холсте картину, а может использовать возможности многократного обновления на цифровом холсте созданного им произведения. разработали «робота художника», который каждый раз, когда его запускают, рисует одну и туже картину по вашим правилам. Эти правила вы и пишите в виде исходного кода.

В том случае, если ваша цель – создание статического графического произведения, то вам потребуется просто сохранить результат в файл. Вы можете вызвать метод saveFrame("myArt.png");, в аргументе которого в двойных кавычках указывается путь и имя файла для записи картинки с холста приложения. Также обязательно нужно указать расширение файла, например, TIFF (.tif), JPEG (.jpg), или PNG (.png). Вызов метода можно расположить, как в Листинге 20, после 15-й строки.

Однако если вы хотите создать интерактивное произведение, которое, например, позволит зрителям принимать участие в том, что появляется на холсте, вам не обойтись без динамики и анимации.

Рассмотрим код Листинга 24. Он очень прост и напоминает наш самый первый скетч за исключением нескольких моментов. Первое отличие

– это строка 6. В ней комментарием дан вызов метода noLoop(): две наклонных черты (два слеша) служат специальным символом, делая строку невидимой для программы, но не для программиста. Поставив два слеша, мы сделали строку 6 пустой для программы, но если возникнет необходимость снова вызвать метод noLoop(), то нужно будет просто удалить эти два слеша.

Листинг 24: Рисуем крестик и печатаем в консоль

1

void setup

() {

2

size (300 ,

300) ;

3smooth () ;

4 strokeWeight (30) ; 5 stroke (100) ;

6// noLoop () ;

7}

8

9void draw () {

10 background (0) ;

11 line (100 ,100 , 200 , 200) ;

12 line (200 ,100 , 100 , 200) ;

13println ( frameCount );

14}

55

Второе отличие кода Листинга 24 – строка 13. В ней мы вызываем метод println() (от английского print line ), и передаем ему аргументом переменную frameCount. Переменная frameCount объявлена не нами, а разработчиками Processing. Но по сути своей это такая же переменная, как и объявленные нами переменные i и k.

Метод println() выводит свои аргументы в черное поле внизу скетча в редакторе Processing (см. Рисунок 28): в это поле, которое называют консолью, выводятся цифры – номера фреймов. Но прежде чем начать разбираться с этими цифрами, давайте изменим код и посмотрим на Листинг 25.

Рис. 28: Результат работы Листинга 24. Снимок экрана.

Запустив код Листинга 25, вы увидите, что крестик начнет двигаться.

56

Это движение происходит по двум причинам. Во-первых, мы используем переменную, которая постоянно растет на 1. Во-вторых, вызов метода draw() происходит не один раз, а в цикле. Более того, метод draw() вызывается бесконечно, пока вы не выключите программу или компьютер. При этом мы не видим, в какой именно строке и в каком файле происходит вызов метода draw(), полагаясь только на разработчиков Processing. Каждый раз, когда вызывается метод draw(), крестик отрисовываетсяался с координатами при значении переменной frameCount = 1. Эта переменная и содержит номер текущего кадра, который отрисовывается на экране. И далее, как в классической мультипликации, мы рисуем следующий кадр. В следующем кадре мы заливаем холст черным в строке 10 и заново рисуем крестик при frameCount = 2.

Листинг 25: Анимируем крестик

1

void setup

() {

2

size (300 ,

300) ;

3smooth () ;

4 strokeWeight (30) ; 5 stroke (100) ;

6// noLoop () ;

7}

8

9void draw () {

10

background (0) ;

 

11

line ( frameCount ,100 , 100+ frameCount ,

200) ;

12

line (100+ frameCount ,100 , frameCount ,

200) ;

13// println ( frameCount );

14}

Важно отметить, что при таком покадровом подходе к анимации, каждый следующий кадр «ничего не знает» о предыдущем. Когда мы с вами смотрим на анимацию крестика, то мы видим ОДИН крестик, который движется по экрану, а на самом деле этого ОДНОГО крестика нет. Каждый раз отрисовка происходит заново, программа перерисовывает экран новой картинкой. Чтобы продемонстрировать это, давайте рассмотрим код Листинга 26.

Листинг 26: Анимириуем крестик без заливки фона

1

void setup

() {

2

size (300 ,

300) ;

3smooth () ;

4 strokeWeight (30) ;

5background (0) ;

6}

7

57

8 void draw () {

9stroke ( frameCount );

10

line ( frameCount ,100 , 100+ frameCount ,

200) ;

11

line (100+ frameCount ,100 , frameCount ,

200) ;

12

}

 

Код Листинга 26 отличается от Листинга 25 тем, что метод background(0) вызывается один раз в методе setup(), а вот метод stroke(), напротив, вызывается методом draw() так же часто, как и сам метод draw(). Аргументом а метода stroke() мы передаем frameCount. Таким образом с каждым новым кадром мы меняем цвет линии и не заливаем наш холст черной краской после предыдущего кадра. Мы как бы оставляем предыдущий мультипликационный кадр и рисуем прямо на нем (см. Рисунок 29).

Рис. 29: Результат работы Листинга 26. Крестик и след его движения по горизонтали.

Задание 10. Измените 10-ю и 11-ю строки кода Листинга 26 так, чтобы на холсте было отрисовано изображение, как на Рисунке 30. Крестик должен двигаться по диагонали от левого верхнего угла в правый нижний угол.

При помощи прямоугольника (а на самом деле при помощи любой заливаемой цветом фигуры) можно добиться интересных художественных

58

Рис. 30: Результат выполнения задания 10. Крестик и след его движения по диагонали.

эффектов, как это продемонстрировано в коде Листинга 27.

Листинг 27: Движущийся шарик

1

 

 

2

void setup ()

{

3

size (500 ,

500) ;

4smooth () ;

5}

6

7float counter ;

8

9void draw () {

10noStroke () ;

11fill (10 , 50) ;

12rect ( -1 , -1 , width +1 , height +1) ;

13

14 float ny = sin ( counter ) *100+200; 15 float nx = counter *10;

16

17stroke (250) ;

18strokeWeight (20) ;

19line (nx , ny , nx , ny );

20

21 counter = counter + 0.1;

22

23 if ( nx > width ){

59

24counter = 0;

25}

26}

27

 

28

void keyPressed () {

29

if ( key == ’s ’) saveFrame (" myProcessing . png ");

30

}

Результат выполнения кода Листинга 27 представлен на Рисунке 31. Мы отрисовываем отрезок «нулевой длины»: координаты его начальной и конечной точек равны. Координата по оси Y изменяется по закону синуса: в 14-й строке мы вызываем метод sin() и передаем ему переменную counter, которая увеличивается с шагом 0.1 в 21-й строке. Координата по оси X изменяется линейно, в 15-й строке ей дается приращение в виде текущего значения переменной counter, умноженного на 10. Как только значение этой координаты становится больше ширины холста, мы обнуляем счетчик (см. строки 23 и 24). Логика изменения координаты Y более сложная: мы меняем координату Y по синусоидному закону. Метод sin() возвращает значение синуса, принятого в радианах аргумента (строка 14). Более детально работа с тригонометрическими функциями будет рассмотрена в отдельной главе.

Рис. 31: Результат выполнения Листинга 27. Фазы движения шарика.

Логика движения нашего нулевого отрезка довольно проста. Интерес, как нам кажется, представляет художественный эффект в виде шлейфа. Шлейф тянется за объектом, повторяя его движение и растворяясь в черном фоне холста. Такого эффекта мы добились, используя отрисовку прямоугольника в 12-й строке. Прямоугольник мы отрисовываем с заливкой fill(10,50) – черного цвета и с прозрачностью.

60

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]