2.1.5. Управление спрайтами с клавиатуры с использованием прерываний 2~го рода.
Выше мы уже говорили, что существуют два
основных метода управления движением спрайтов. Первый - это управление
от клавиатуры или джойстика, т.е. управление от пользователя. Второй -
автоматическое управление из программы. Обычно герои игры
(пользовательские персонажи) управляются от клавиатуры, а монстры
(непользовательские персонажи) управляются автоматически по заранее
заданному алгоритму. При этом алгоритм управления ими может быть
достаточно сложным и использовать методы искусственного интеллекта
Листинг 11
Загрузчик процедуры, управляющей спрайтом от клавиатуры.
10 REM *** Загрузчик машинного кода
20 LET adr=53100: LET long=250: LET
check=81326: 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
|
042
|
,011,
|
092,
|
017
|
,004
|
120
|
DATA
|
000
|
,025,
|
126,
|
230
|
,001
|
130
|
DATA
|
050
|
,095,
|
208,
|
032
|
,011
|
140
|
DATA
|
042
|
,096,
|
208,
|
237
|
,075
|
150
|
DATA
|
106
|
,207,
|
205,
|
196
|
,209
|
160
|
DATA
|
201
|
,03C,
|
008,
|
025
|
,078
|
170
|
DATA
|
025
|
,070,
|
025,
|
126
|
,230
|
180
|
DATA
|
001
|
,050,
|
093,
|
208
|
,025
|
190
|
DATA
|
126
|
,033,
|
009,
|
213
|
,017
|
200
|
DATA
|
063
|
.000.
|
025.
|
061
|
.032
|
210 DATA 252,034,096,208,205 220 DATA
093,210,237,067,106 230 DATA 207,243,175,071,050 240 DATA
094,208,062,207,033 250 DATA 002,206,119,035,016 260 DATA
252,062,206,237,071 270 DATA 237,094,251,201,000
280
|
DATA
|
000,
|
000,
|
000
|
,000
|
,000
|
290
|
DATA
|
000,
|
000,
|
000
|
,000
|
,000
|
300
|
DATA
|
000,
|
000,
|
000
|
,000
|
,255
|
310
|
DATA
|
243,
|
245,
|
197
|
,213
|
,229
|
320
|
DATA
|
008,
|
245,
|
008
|
,221
|
,229
|
330
|
DATA
|
058,
|
095,
|
208
|
,254
|
,000
|
340
|
DATA
|
040,
|
024,
|
205
|
,007
|
,208
|
350
|
DATA
|
058,
|
094,
|
208
|
,254
|
,000
|
360
|
DATA
|
040,
|
014,
|
058
|
,093
|
,208
|
370
|
DATA
|
254,
|
000,
|
040
|
,007
|
,205
|
380
|
DATA
|
123,
|
207,
|
175
|
,050
|
,095
|
390
|
DATA
|
208,
|
195,
|
252
|
,207
|
,221
|
400
|
DATA
|
225,
|
008,
|
241
|
,008
|
,225
|
410
|
DATA
|
209,
|
193,
|
241
|
,251
|
,201
|
420
|
DATA
|
237,
|
075,
|
106
|
,207
|
,042
|
430
|
DATA
|
096,
|
208,
|
062
|
,239
|
,219
|
440
|
DATA
|
254,
|
203,
|
103
|
,040
|
,044
|
450
|
DATA
|
203,
|
095,
|
040
|
,031
|
,203
|
460
|
DATA
|
087,
|
040,
|
018
|
,062
|
,247
|
470
|
DATA
|
219,
|
254,
|
203
|
,103
|
,040
|
480
|
DATA
|
001,
|
201,
|
013
|
,013
|
,013
|
490
|
DATA
|
121,
|
230,
|
252
|
,200
|
,024
|
500
|
DATA
|
025,
|
012,
|
012
|
,012
|
,062
|
510
|
DATA
|
231,
|
145,
|
216
|
,024
|
,016
|
520 DATA 005,005,005,120,230 530 DATA 252,200,024,007,004 540 DATA 004.004.062.153.144
550 DATA 216,197,237,075,106 560 DATA
207,205,196,209,193 570 DATA 205,093,210,050,094 580 DATA
208,237,067,106,207 590 DATA 201,000,000,000,064 600 DATA
215,000,000,000,000
Формат управляющей процедуры.
DBF FNh (s,x,y,c,n)
s - переключатель (SWITCH). Если 8=1, процедура должна быть включена. Если 8=0
- процедура выключается. Необходимость в специальном способе отключения
процедуры связана с тем, что процедура размещается и работает в памяти
резидентно, от прерываний. Поэтому ее нетрудно включить, но выключить
ее из БЕЙСИКа не удастся, если не предусмотреть для этого специальные
меры. Интересно, что после того, как процедура отработает и Вы в
БЕЙСИКе войдете в режим редактирования программы, спрайт может
продолжать бегать по экрану, подчиняясь нажатиям управляющих клавиш.
Для отключения процедуры и предусмотрен параметр 8=0.
Вызов процедуры для отключения можно делать с одним этим параметром, не
указывая все прочие. В этом случае процедуру выключения спрайта можно
определить, как Fn z(s).
х,у - координаты исходной позиции спрайта. За начало отсчета принимается левый верхний угол экрана.
0<=х<=231 0<=у<=154
с - флаг детекции коллизии. 1 - включен. 0 - выключен.
п - номер спрайта (1...10).
Листинг 12
Процедура, управляющая спрайтом от клавиатуры
Адрес Маш-код Метка Мнемоника
YXLAST DEFW #0000
LD HL,(#5С0В)
LD DE,#0004
ADD HL,DE
LD A,(HL)
AND #01
LD (SWTCH),A
3R NZ,CONT
CF7B CF7E CF82
CF85 CF86 CF88 CF89 CF8A CF8B CF8C CF8D CF8E
2A60D0 S-LAST LD HL,(ADSPR) ED4B6ACF LD BC,(#CF6A)
CDC4D1 CALL SPRDRV-S
C9
1E08
19
4E
19
46
19
7E
E601
RET
LD
ADD
LD
ADD
LD
ADD
LD
AND
E, #08 HL,DE C,(HL) HL, DE В,(HL) HL,DE A,(HL) #01
Последние координаты у и x. ;По ним можно
определить, например, где произошла коллизия с препятствием.
Установление адресов параметров функции пользователя Fn (). Сдвиг от
DEFADD на 4 байта, переход к первому параметру. Прием параметра 8.
Маскирование старших битов .
Запомнили в переменной. Если 8=1, то выключаться не надо и работу продолжаем .
Адрес шаблона спрайта-Последние координаты у,х
Стирание спрайта вызовом драйвера SPRDRV-S. Выключение процедуры. Сдвиг
еще на 8 байтов ко второму параметру. Координата х. Переход к 3-му
пар-ру. Координата у. Переход к пар-ру с. Приняли параметр.
Маскирование старших битов.
Адрес Маш.код Метка Мненоиика__Комментарий.
CF90 325DD0 LD (#D05D) ,А ;Запомнили состояние фла-
;га детекции коллизии в программной переменной.
CF93
|
19
|
ADD
|
HL,DE
|
|
Переход к пар-ру п.
|
CF94
|
7Е
|
LD
|
A,(HL)
|
|
Приняли номер спрайта.
|
CF95
|
2109D5
|
LD
|
HL,#D509
|
|
Определение начала
|
CF98
|
113F00
|
LD
|
DE,#003F
|
|
шаблона спрайта в таб
|
CF9B
|
19 LOOP
|
ADD
|
HL,DE
|
|
лице по его номеру (см.
|
CF9C
|
3D
|
DEC
|
A
|
|
комментарий на с.26).
|
CF9D
|
20FC
|
JR
|
NZ,LOOP
|
|
|
CF9F
|
2260D0
|
LD
|
(ADSPR),HL
|
Запомнили начало шаблона
|
CFA2
|
CD5DD2
|
CALL
|
SPRDRV-P
|
|
Печать спрайта (см. с. 44).
|
CFA5
|
ED436ACF
|
LD
|
(YXLAST)
|
ВС
|
Текущие координаты у,х.
|
CFA9
|
F3
|
DI
|
|
|
Отключение прерываний, на время организации процедуры обработки IM2.
|
CFAA
|
AF
|
XOR
|
A
|
|
Обнуление аккумулятора.
|
CFAB
|
47
|
LD
|
B,A
|
|
Нуль в счетчике "В".
|
CFAC
|
325ED0
|
LD
|
(COLLIZ)
|
A
|
Инициализация переменной
|
CFAF
|
3ECF
|
LD
|
A,#CF
|
|
Формирование таблицы
|
CFB1
|
2102СЕ
|
LD
|
HL,#CE02
|
|
для IM 2. Начиная с ад
|
CFB4
|
77 LOOP
|
LD
|
(HL),A
|
|
реса #СЕ02 256 байтов
|
CFB5
|
23
|
INC
|
HL
|
|
памяти заполняются кодом
|
CFB6
|
10FC
|
DJNZ
|
LOOP
|
|
#CF. Теперь если мы выс
|
CFB8
|
3ECE
|
LD
|
A,#CE
|
|
тавим в регистре I код
|
CFBA
|
ED47
|
LD
|
I, A
|
|
#СЕ, то независимо от того, что будет на шине
|
|
|
|
|
;данных в момент прихода
|
|
|
|
|
|
прерывания, в качестве
|
;процедуры для его обработки будет назначена процедура, начинающаяся ;с адреса #CECF.
Адрес Маш.код Метка Мнемоника
;Включение прерываний ;второго рода. ;Разрешение прерываний. ;Возврат.
IM 2
EI
RET
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
CFBE CFBF CFCO CFC1 CFC2 CFC3 CFC4 CFC5 CFC6 CFC7 CFC8 CFC9 CFCA CFCB CFCC CFCD CFCE
FB С9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
RST #38
DI
PUSH AF PUSH ВС PUSH DE PUSH HL EX AF,AF*
;Начало процедуры обработки прерываний 2-го ;рода. RST #38 - это ;сканирование клавиатурь ;в поисках нажатой клав* ;ши.
;На время обработки IM ; прерывания надо отключать, иначе возможно ;зависание компьютера.
Сохранение всех основных регистров на машинном стеке.
Адрес Наш.код Метка Мнемоника
Комментарий.
CFD6
|
F5
|
|
PUSH
|
AF
|
|
CFD7
|
08
|
|
EX
|
AF,AF'
|
|
CFD8
|
DDE 5
|
|
PUSH
|
IX
|
|
CFDA
|
3A5FD0
|
|
LD
|
A, (SWTCH)
|
Переменная SWTCH несет в себе параметр в, определяющий режим Вкл/Выкл
|
CFDD
|
FEOO
|
|
CP
|
#00
|
Если выставлено "Выкл",
|
CFDF
|
2818
|
|
OR
|
Z,EXIT
|
то ничего делать не надо и проследуем на выход.
|
CFE1
|
CD07D0
|
|
CALL
|
KEYB
|
Вызов процедуры, обрабатывающей прерывания 2-го рода
|
CFE4
|
3A5EDO
|
|
LD
|
A,(COLLIZ)
|
Была коллизия при по-
|
CFE7
|
FEOO
|
|
CP
|
#00 ;следней печати спрайта?
|
CFE9
|
280E
|
|
OR
|
Z.EXIT
|
Если нет, пройти иа выход.
|
CFEB
|
3A5DDO
|
|
LD
|
A.(FLAG)
|
Если коллизия была, проверяем флаг детекции
|
CFEE
|
FEOO
|
|
CP
|
#oo
|
коллизии.
|
CFFO
|
2807
|
|
OR
|
Z.EXIT
|
Если он отключен, переход на выход.
|
CFF2
|
CD7BCF
|
|
CALL
|
S-LAST
|
Если ои включен, стира-еи спрайт последний раз.
|
CFF5
|
AF
|
|
XOR
|
A ;Обнуление аккумулятора.
|
CFF6
|
325FD0
|
|
LD (SWTCH),A
|
Засылка иуля в эту пере
|
|
|
|
|
|
менную обеспечит прекра
|
|
|
|
|
|
щение обработки прерыва
|
|
|
|
|
|
ний на следующем проходе
|
CFF9
|
C3FCCF
|
EXIT
|
OP
|
END ;Шаг вперед.
|
CFFC
|
DDE1
|
END
|
POP
|
IX
|
|
CFFE
|
08
|
|
EX
|
AF.AF'
|
|
CFFF
|
F1
|
|
POP
|
AF
|
Финишные операции.
|
D000
|
08
|
|
EX
|
AF.AF1
|
Балансировка стека.
|
DO 01
|
El
|
|
POP
|
HL
|
Разрешение преры
|
D002
|
D1
|
|
POP
|
DE
|
ваний .
|
Адрес Маш.код Метка Мнемоника
ED4B6ACF
2A60D0
3EEF
D014 D016 D018 D01A D01C D01E
D010 DBFE D012 CB67
282C CB5F 281F CB57 2812 3EF7
D020 DBFE DO22 CB67
D024 2801
ВС, (YXLAST) HL,(ADSPR)
A, #EF
IN A,(#FE) BIT 4,A
Z, DOWN 3, A Z,UP 2,A
Z,RIGHT A,#F7
IN A, (#FE) BIT 4,A
JR Z,#D027
Координаты y,x Адрес шаблона спрайта. Старший
байт адреса порта, равный #EF, указывает на правый полу-ряд верхнего
(цифрового) ряда клавиатуры. Порт клавиатуры. Бит 4 соответствует
клавише "6" (вниз). Если эта клавиша нажата, бит - выключен.
Подробности см. в книге "Программирование в "машинном коде", с.92-94.
Движение "вниз". Проверка клавиши "7" Движение
"вверх"-Проверка клавиши "8" Движение "вправо". Старший байт адреса
порта, равный #F7, указывает на левый верхний полуряд клавиатуры.
Порт клавиатуры. Проверка клавиши "5" ("влево")-Движение влево.
Адрес Маш.код Метка Мнемоника
:Выход из процедуры.
Уменьшение координаты х на три единицы.
Проверка на выход за пределы экрана Выход, если так. Иначе продолжить работу Увеличение координаты х на три единицы.
Проверка на выход за пределы экрана. Возврат,
если так. Иначе продолжить работу Уменьшение координаты у на три
единицы. (Напомним, что у нас за начало отсчета принят левый верхний
угол, поэтому при движении вверх координата у не увеличивается, как
обычно, а уменьшается.) Проверка на выход за пределы экрана. Возврат,
если так. Иначе продолжить работу Увеличение координаты у иа три
единицы.
Проверка на выход за пределы экрана.
С С С
А,С #FC
Z
NEXT
С
с с
A,#E7
С
С
NEXT В В В
OD OD OD 79
E6FC
C8 1819 ОС ОС ОС 3EE7 91 D8 1810 05 05 05
DEC
DEC
DEC
LD
AND
RET
JR
INC
INC
INC
LD
SUB
RET
JR
DEC
DEC
DEC
D027 D028 D029 D02A D02B
D02D D02E DO 30 D031 D032 DO 33 D035 D036 D037 DO 39 DO ЗА D03B
D03C DO 3D D03F D040 D042 D043 D044 DO 4 5 D047
78
E6FC
C8
1807
04
04
04
3E99 90
LD
AND
RET
JR
INC
INC
INC
LD
SUB
А,В #FC Z
NEXT В В В
A,#99 В
Адрес Маш.код Метка Мнемоника
D048 D049
DO4A ED4B6ACF
D04E CDC4D1
D051 С1
D052 CD5DD2
D055 325EDO
ED436ACF С9 00 00
00 40
00 00 00 00
D05F D060
D062 D063 D064 D065
RET С PUSH ВС
LD ВС,(YXLAST)
CALL SPRDRV-S
POP ВС
CALL SPRDRV-P
LD (COLLIZ),A
LD (YXLAST),ВС RET
DEFB 00 DEFB 00
DEFB 00 DEFW 0000
NOP NOP NOP NOP
Возврат, если так. Запомнили новые координаты.
Прежде чем печатать спрайт в новом месте, нужно стереть его в старом, для чего восста иовили предыдущие к, у. Стирание спрайта (см. с. 40)
Восстановление новых координат. Печать спрайта (см. с. 44)
После выхода из процедуры печати спрайта аккумулятор несет информацию о том, произошла коллизия (1) или нет (о).
Запомнили новые координаты в качестве текущих.
Флаг детекции коллизии Если коллизия при печати спрайта была, эта
переменная включается. Параметр в. Адрес начала шаблона спрайта.