Фазы движения человечка
Рисунок 5.6. Фазы движения человечка
Прежде всего закодируем отдельные элементы двух изображений человечка, воспользовавшись, как и в предыдущей главе, определяемыми пользователем символами UDG. В результате кодирования получится блок данных, первому байту которого присвоим метку UDG:
UDG DEFB 0,0,3,4,102,68,35,62 ;A (144) DEFB 0,0,192,32,166,34,204,56 ;B (145) DEFB 31,15,7,7,3,7,6,6 ;C (146) DEFB 112,96,192,96,192,224,224,224 ;D (147) DEFB 6,6,6,4,8,0,0,0 ;E (148) DEFB 96,96,96,32,16,0,0,0 ;F (149) DEFB 3,4,6,4,195,236,127,55 ;G (150) DEFB 192,32,160,32,195,55,126,108 ;H (151) DEFB 7,7,7,14,28,12,6,14 ;I (152) DEFB 224,96,224,112,56,48,96,112 ;J (153) DEFB 8,16,108,254,190,158,78,60 ;Яблоко (154) DEFB 17,85,255,0,0,0,0,0 ;Трава (155)
Справа от каждой строки указаны коды, которые понадобятся нам для составления трех других блоков данных. Первый из них с меткой PEJZ мы используем для создания примитивного пейзажа, состоящего, как мы уже говорили, из зеленой травы и яблока (маленькую ветку проще получить программным путем).
PEJZ DEFB 22,13,13,16,4 DEFB 155,155,155,155,155,155 DEFB 22,8,15,16,2,17,0 DEFB 154
Можно заметить, что кроме кодов UDG в блок включены также и управляющие символы, устанавливающие позицию печати и изменяющие цвета спрайтов.
Второй и третий блоки - это как раз те два спрайта, которые должны попеременно появляться на вашем экране, создавая иллюзию движения:
SPR1 DEFB 6 DEFB 0,0,7,144,0,1,7,145 DEFB 1,0,7,146,1,1,7,147 DEFB 2,0,7,148,2,1,7,149 SPR2 DEFB 6 DEFB 0,0,0,32,0,1,0,32 DEFB 1,0,7,150,1,1,7,151 DEFB 2,0,7,152,2,1,7,153
Для вывода этих спрайтов на экран можно было бы, как и раньше, воспользоваться подпрограммой 8252, однако основная идея применения спрайтов заключается в том, чтобы их можно было легко перемещать по экрану. Но поскольку спрайт обычно состоит из нескольких знакомест, которые имеют строго фиксированное положение внутри него, то при использовании процедуры 8252 пришлось бы перекодировать координаты всех составляющих его фрагментов. Сами понимаете, что это не слишком удобно, особенно если спрайт состоит из десятка-другого знакомест. Это означает, что для вывода спрайтов на экран необходимо создать самостоятельную процедуру, которую мы назовем PUT.
Теперь следует сказать несколько слов о построении блоков данных SPR1 и SPR2, поскольку они тесно связаны с подпрограммой PUT и их формат, естественно, должен быть согласован с ее работой. Опишем их структуру. Первый байт соответствует количеству фрагментов, входящих в спрайт (в нашем примере как для первого, так и для второго спрайта - это число 6). Далее следуют параметры для каждого фрагмента, занимающие по 4 байта:
1-й байт - относительная вертикальная координата данного знакоместа в спрайте; 2-й байт - относительная горизонтальная координата данного знакоместа в спрайте; 3-й байт - байт суммарных атрибутов знакоместа; 4-й байт - код символа соответствующего фрагмента спрайта.
Поскольку подпрограмма PUT нам потребуется не только в данном примере, сохраните ее в виде отдельного библиотечного файла. Она имеет следующий вид:
PUT LD E,(HL) ;считываем количество фрагментов спрайта PUT1 INC HL LD A,22 RST 16 LD A,B ;регистр B содержит координату ROW ADD A,(HL) ;прибавляем к ней относительную ; координату внутри спрайта RST 16 INC HL LD A,C ;в C - горизонтальная координата COL ADD A,(HL) ;складываем ее с относительной ; координатой, взятой из блока данных RST 16 INC HL LD A,(HL) ;считываем байт атрибутов знакоместа LD (23695),A INC HL LD A,(HL) ;берем код выводимого символа RST 16 DEC E JR NZ,PUT1 ;переходим к выводу следующего ; фрагмента RET
Перед вызовом этой процедуры необходимо в регистровой паре HL указать начальный адрес блока данных, соответствующего выводимому спрайту, а в регистрах B и C задать координаты экрана по вертикали и горизонтали.
Наконец соберем все части программы в единое целое, добавив несколько уже знакомых процедур, и напишем небольшую часть, управляющую движением человечка:
ORG 60000 ENT $ CALL SETSCR LD HL,UDG LD (23675),HL CALL FON CYCLE LD HL,SPR1 ;вывод спрайта 1 LD BC,#A0F ;B = 10, C = 15 CALL PUT CALL PAUSE ;небольшая задержка LD HL,SPR2 ;вывод спрайта 2 LD BC,#A0F CALL PUT CALL PAUSE ;снова задержка ; Выход из цикла при нажатии клавиши Space
LD A,(23560) ;системная переменная LAST_K, в которой ; хранится код последней нажатой клавиши CP " " JR NZ,CYCLE ;повтор RET ; Задержка (PAUSE 12) PAUSE LD BC,12 JP 7997 ; Рисование пейзажа FON LD DE,PEJZ LD BC,19 CALL 8252 EXX PUSH HL LD A,6 LD (23695),A LD BC,#7078 ;B = 112, C = 120 CALL 8933 LD DE,#101 ;D = 1, E = 1 LD BC,10 CALL 9402 LD BC,#757D ;B = 117, C = 125 CALL 8933 LD E,#FF01 ;D = -1, E = 1 LD BC,#F0F ;B = 15, C = 15 CALL 9402 POP HL EXX RET
Эффект движения здесь создается с помощью простого цикла, начинающегося с метки CYCLE, в теле которого по очереди выводятся то первый спрайт, изображающий стоящего человечка, то второй, показывающий человечка в прыжке. Скорость смены фаз движения регулируется подпрограммой PAUSE.