01 апреля 2021 |
|
О туннелях и небоскребах Alone Coder Прямоугольный туннель появился ещё в волосатом году в сеговской игре Galaxy Force II. На Спектруме мы его впервые на─ блюдали в демо Yes (1997). Разумеется, для отрисовки такого тун─ неля не нужно рисовать прямоугольники. Он строится по строчкам. Обычно в одной стро─ чке добавляется проекция не более чем од─ ного прямоугольника. Но если и больше - не страшно. Главное - во всём кадре видно не более N разных строчек, где N - общее чис─ ло прямоугольников в туннеле (включая вне─ шний, который во весь экран). Эффект с небоскрёбами при виде сверху тоже рисуется ограниченным числом строчек (в данном случае 2*N,где N - число слоёв). Туда же зуминг шахматных сеток, бегущих строчек и т.п. Итак. 1. Nedotunnel В деме Yes туннель был чёрно-белым, но ничто не мешает его раскрасить. Например, в мультиколоре 8x2 (всего лишь стек пере─ ставлять между строчками). Но мне такой туннель понадобился в Nedodemo 2, а дема эта под ATM-Turbo 2+ (рекомендуется ZX Evo baseconf ),так что я строил этот туннель в аппаратном мультиколоре объёмом аж 32000 байт. Задача разбивается на следующие шаги: - нагенерировать координаты N прямоуго─ льников; - нагенерировать N строчек с последова─ тельным добавлением прямоугольников; - составить массив,где для каждой строки экрана указано,какую графику использовать; - вывести экран по этому массиву (в слу─ чае мультиколора - тривиально, а в случае жирного АТМного экрана надо подумать). Поскольку строчки содержат много одина─ ковых байтов подряд, можно генерировать не графику строчек, а код для их вывода. Но все 32000 байт мы выводить не будем, выво─ дить будем только атрибуты, как и для про─ граммного мультиколора. Также отметим, что в аппаратном мульти─ колоре ATM-Turbo есть два чередующихся слоя экрана. Можно оба слоя вывести в рамках одной процедуры: dup 20 [ld de/d/e,...] push de edup ld sp,ix dup 20 [ld de/d/e,...] push de edup jp (iy) Чтобы сгенерировать такую оптимизиро─ ванную процедуру (а всего их, напомню, N), удобно иметь сначала графику строки в ли─ нейном виде. Вызывалка может выглядеть так (можно совместить с вычислением массива строк,так что массив будет и не нужен): <логика> ld sp,scr+#2000 ld ix,scr ld iy,$+ /ld ly,$+ jp (hl) и так для каждой строки. Логика просто следит, пересекли ли мы верхнюю (или нижнюю) границу очередного прямоугольника,если да,то пересекли ли для следующего и т. д., с каждым разом меняя номер рисуемой графики строчки. Расчёт координат тоже ничего особенного не представляет - опишу его в двух словах, подробности можете посмотреть в исходниках Nedodemo 2. У каждого прямоугольника есть виртуаль─ ные X,Y,Z и виртуальные размеры (в данном случае у всех одинаковые). По идее размеры слоёв убывают как 1/N. Но при плавном зуме N будет дробным. Так что лучше иметь массив всех видимых размеров прямоугольников и шагать по этому массиву большими шагами. Прямоугольники не только приближаются, но и колеблются по X и Y (например, по си─ нусам). Сдвиги прямоугольников по X и Y в проекции экрана должны быть сообразны их масштабу. Вот и весь эффект. 2. Skyscrappers Эффект с небоскрёбами с высоты птичьего полёта я писал для The Board II (эта дема написана раньше предыдущей). Там тоже ап─ паратный мультиколор ATM-Turbo и тоже было два варианта: А) заранее готовим все строки и юзаем их Б) строку апдейтим по ходу отрисовки. Прикинул и решил сгенерировать все воз─ можные строки, и их оптимизировать в ld: push. Все возможные строки для случая 4 слоёв (в деме их столько,а не больше,пото─ му что иначе не получался красивый цвето─ переход): пусто 0 01 012 0123 123 23 3 итого 8 строк. Можно представить себе промежуточный формат строки как байт на точку,каждый бит - наличие определённого слоя небоскрёба. Чтобы сгенерировать эти битпланы, нужно запустить зумер для каждого из 4 битпланов и каждый байт либо не трогать, либо пропи─ сать нужный бит в каждый из битпланов. Из такого байта с битпланами можно вычислить видимый цвет по таблице, а заодно пересчи─ тать в два пикселя в байте и в два череду─ ющихся слоя. Удалось реализовать это без промежуточ─ ного буфера, сразу в два пикселя в байте. Слои накладывает сама палитра, а зумер од─ ного битплана состоит из цикла пропуска и цикла рисования залитой части. Цикл пропуска (b=ширина пропуска): ZOOMSKIP _=0 dup wid/2 _=_+42 djnz $+26 ;обходим запись и jp ;кончился пропуск ld h,c ld d,ly dup 4 ld a,(hl) or d ld (hl),a ;правый пиксель inc h edup org $-1 inc l ld b,hx ;ширина залитой части-1 jp ZOOMWRITE+_ ;идём на рисование ;+26 - это сюда inc l djnz $+7 ;кончился пропуск ld b,lx ;ширина залитой части jp ZOOMWRITE+_ edup Цикл рисования (b=ширина залитой части): ZOOMWRITE _=0 dup wid/2 _=_+34 djnz $+26 ;обходим запись и jp ld h,c ld d,hy dup 4 ld a,(hl) or d ld (hl),a ;левый пиксель inc h edup org $-1 inc l ld b,hx ;ширина пропуска-1 jp ZOOMSKIP+_ ;+26 - это сюда ld h,c dup 4 ld (hl),e ;левый+правый пиксель inc h edup org $-1 inc l djnz $+7 ld b,lx ;ширина пропуска jp ZOOMSKIP+_ edup В любом случае, надо будет пересчитать сгенерированные строки (кроме пустой) в ld:push. Вот таким кодом (для упрощения считаем, что d и e одновременно не меняются): pop af ;два пикселя от зумера ;(второй слой пропускаем) cp b jr z,$+10 exd ld (hl),#16 ;"ld d," exd inc e ld (de),a inc e ld b,a pop af ;два пикселя от зумера ;(второй слой пропускаем) cp c jr z,$+10 exd ld (hl),#1e ;"ld e," exd inc e ld (de),a inc e ld c,a ld a,#d5 ;"push de" ld (de),a inc e Вызывалка ld:push'ей (она сама вычисля─ ет, какие слои активны в данной строке - код похож на 4-канальный плейер на бипере :)) exx dec h jr nz,$+5 xor 8 ld h,l dec d jr nz,$+5 xor 4 ld d,e djnz $+5 xor 2 ld b,c exx djnz $+5 xor 1 ld b,c ld h,a ;%1111EDCB ld h,(hl) ld sp,первыйслой ld ix,второйслой ld iy/ly,следующаявызывалка jp (hl) ... ld:push *20 ld sp,ix ld:push *20 jp (iy) ;на следующую вызывалку В The Board II строки повторяются (всё равно атрибутные "пиксели" широкие, а так получатся квадратные), так что на каждой второй строке расчёта нет, а стоит опять: ld sp,первыйслой ld ix,второйслой ld iy/ly,следующаявызывалка jp (hl) В таком духе можно писать и вызывалки для зума, скролла или ещё чего-нибудь, но обычно я так не делаю. Главное,что работа─ ет! :)
Other articles:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Similar articles:
В этот день... 21 November