Поверх старого спрайта печатаю новый со сдвигом - получается одновременно и движение и затирание следа.
Вид для печати
Нет, герой 24х24. Когда например идёт сдвиг влево то у меня есть готовые спрайты 32х24 в котором идёт сдвиг влево и анимация заодно.
А когда герой стоит на месте то печатается спрайт 24х24. При сдвиге вверх тоже печатается 24х24 т.к. в спрайте снизу и сверху есть запас чёрных-нулевых линий.
metamorpho, забавный глюк
если уперется в стену вверх или вниз и зачать соостветсвенно вверх или вниз то враги дрожат на месте
- - - Добавлено - - -
вот тебе архив с комментариями
3 файла
interrupt.a80 правильные прерывания для работы с программой отрисовки спрайтов
Скрытый текст
Код:;процедура обработки прерывания с восстановлением поврежденных данных
;при доступе к стеку
;регистровая пара для доступа к стеку BC
im_routine
di
;сохраняем HL и забираем адрес возврата из прерывания
ex (sp),hl
;сохраняем его
ld (im_ret),hl
;забираем HL
pop hl
;сохраняем его чтобы не потерять при манипуляциях с SP
ld (im_hl),hl
;сохраняем флаги
push af
;вычисляем корректный адрес стека программы
ld hl,2
add hl,sp
;сохраняем стек программы
ld (im_sp),hl
pop af
;восстановлением поврежденые данные регистром BC
push bc
;задаем стек прерывания
ld sp,im_stek
;сохраняем все регистры кроме HL
push af,bc,de
;-----------------------------
;ISR
;здесь прерывание
;-----------------------------
;восстанавливаем регистры
pop de,bc,af
;восстанавливаем HL
ld hl,#2121
im_hl equ $-2
;восстанавливаем стек
ld sp,#3131
im_sp equ $-2
ei
;возвращаемся из обработки прерывания
jp #c3c3
im_ret equ $-2
[свернуть]
sprite.a80 две подпрограммы быстрого вывода через стек
но тебе надо будет поменять формат спрайтов
сначала вся линия для одного плана, потом для другого, потом для третьего.
это значительно ускорит вывод.
вектор использует систему битпланов при формировании цвета точки
вот здесь на примере идентичной системы Commodore Amiga более менее рассказано
Скрытый текст
Код:;вывод спрайта в системе битпланов Вектор 06
;ширина спрайта -24
;на входе
;bc адрес спрайта
;de aдрес на экране
;E-Y D-X
;A высота спрайта/2
drop24
ld hl,0
add hl,sp
ld (sprite_sp0),hl
ld h,b
ld l,c
ld c,(hl)
inc hl
ld b,(hl)
inc hl
ld sp,hl
;задаем Y в L
ld l,e
;задаем высоту спрайта в E
ld e,a
;задаем X в A
ld a,d
;переход между битпланами
ld d,#20
drop240
ld h,a
;рисуем на первом плане
ld (hl),c
inc h
ld (hl),b
inc h
pop bc
ld (hl),c
;переход на второй битплан
add a,d
ld h,a
;рисуем на втором плане
ld (hl),b
inc h
pop bc
ld (hl),c
inc h
ld (hl),b
pop bc
;переход на третий битплан
add a,d
ld h,a
;рисуем на третьем плане
ld (hl),c
inc h
ld (hl),b
inc h
pop bc
ld (hl),c
;возвращаемся на первый план
sub #40
;переходим на следующую строку
inc l
;повторяем цикл рисования
;
ld (hl),b
inc h
pop bc
ld (hl),c
inc h
ld (hl),b
pop bc
;переход на второй битплан
add a,d
ld h,a
;рисуем на втором плане
ld (hl),c
inc h
ld (hl),b
inc h
pop bc
ld (hl),c
;переход на третий битплан
add a,d
ld h,a
;рисуем на третьем плане
ld (hl),b
inc h
pop bc
ld (hl),c
inc h
ld (hl),b
;выбираем следующую пару байтов для цикла рисования
pop bc
;возвращаемся на первый план
sub #40
;переходим на следующую строку
inc l
;проверяем на завершение цикла
dec e
jp nz,drop240
sprite_sp
ld sp,#3131
sprite_sp0 equ $-2
ret
;ширина спрайта -32
;на входе
;bc адрес спрайта
;de aдрес на экране
;E-Y D-X
;A высота спрайта/2
drop32
ld hl,0
add hl,sp
ld (sprite_sp0),hl
ld h,b
ld l,c
ld c,(hl)
inc hl
ld b,(hl)
inc hl
ld sp,hl
;задаем Y в L
ld l,e
;задаем высоту спрайта в E
ld e,a
;задаем X в A
ld a,d
;переход между битпланами
ld d,#20
drop320
ld h,a
;рисуем на первом плане
ld (hl),c
inc h
ld (hl),b
inc h
pop bc
ld (hl),c
inc h
ld (hl),b
pop bc
;переход на второй битплан
add a,d
ld h,a
;рисуем на втором плане
ld (hl),c
inc h
ld (hl),b
inc h
pop bc
ld (hl),c
inc h
ld (hl),b
pop bc
;переход на третий битплан
add a,d
ld h,a
;рисуем на третьем плане
ld (hl),c
inc h
ld (hl),b
inc h
pop bc
ld (hl),c
inc h
ld (hl),b
pop bc
;возвращаемся на первый план
sub #40
;переходим на следующую строку
inc l
;повторяем цикл рисования
;
ld (hl),c
inc h
ld (hl),b
inc h
pop bc
ld (hl),c
inc h
ld (hl),b
pop bc
;переход на второй битплан
add a,d
ld h,a
;рисуем на втором плане
ld (hl),c
inc h
ld (hl),b
inc h
pop bc
ld (hl),c
inc h
ld (hl),b
pop bc
;переход на третий битплан
add a,d
ld h,a
;рисуем на третьем плане
ld (hl),c
inc h
ld (hl),b
inc h
pop bc
ld (hl),c
inc h
ld (hl),b
;выбираем следующую пару байтов для цикла рисования
pop bc
;возвращаемся на первый план
sub #40
;переходим на следующую строку
inc l
;проверяем на завершение цикла
dec e
jp nz,drop320
jp sprite_sp
[свернуть]
И небольшая таблица в EXCEL
с памяткой по переводу команд из z80 в i8080 и назад.
чтобы понять как это работает
Вложение 73199
Я тут собрал "болванку" по образцу этой программы.
Спрайты 24х24 на 3 плоскости, на экране 10х10 ячеек игрового поля, ширма 16 строк.
Вывод спрайтов с использованием стека на чтение.
Прерывания, те, которые тут обсуждаются, для данного метода вывода спрайтов.
В итоге получается, что при перемещениях персонажа по горизонтали, и отрисовка ещё 5-ти подвижных объектов спокойно укладывается между прерываниями, т.е. требуется менее 20мс.
А вот при перемещении по вертикали, из-за подготовки поля под ширмой, до прерывания можно обработать только 4-е подвижных объекта, и совсем без запаса.
KTSerg, ты как поле готовишь?
Мой метод спрайтов посмотрел?
jerri, примерно да. Только у меня алгоритм значительно длиннее, и не построчно, а по две строки.
Т.е. две строки в одной колонке, потом две во второй, в третьей. Потом переход на след. план. По две строки справа налево. Переход на след. план. Снова по две строки в право. И так дважды.
За счет более длинного и развёрнутого алгоритма, по тактам, мой не значительно быстрее. Видимо за счет меньшего количества проверок на конц цикла. Т.к. у тебя на 4 строки дважды проверка на повтор, а у меня один раз.
Поскольку у тебя, переход между планами и проверка циклов компактнее, чем у меня.
Спасибо за идею.
И подозреваю, что у моего метода "по две строки" выше вероятность появлению мельтешения (мерцания).
- - - Добавлено - - -
jerri, в алгоритме рисования спрайта, есть для меня один не понятный момент.
При переходе на след строку (в средине алгоритма):
Уменьшение аккумулятора на 40 - это я понимаю, переход не след строку "inc l" - тоже.Код:ld (hl),c
;возвращаемся на первый план
sub #40
;переходим на следующую строку
inc l
;повторяем цикл рисования
ld (hl),b
А как происходит перевод регистра H - на начало?
Не пропущено "mov h,a" ?