Графический редактор “Раскрашка”
Применим полученные знания для выполнения довольно большого проекта - написания графического редактора “Раскрашка”. В этом редакторе можно закрашивать заложенные в программу контурные рисунки. Опишем схему работы программы.
На экране находится контурный рисунок и палитра цветов. Для выбора цвета закраски передвигаем курсор - картинку-указатель на прямоугольник с нужным цветом и нажимаем Enter. Затем перемещаем курсор на основное поле так, чтобы он указывал на какую-нибудь область рисунка. После нажатия на Enter область закрашивается выбранным ранее цветом. Для правильной работы оператора закрашивания нужно, чтобы все границы были нарисованы одним и тем же цветом. Понятно, что этот цвет следует исключить из палитры, так как область, закрашенную цветом границы, нельзя будет перекрасить другим цветом.
За основу “Раскрашки” возьмем программу “Рожица”. Загрузим программу и запишем ее в файл RASCRAS.BAS куда и будем вносить все изменения.
Начнем с курсора. Зададим шаблон курсора-стрелки, отмечая точки курсора единичками.
|
|
Как и раньше, выведем курсор на экран для дальнейшего запоминания в памяти, после чего экран очистим. Но цвет 1 - это синий цвет, и стрелка будет плохо видна на экране. Поэтому при выводе заменим цвет курсора на более яркий.
dx = 7: dy = 15
SCREEN 7: xmax = 319: ymax = 199 DIM a%(40) FOR y = 0 TO dy FOR x = 0 TO dx READ c: IF c = 1 THEN c = 10 ‘Изменение цвета курсора PSET (x, y), c NEXT x NEXT y
‘Запоминаем картинку в массиве и очищаем экран
GET (0, 0)-(dx, dy), a% CLS |
Теперь рисуем рамку основного поля, палитру и индикатор.
LINE (0, 0)-(xmax, ymax), 15, B LINE (80, 0)-(80, ymax), 15 LINE (10, 10)-(70, 160), 15, B<
‘Заполняем палитру красками
c = 14 FOR y = 20 TO 150 STEP 10 LINE (10, y)-(80, y), 15 PAINT (40, y-5), c, 15 c = c - 1 NEXT y
‘Индикатор
CIRCLE (40,180), 10, 15 |
Далее должна следовать часть программы, создающая контурный рисунок на основном поле. Нарисуем, например, “мишень”:
FOR r = 10 TO 100 STEP 15 CIRCLE (200, 100), r, 15 NEXT r |
Чтобы контурный рисунок не мог нечаянно выйти за пределы основного поля, можно ограничить область вывода с помощью оператора VIEW:
VIEW (x1, y1)-(x2, y2) - устанавливает прямоугольное окно вывода с новой системой координат, начало которой располагается в левом верхнем углу окна. Относительные (локальные) координаты позволяют не задумываться о том, в каком месте экрана будет в дальнейшем расположен рисунок. Если по каким-либо причинам требуется сохранить в окне систему координат экрана, то следует использовать вариант
VIEW SCREEN (x1, y1)-(x2,
y2).
Чтобы восстановить возможность вывода на весь экран, следует применить оператор VIEW без параметров.
Следующую часть программы - управление курсором - позаимствуем из программы “Рожица”, только в комментариях заменим “картинку” на “курсор”. Изменим и шаг перемещения курсора, чтобы можно было закрашивать маленькие области. (Оптимальный вариант - ввести переменную, значение которой можно было бы изменять, нажимая какие-то клавиши на клавиатуре, например, клавиши“<” и “>”).
‘Задаем константы
lf$ = CHR$(0) + CHR$(75) rt$ = CHR$(0) + CHR$(77) up$ = CHR$(0) + CHR$(72) dn$ = CHR$(0) + CHR$(80)
‘Задаем исходное положение курсора и выводим его на экран
x0 = 165: y0 = 45: x = x0: y = y0 PUT (x0, y0), a%
‘Ждем нажатия клавиши
10 w$ = INKEY$: IF w$ = "" THEN GOTO 10
‘Вычисляем новое положение курсора
SELECT CASE w$ CASE lf$: x = x0 - 2: IF x < 0 THEN x = x0 CASE up$: y = y0 - 2: IF y < 0 THEN y = y0 CASE rt$: x = x0 + 2: IF x + dx > xmax THEN x = x0 CASE dn$: y = y0 + 2: IF y + dy > ymax THEN y = y0 CASE CHR$(27): STOP CASE ELSE: GOTO 10 END SELECT
‘Стираем курсор на старом и выводим на новом месте
PUT (x0, y0), a% PUT (x, y), a%
‘Обновляем переменные
x0 = x: y0 = y GOTO 10 |
Добавим теперь в оператор выбора реакцию программы на нажатие клавиши Enter. Эту клавишу мы нажимаем в двух случаях: когда хотим выбрать цвет закрашивания, и когда указываем область для закраски. Различить эти случаи легко: в первом случае острие стрелки (точка x0, y0) находится в прямоугольнике (10, 10)-(70, 160) - это границы палитры; во втором - в прямоугольнике (80, 0)-(xmax, ymax) - это границы основного поля.
CASE CHR$(13) IF x0 > 10 AND x0 < 70 AND y0 > 10 AND y0 < 160 THEN ‘Определяем цвет краски на палитре c = 15 - y0 \ 10 ‘Прячем курсор PUT (x0, y0), a% ‘закрашиваем индикатор PAINT (40, 180), c, 15 ‘и восстанавливаем курсор на том же месте PUT (x0, y0), a% END IF |
Получить формулу, которая связывает номер цвета с расположением краски на палитре, поможет следующая таблица:
Интервал |
Номер |
Цвет |
10 < y < 20 |
1 |
14 |
20 < y < 30 |
2 |
13 |
30 < y < 40 |
3 |
12 |
... |
... |
... |
150<y<160 |
15 |
0 |
Легко видеть, что номер интервала и цвет в сумме равны 15 в любой строке таблицы, а номер интервала равен количеству полных десятков в числе y. Вычислить номер интервала можно с помощью операции целочисленного деления: n = y \ 10. После этого цвет краски получается по формуле c = 15 - n.
Заметим, что простота формулы есть результат простой закономерности в расположении цветов палитры. В других случаях может оказаться проще “считывать” цвет непосредственно с экрана, используя функцию POINT.
POINT(x, y) - возвращает цвет пикселя экрана с координатами (x, y).
Зачем потребовалось стирать курсор перед закрашиванием индикатора? Дело в том, что при закраске области может оказаться, что курсор задевает ее границу. В этом месте граница исчезнет, и через образовавшуюся “дыру” краска вытечет за пределы области. Поэтому перед любым закрашиванием мы будем убирать курсор с экрана, а после - возвращать на экран. (“Прятать” курсор придется и при определении функцией POINT цвета точки (x0, y0), которая находится под курсором.)
Займемся теперь основным полем.
IF x0 > 80 AND x0 < xmax AND y0 > 0 AND y0 < ymax THEN ‘Прячем курсор PUT (x0, y0), a% ‘Закрашиваем область PAINT (x0, y0), c, 15 ‘Восстанавливаем курсор PUT (x0, y0), a% END IF |
Задание. Придумать и вставить в программу свой рисунок для раскрашивания (ниже приведен пример выполнения задания).