2.1.9 Некоторые рекомендации.
Для того, чтобы получить благоприятный результат, надо придерживаться нескольких основополагающих принципов
Во-первых, помните, что для получения гладкой и
плавной анимации, напоминающей движение реальных тел в живой природе,
надо стараться делать отдельные фазы движения с минимальными
изменениями. Чем проще, тем лучше Глаз сам поможет обмануть наблюдателя.
Во-вторых, необходимо помнить, что если у Вас
есть последовательность из N кадров, то за N ным кадром идет первый
кадр. И потому изменения при переходе от кадра N к кадру 1 должны быть
столь же минимальны, как при переходе от кадра 1 к кадру 2 То есть
последовательность смены кадров должна быть ЗАМКНУТА Наиболее часто
встречающаяся ошибка начинающих составление ОТКРЫТОЙ последовательности
спрайтов, в которой последний спрайт плохо согласован с первым-
В-третьих, если Вы приступили к работе над
последователь ностью кадров, то на первых порах не перемещайте спрайты
по экрану, а ограничьтесь печатью всей последовательности попеременно в
одной позиции. Это даст Вам возможность легко обнаружить ошибки и
поправить их. Даже очень малая несогласованность в движении отдельных
точек изображения может привести к очень плохим конечным результатам, а
причины плохого результата очень трудно обнаружить на двигающихся
спрайтах.
В заключение, надо сказать насколько олов и о
работа с цветом. До снх пор все, что иы писали об анимации спрайтов,
относилось к черно белой (или одноцветной) печати. Для анимации цветных
спрайтов надо поинить еще и о проблемах, связанных с экраном цветовых
атрибутов "Спектрума".
По содержанию наших предыдущих книг Вы знаете,
что цветовые атрибуты "Спектрума" привязаны не к пикселам, а к
знакоместам и разрешение экрана цветовых атрибутов составляет 32X24
знакоместа (вместо 256X192 пиксела в черно-белой графике). Каждое
знакоместо - это квадрат размером 8X8 пикселов
Что же делать, чтобы двигать цветной спрайт?
Прежде всего, здесь от Вас потребуется не только написать процедуру для
перемещения черно-белого шаблона, но и процедуру для перемещения
цветных атрибутов спрайта. Второй вопрос - как их двигать? Очевидно,
что они могут быть двинуты только на величину знакоместа, т.е не менее,
чем на восемь пикселов Но если Вы попробуете и черно белую составляющую
двигать тоже на 8 пикселов за один такт, то увидите, что результат
будет очень грубын. Фактически это уже будет не растровая анимация, а
блочная, причем такого сорта, какую можно получить и из БЕЙСИКа с
помощью оператора PRINT AT Поэтому здесь делают так, что на один
такт движения атрибутов приходятся несколько тактов движения
черно-белого шаблона
Если черно-белый шаблон двигать на 4 пиксела за
такт, то на два такта движения шаблона придется один такт движения
атрибутов. Если двигать ч/б шаблон на 2 пиксела за такт, то на четыре
такта движения шаблона придется один такт движения атрибу тов.
Но и здесь возможны интересные решения Так,
напринер, в программе Everyone's a Wally (фирма Mikrogen) герои
двигаются по более хитрому закону, когда на шесть тактов движения
шаблона приходится два такта движения атрибутов. Как это сделано,
показано на рис 18 Шаблон спрайта в этой игре имеет размер 16X16, т.е.
в ширину занимает 2 знакоместа. Отдельные кадры печатаются со смещением
в 2 пиксела и поэтому бывают моменты, когда шаблон растягивается на три
знакоместа. Можно было бы атрибуты спрайта всегда печатать с размером 3
знакоместа в ширину, но для большей плавности перемещения в игре
сделано так, что атрибуты иногда занимают два знакоместа, а иногда три.
Условные
|
обозначения
|
ххххх -
ААААА 00000 -
|
шаблон атрибуты пустые места
|
Кадр
|
1
|
ХХХХХХХХ АААААААА
|
ХХХХХХХХ АААААААА
|
|
|
Кадр
|
2
|
ООХХХХХХ АААААААА
|
ХХХХХХХХ АААААААА
|
ХХОООООО АААААААА
|
|
Кадр
|
3
|
ООООХХХХ АААААААА
|
ХХХХХХХХ АААААААА
|
ХХХХОООО АААААААА
|
|
Кадр
|
4
|
ООООООХХ АААААААА
|
ХХХХХХХХ АААААААА
|
ХХХХХХОО АААААААА
|
|
Кадр
|
5
|
|
ХХХХХХХХ АААААААА
|
ХХХХХХХХ АААААААА
|
|
Кадр
|
6
|
|
ООХХХХХХ АААААААА
|
ХХХХХХХХ АААААААА
|
ХХОООООО АААААААА
|
Кадр
|
7 =
|
Кадру 1
|
ООООХХХХ АААААААА
|
ХХХХХХХХ АААААААА
|
ХХХХОООО АААААААА
|
Рис. 18 Организация движения шаблона и цветовых атрибутов в программе Everyone's a Wally.
Как видите, здесь нет полной цикличности в
сиене кадров Так. кадр 1 равен кадру 7 только с точки зрения шаблона С
точки зрения атрибутов они различаются. Если бы нашу последовательности
продолжить, то оказалось бы, что полное соответствие наступит только на
кадре 13. Такое решение программистов обеспечило довольно неплохую
гладкость анимации не только шаблона, но и атрибутов при достаточно
экономном расходе памяти.
Конечно, существуют и другие приемы.
Внимательно смотрите на движение спрайтов в Ваших любимых играх и Вы
сможете узнать много интересного и, возможно, почерпнете что-то и для
себя
2.2 Анимация заднего плана. Окна.
Для обеспечения самой плавной и гладкой
аннмации требуется еще более тонкое управление движением графики на
экране. Самое же плавное перемещение можно получить скроллингом экрана
или части экрана на 1 пиксел. Здесь мы рассмотрим две процедуры,
обеспечивающие скроллинг по горизонтали и вертикали.
2.2.1. Горизонтальный скроллинг экрана.
Формат процедуры для выполнения горизонтального скроллинга экрана - следующий: FN 1 (1, d)
1 length параметр, указывающий на какую величину (в пик
селах) следует исполнить скроллинг.
d direction параметр, определяющий направление перемещения
d=l скроллинг слева направо d=0 - скроллинг справа налево.
Листинг 19. Загрузчик машинного кода про цедуры горизонтального скрол линга.
10 REM *** Загрузчик машинного кода
20 LET adr=51500: LET long=85: LET check^7863: LET sum=0 30 FOR k=0 TO long-1: READ a 40 POKE (adr+k),a: LET sum=sum+a 50 NEXT k
60 IF sumocheck THEN PRINT "??": STOP 100 REM *** Данные для машинного кода
110
|
DATA
|
243,
|
042,
|
011,
|
092
|
,017
|
120
|
DATA
|
004,
|
000,
|
025,
|
070
|
,030
|
130
|
DATA
|
008,
|
025.
|
126,
|
254
|
,000
|
140
|
DATA
|
032,
|
034,
|
014,
|
191
|
,197
|
150
|
DATA
|
033,
|
000,
|
064,
|
229
|
,006
|
160
|
DATA
|
032,
|
167,
|
203,
|
030
|
,035
|
170
|
DATA
|
016,
|
251,
|
225,
|
048
|
,004
|
180
|
DATA
|
062,
|
128,
|
182 ,
|
119
|
,017
|
190
|
DATA
|
032,
|
000,
|
025,
|
013
|
,032
|
200
|
DATA
|
233,
|
193,
|
016,
|
224
|
,251
|
210 DATA 201,014,191,197,033 220 DATA
031,064,229,006,032 230 DATA 167,203,022,043,016 240 DATA
251,225,048,004,062 250 DATA 001.182,119,017,032 260 DATA
000,025,013,032,233 270 DATA 193,016.224,251,201
Листинг 20 Процедура, управляющая горизонтальным скроллингом
Адрес Маш-код Метка Мнемоника
;Запрет прерываний HL,(#5C0B) ;Указание на
адрес, в котором располагаются па ;раметры функции польэо-;вателя FN
1() DE, #0004 .-Вычисление адреса пер HL,DE ;вого параметра.
В,(HL) ;Прием параметра 1
Е,#08 ;Переход ко второму
HL,DE ;параметру.
A,(HL) ;Приен параметра а.
С930 С933 С931 С935 С937 938
Адрес Маш.код Метка Мнемоника
С939 FEOO CP #00
С93В 2022 OR NZ,LEFT
C93D OEBF DIST LD C,#BF
C93F C5 C940 210040
PUSH ВС LD HL,#4000
VERT PUSH HL
LD B,#20
AND A
HORIZ RR (HL)
DJNZ HORIZ
JR NC,BYPASS
;Определяем направление ;скроллинга. ;Если влево, то ,переход.
;#BF=192 DEC - количество горизонтальных линий ;экрана.
;Сохранение на стеке ;Адрес начала экранной ;области.
.Сохранили на стеке. ;32 байта - длина одной линии.
;Сброс флага переноса. ;Вращение вправо пикселов ;в одной
линии знакоместа. ;Пиксел, вышедший за пре ,делы знакоместа отклады
,ваетси во флаг переноса. .Переход к следующему зна ;коместу справа.
:Если не вся линия сдвинула, возврат в начало ;цикла.
.Восстановление адреса .самого первого
знакоместа ,в текущей пинии для ре .шения вопроса о "прокрутке" (когда
рисунок уходящий вправо выплывает ;слева)
,Если последний уходящий .вправо за пределы экрана ;пиксел был выключен, то .все 0К, ничего делать
Адрес Маш.код Метка Мнемоника
ЗЕ80
В6
77
112000
19
0D
C94F
С951 С952 С953 C95G С957 С958
20Е9
С95А С1 С95В 10Е0
C95D FB С95Е С9
LD OR LD
A,#80 (HL) (HL),A DE,#0020 HL, DE С
BYPASS LD ADD DEC
3R NZ.VERT
POP ВС D3NZ DIST
EI RET
;не надо, обход на BYPASS .Включение старшего
бит;а. ;Включение левого пиксела ;в первом знакоместе. ;Переход к
очередной линии экрана.
;Уменьшили счетчик линий. .Если не все линии
смещены, то возврат. ;Проверка на исчерпание ,дистанции перемещения 1.
;Если не весь путь пройден, возврат на DIST. ;Включение прерываний и
;выход.
LEFT LD C,#BF
C95F 0EBF
С961 С5 С962 211F40
С965 Е5 С966 0620
С968 А7 С969 СВ16
VERT1
PUSH HL LD B,#20
AND A H0RIZ1 RL (HL)
;#BF=192 DEC - количество горизонтальных линий ;экрана.
;Сохранение на стеке .Адрес первой линии в
;последнем знакоместе Первой экранной строки. .•Сохранили на
стеке. ;32 байта - длина од-;ной линии.
;Сброс флага переноса .Вращение влево пикселов
:в одной линии знакоместа. Пиксел, вышедший за пре-;делы знакоместа
отклады-;вается во флаг переноса.
Адрес Маш.код Метка Мнемоника
С96В 2В
С971 С973 С974 С975 С978 С979 С97А
С96С 10FB
С96Е Е1
C96F 3004
ЗЕ01 В6 77 112000 19 0D 20Е9
С97С С1 C97D 10Е0
C97F FB С980 С9
DEC HL
DJNZ H0RIZ1
POP HL
□ R NC,PASS-1
A, #01 (HL) (HL),A DE,#0020
ADD HL.DE DEC С
JR NZ.VERT1
POP ВС DJNZ LEFT
EI RET
Переход к соседнему знакоместу слева. Если не вся линия сдвинута, возврат в начало цикла.
Восстановление адреса последнего знакоместа в
текущей линии для решения вопроса о "прокрутке" (когда рисунок уходящий
влево выплывает справа).
Если последний уходящий влево за пределы экрана
пиксел был выключен, то все 0К, ничего делать не надо, обход на PASS-1
Включение младшего бита. Включение правого пиксела в последнем
знакоместе. Переход к очередной линии экрана.
Уменьшили счетчик линий. Если не все линии
смещены, то возврат. Проверка на исчерпание дистанции перемещения 1.
Если не весь путь пройден, возврат. Разрешение прерываний. Выход.