(c) Steelzer/Triumph
-------------------------
FLAME
Вы конечно же видели эффект FLAME'а
(пламени) в демках, интрах и т.д. и если
для вас секрет, как он сделан - читайте
далее.
Для начала определим какой огонь мы
хотим получить. Мода на атрибуты давно
канула, и сейчас более актуальны chunky
(dithering). Поэтому речь пойдет о
'чанковом' FLAME. Огонь должен быть не
слишком высоким, но и не слишком малень-
ким. Пусть будет на треть экрана. Гореть
он может вертикально вверх, а может и в
сторону, что создает эффект ветра, но о
том как это сделать немного попозже.
Для начала инициализируем таблицу -
некий буфер, с которым мы будем рабо-
тать, а потом печатать на экран. Усло-
вимся, что использоватся будут чанки
4x4, и под 1 чанк в буфере будет выде-
ляться 1 байт - так с ними проще рабо-
тать. Итого нам потребуется таблица
64x16 (1024 байт).
Ну а теперь собственно о том как
делается огонь. Внизу пламени точки
имеют максимальную яркость и постепенно
переходя к самому верху тускнеют.
Вот элементы нашего буфера:
0, 2, 3, ... 61, 62, 63
64, 65, 66, ... 125, 126, 127
Следует понять, что мы имеем массив
64x16, и что номер нижнего элемента
(смещение в памяти) отличается от номера
верхнего на 64.
Вот сам алгоритм:
1) взять байт из X;
2) сложить с байтом из X+64;
3) проверить, равны ли они;
4) если да, то обнулить X;
5) сложить X с X+64 и разделить сумму на
2;
6) положить частное в X;
7) и т.д. для всех элементов буфера;
8) напечать буфер на экран;
9) после обработки и печати, следует
обновить 64 байта из конца буфера
случайными цифрами от 0 до 15 (т.к.
всего чанков 16) чтобы пламя не гас-
ло.
Чтобы пламя шло вверх и в сторону,
нужно в п.2 алгоритма поменять число 64
на 63 (вправо), или на 65 (влево).
Вот примерно что должно быть на
экране после печати буфера:
Сильно не заглядывайтесь - на эффект
нужно смотреть в действии, а не прикалы-
ваться по screenshot'ам.
Если вам кажется, что пламени чего -
то не хватает, то можно попробовать
изменить алгоритм.
Вместо того, чтобы складывать эле-
мент с нижним и делить на 2, попробуем
сложить элемент не только с нижним, но и
с нижним - левым и с нижним правым
элементами и разделить сумму уже на 4.
Тогда на экране появится примерно
такое:
Лично мне больше нравится второй
FLAME. Вот 3 minutes coded програмка,
которая как раз и делает второй вариант.
Там правда я использую подгружаемый
блок - "чанковый фонт", и печатаю чанки
по 2 за раз. Не буду спорить, печаталка
далеко не идеальная. Но это сделано лишь
для того, чтобы оставить "простор для
оптимизации" начинающим кодерам. Надеюсь
сами сгенерите "чанковый фонт", и
подгрузите под адрес #7800. Лично я его
генерил из 32 байт.
;(c)Steelzer/CRZ
; 3 minut coded flame
; rem can be modifed :)
ORG 25000
LD HL,#C000 ;инициализация
LD DE,#C001 ;буфера
LD (HL),L
LD BC,1024
LDIR
FLAME LD IX,#C000+63 ;смещение вверх и вправо
LD DE,#C000
LD BC,1024 ;столько элементов придется
;обработать
BEGIN LD A,(DE)
CP (IX+0)
JR NZ,LOOP1
XOR A
LOOP1 CP (IX-1)
JR NZ,LOOP2
XOR A
LOOP2 ADD A,(IX+0)
ADD A,(IX+1)
ADD A,(IX+2)
SRA A
SRA A
LD (DE),A
INC IX
INC DE
DEC BC
LD A,B
OR C
JR NZ,BEGIN
CALL PRINT
LD A,R ;заполнялка RANDOM'ом из почти ПЗУ ;)
AND %00111111
LD H,A
LD A,R
LD L,A
LD DE,#C000+1024
LD B,64
RND LD A,R
OR (HL)
OR 8
AND 15
LD (DE),A
INC HL
INC DE
DJNZ RND
JR FLAME
PRINT LD HL,#C000
LD DE,#5000
LD B,16
LI1 PUSH DE
LD A,(HL) ;весь этот блок
INC HL ;нужно повторить 32 раза
ADD A,A ;
ADD A,A ;
ADD A,A ;
ADD A,A ;
OR (HL) ;
PUSH HL ;
PUSH DE ;
LD L,A ;
LD H,30 ;
ADD HL,HL ;
ADD HL,HL ;
LD A,(HL) ;
LD (DE),A ;
INC HL ;
INC D ;
LD A,(HL) ;
LD (DE),A ;
INC HL ;
INC D ;
LD A,(HL) ;
LD (DE),A ;
INC HL ;
INC D ;
LD A,(HL) ;
LD (DE),A ;
POP DE ;
POP HL ;
INC DE ;
INC HL ;
POP DE
CALL NL1
DEC B
JP NZ,LI1
LD BC,#7FFE
IN A,(C)
BIT 0,A
JP Z,EXIT ;адрес выхода установите сами
RET
NL1 LD A,4
ADD A,D
LD D,A
NEXTL2 LD A,D
NEXTL3 AND 7
JR NZ,V1
LD A,E
ADD A,32
LD E,A
JR C,V1
LD A,D
SUB 8
LD D,A
V1 RET
NX INC D
JR NEXTL2
----------------------------------------