Мультипликация (движение картинки)

   Управление картинкой на “пустом” экране ничем не отличается от управления окружностью - нарисовал - стер - нарисовал на новом месте. Но если на экране уже есть какое-то изображение, на фоне которого должна двигаться картинка, то возникает проблема - как стереть “старое” изображение, чтобы не испортить фон.

   Здесь нам поможет “связка” операторов GET и PUT.

   Вспомним, что при выводе оператором PUT картинки на экран, по умолчанию над цветом точки экрана и цветом точки картинки выполняется логическая операция “исключающее или”. При этом на месте точек, совпадающих по цвету, появляются черные “дыры” (точнее, прозрачные “дыры”, через которые виден цвет фона). Значит, если наложить картинку саму на себя, то она исчезнет с экрана. Если фон экрана уже содержит изображение, то при первом выводе картинки ее цвета изменятся (к сожалению!), но зато при втором выводе восстановится фоновое изображение. В ряде случаев изменение цветов картинки нежелательно, тогда приходится использовать другой алгоритм, который мы разберем позже.

   Итак, за основу возьмем алгоритм управления окружностью и программу CIRCLES.BAS. Дополним алгоритм “нулевым” пунктом:

      0. Рисуем и запоминаем картинку

и немного модифицируем остальные пункты:

1.      Задаем константы.

  1. Задаем исходное положение картинки и выводим ее на экран.
  2. Ждем нажатия клавиши.
  3. Вычисляем новое положение картинки.
  4. Стираем картинку на старом и выводим ее на новом месте.
  5. Обновляем переменные, отвечающие за положение картинки, и переходим к пункту 3.

   Положение картинки на экране задается следующим образом: фиксируется некоторая точка картинки и задаются ее координаты на экране. За эту точку картинка “привязывается” к экрану, поэтому ее иногда называют точкой привязки. В качестве точки привязки возьмем левый верхний угол (вершину) прямоугольной области, в которой размещена картинка.

x =

0

1

2

3

4

5

6

7

8

y = 0

 

 

7

7

7

7

7

 

 

1

 

8

 

 

 

 

 

8

 

2

8

 

 

8

 

8

 

 

8

3

8

 

3

3

 

3

3

 

8

4

8

 

 

 

 

 

 

 

8

5

8

 

 

12

12

12

 

 

8

6

 

8

 

 

 

 

 

8

 

7

 

 

8

8

8

8

8

 

 

   Для рисования картинки можно использовать любые графические операторы, но если картинка маленькая, удобнее задавать ее по точкам. Посмотрим на увеличенный рисунок рожицы.

 

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

   В программе на Quick Basic таблицу чисел удобно задать с помощью оператора DATA.

 
‘Задаем картинку
 
DATA 0, 0, 7, 7, 7, 7, 7, 0, 0
DATA 0, 8, 0, 0, 0, 0, 0, 8, 0
DATA 8, 0, 0, 8, 0, 8, 0, 0, 8
DATA 8, 0, 3, 3, 0, 3, 3, 0, 8
DATA 8, 0, 0, 0, 0, 0, 0, 0, 8
DATA 8, 0, 0, 12, 12, 12, 0, 0, 8
DATA 0, 8, 0, 0, 0, 0, 0, 8, 0
DATA 0, 0, 8, 8, 8, 8, 8, 0, 0
 
‘Выводим ее на экран
 
SCREEN 7
DIM a%(40)
FOR y = 0 TO 7
   FOR x = 0 TO 8
      READ c: PSET (x, y), c
   NEXT x
NEXT y
 
‘Запоминаем картинку в массиве и очищаем экран
 
GET (0, 0)-(8, 7), a%
CLS
 
‘Задаем константы
 
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 - 5
   CASE  rt$: x = x0 + 5
   CASE  up$: y = y0 - 5
   CASE  dn$:  y = y0 + 5
   CASE CHR$(27): STOP
   CASE ELSE: GOTO 10
END SELECT
 
‘Стираем картинку на старом и выводим на новом месте
 
PUT (x0, y0), a%
PUT (x, y), a%
 
‘Обновляем переменные
 
x0 = x: y0 = y
GOTO 10

   Запишем программу в файл ROZICA.BAS и попробуем ее выполнить. Пока “рожица” бегает по экрану - все хорошо. Но при попытке увести ее за экран появляется сообщение об ошибке “Illegal function call” и высвечивается строка с оператором PUT(x, y), a%. Что ж, будем контролировать значения переменных x и y, а при необходимости, восстанавливать прежние значения. Это просто для случаев движения влево или вверх, так как (x, y) - координаты левого верхнего угла картинки:

CASE lf$: x = x0 - 5: IF x < 0 THEN x = x0

CASE up$: y = y0 - 5: IF y < 0 THEN y = y0

   

Если же мы движемся вправо или вниз, то необходимо чтобы правый нижний угол картинки еще помещался на экране. Чтобы не менять во всей программе параметры экрана при их изменениях, введем переменные xmax - номер самой правой точки экрана и ymax - номер самой нижней точки экрана (для SCREEN 7 xmax = 319, ymax = 199). То же самое относится и к изменению размеров картинки - пусть она при выводе в левый верхний угол экрана занимает место от 0 до dx по горизонтали и от 0 до dy по вертикали. Тогда проверочные условия примут вид:

CASE rt$: x = x0 + 5: IF x + dx > xmax THEN x = x0

CASE dn$: y = y0 + 5: IF y + dy > ymax THEN y = y0

   Естественно значения dx и dy задавать после операторов DATA, а переменные xmax и ymax инициализировать после оператора SCREEN. В результате доработок получим следующую программу:

 
‘ ---------- Программа “Рожица” ----------

‘Задаем картинку
 
DATA 0, 0, 7, 7, 7, 7, 7, 0, 0
DATA 0, 8, 0, 0, 0, 0, 0, 8, 0
DATA 8, 0, 0, 8, 0, 8, 0, 0, 8
DATA 8, 0, 3, 3, 0, 3, 3, 0, 8
DATA 8, 0, 0, 0, 0, 0, 0, 0, 8
DATA 8, 0, 0, 12, 12, 12, 0, 0, 8
DATA 0, 8, 0, 0, 0, 0, 0, 8, 0
DATA 0, 0, 8, 8, 8, 8, 8, 0, 0
dx = 8: dy = 7
 
‘Выводим ее на экран
 
SCREEN 7: xmax = 319: ymax = 199
DIM a%(40)
FOR y = 0 TO dy
   FOR x = 0 TO dx
      READ c: PSET (x, y), c
   NEXT x
NEXT y
 
‘Запоминаем картинку в массиве и очищаем экран
 
GET (0, 0)-(dx, dy), a%
CLS
 
‘Задаем исходное положение картинки и выводим ее на экран
 
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 - 5: IF x < 0 THEN x = x0
   CASE  up$: y = y0 - 5: IF y < 0 THEN y = y0
   CASE  rt$: x = x0 + 5: IF x +  dx > xmax THEN x = x0
   CASE  dn$: y = y0 + 5: 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

   Задание. Запишите программу под тем же именем. Нарисуйте фон, по которому будет двигаться рожица. Убедитесь, что при движении рожицы фон не портится. Задайте вместо рожицы другую картинку (человечка, кошку, крестик и т.д.). Сохраните результат под другим именем.

Сайт создан в системе uCoz