что с музыкой решили, будет GS из Doom?
что с музыкой решили, будет GS из Doom?
но для прикола неплохо бы при загрузке иметь меню выбора с музой, в т.ч. и из дума
---------- Post added at 22:07 ---------- Previous post was at 22:04 ----------
А вааще загрузу продумывали? Интересно было бы сначала грузить картинки с текстом, типа предыстория, а потом уже игру.
есть еще вариант отрисовки
1 как сделано у тебя
есть теневой экран 6912 байт
сначала ты делаешь расчеты, потом рисуешь, потом копируешь на экран - это долго
2 как можно сделать
сделать таблицу 3072 байта
сделать таблицу 768 байт под атрибуты
где 2 байта обработчик знакоместа
вторые 2 байта - адрес символа
также у тебя на экране имеется довольно много пустых мест
и рисовать в них - довольно расточительно по тактам
как заполнять эту таблицу?Код:итак обработчик обработка пустого места empty_char pop af //снимаем ненужный адрес exx ldi //красим экран - естественно в этом месте атрибуты должны быть #00 exx ret //переходим на следующий элемент draw_char //обычная отрисовка изображения pop hl //снимаем адрес чара ld (draw_c0),sp ld sp,hl ld l,e ld a,d and #f8 ld h,a dup 3 pop bc ld (hl),c inc h ld (hl),b inc h edup pop bc ld (hl),c inc h ld (hl),b ex de,hl exx ldi exx ld sp,$ draw_c0 equ $-2 inc e ret nz ld a,d add a,8 ld d,a ret draw_charfv //отрисовка перевернутого по вертикали изображения pop hl //снимаем адрес чара ld (draw_c1),sp ld sp,hl ld l,e ld a,d or #07 ld h,a dup 3 pop bc ld (hl),c dec h ld (hl),b dec h edup pop bc ld (hl),c dec h ld (hl),b ex de,hl exx ldi exx ld sp,$ draw_c1 equ $-2 inc e ret nz ld a,d add a,8 ld d,a ret
для начала распушаем
нулевой адрес и обработчик нулевых чаров
в область атрибутов заливаем #00
далее при прорисовке добавляем в область атрибутов цвет тайла
а в область обработчика адрес рисовалки и адрес тайла
т.е получается чтото вроде
dw empty_char,0,empty_char,0,empty_char,0,empty_char, 0
dw draw_char,#8000,draw_char,#8008,draw_char,#8010,dr aw_char,#8018
и в файле атрибутов
db 0,0,0,0,1,1,1,1
как то так
основная тема понятна?
дальше рассказывать как делать прорисовку с маской?
С уважением,
Jerri / Red Triangle.
Идею понял. Но есть сомнения.
Расчеты и отрисовка идут сразу для каждого тайла.
Сейчас у меня такой алгоритм:
1. Цикл по клеткам лабиринта, находящихся рядом с клеткой игрока. Смещения до нужных клеток заданы в таблице. Начинаем с ближних клеток и заканчиваем дальними (т.е. получается 7 уровней в глубину, на каждом уровне разное количество клеток).
2. Определяем элемент в текущей клетке.
3. По таблице, в зависимости от элемента клетки, определяем адрес спрайта, процедуру его вывода (1/4, 2/4, 3/4 или 4/4) и координаты спрайта на экране (на самом деле, в таблице хранится только горизонтальная координата, т.к. вертикальная всегда равна нулю).
3а. При этом в 1/4 спрайт будет выводиться как есть, в 2/4 - зеркально отраженным, в 3/4 - перевернутым, в 4/4 - перевернутым и зеркально отраженным. Спрайты, которые не симметричны, будут выводиться процедурой 1/4. Процедуры обозначают только способ вывода, а координаты вывода могут быть любыми, т.е. например 2/4 означает не то, что спрайт выводится только в 2/4 экрана, а то, что в любую координату экрана зеркально отраженным.
3б. В спрайтах хранятся для каждого знакоместа горизонтальная и вертикальная координаты, параметр занятости знакоместа ("краевой параметр") и 8 байтов изображения. Краевой параметр может иметь значения:
- знакоместо полностью перекрывает всё, что за ним;
- знакоместо на левом краю спрайта, поэтому знакоместо другого спрайта, если попадет под это знакоместо, должно будет выводиться с правой маской;
- знакоместо на правом краю спрайта, поэтому знакоместо другого спрайта, если попадет под это знакоместо, должно будет выводиться с левой маской.
4. Выводим спрайт соответствующей процедурой 1/4, 2/4, 3/4 или 4/4 на виртуальный экран.
4а. В каждой процедуре есть 3 блока вывода:
- вывод знакоместа непосредственно без маски;
- вывод знакоместа с левой маской;
- вывод знакоместа с правой маской.
4б. При выводе каждого знакоместа спрайта сначала проверяется хранящийся в байте атрибутов на виртуальном экране занесенный ранее другим спрайтом краевой параметр, в зависимости от этого процедура переходит на нужный блок вывода:
- если краевой параметр равен "знакоместо перекрывает всё, что за ним", то вывод данного знакоместа вообще не осуществляется, сразу переходим на следующее;
- если краевой параметр равен "знакоместо пустое" (т.е. еще сюда ничего не выводили), то выводим знакоместо спрайта без маски;
- если краевой параметр равен "знакоместо на левом краю спрайта", то подсовываем знакоместо спрайта под изображение на экране, затем накладываем правую маску для этого изображения, затем возвращаем сверху изображение на место;
- если краевой параметр равен "знакоместо на правом краю спрайта", то подсовываем знакоместо спрайта под изображение на экране, затем накладываем левую маску для этого изображения, затем возвращаем сверху изображение на место.
4в. В байт атрибутов заносятся, помимо цвета, краевой параметр текущего выводимого спрайта в биты flash и bright.
5. После завершения обхода всех выводимых клеток, копируем виртуальный экран на реальный. При этом в атрибутах сбрасываем биты flash и bright.
--
Т.е., если кратко, просматриваем знакоместа спрайтов и выводим в знакоместа экрана, если они не заняты или заняты частично. Пустые знакоместа в спрайтах не хранятся и на экран не выводятся.
А можно подумать для убыстрения вывода, как сделать наоборот - просматривать знакоместа экрана и выводить в них только ближние знакоместа необходимых спрайтов. Собственно, похожее на это ты и предлагаешь.
В твоем алгоритме пока непонятно, как учитывать краевые параметры (маски). Как подсовывать один спрайт под другой, т.к. мы сначала выводим ближние спрайты, а потом дальние (или сделать обратно, как было в первых тормозных версиях?).
А также сами таблицы должны быть динамическими, т.к. элементов клеток 15, и под каждый элемент свой спрайт.
---------- Post added at 11:28 ---------- Previous post was at 11:20 ----------
пока некогда, еще основную часть пишем.
Последний раз редактировалось Andrew771; 04.04.2011 в 11:46.
здесь действительно надо подумать и посмотреть
ведь отрисовки как раньше уже не будет, потому скорость повысится
а отрисовка станет проще
кстати вот 5 процедур для отображения (только отображения)
Код:обработка пустого места empty_char pop af //снимаем ненужный адрес exx xor a //красим экран - естественно в этом месте атрибуты должны быть #00 ld (de),a inc hl inc de exx ret //переходим на следующий элемент draw_char //обычная отрисовка изображения pop hl //снимаем адрес чара ld (draw_c0),sp ld sp,hl ld l,e ld a,d and #f8 ld h,a dup 3 pop bc ld (hl),c inc h ld (hl),b inc h edup pop bc ld (hl),c inc h ld (hl),b ex de,hl exx ld a,(hl) //красим экран - здесь уже естественно не 0 and c ld (de),a inc hl inc de exx ld sp,$ draw_c0 equ $-2 inc e ret nz ld a,d add a,8 ld d,a ret draw_charf //отрисовка изображения с отзеркаливанием pop hl //снимаем адрес чара ld (draw_c2),sp ld sp,hl ld l,e ld a,d and #f8 ld h,a ld d,ROTTAB dup 3 pop bc ld e,c ld a,(de) ld (hl),a inc h ld e,b ld a,(de) ld (hl),a inc h edup pop bc ld e,c ld a,(de) ld (hl),a inc h ld e,b ld a,(de) ld (hl),a ex de,hl exx ld a,(hl) //красим экран - здесь уже естественно не 0 and c ld (de),a inc hl inc de exx ld sp,$ draw_c2 equ $-2 inc e ret nz ld a,d add a,8 ld d,a ret draw_charv //отрисовка перевернутого по вертикали изображения pop hl //снимаем адрес чара ld (draw_c1),sp ld sp,hl ld l,e ld a,d or #07 ld h,a dup 3 pop bc ld (hl),c dec h ld (hl),b dec h edup pop bc ld (hl),c dec h ld (hl),b ex de,hl exx ld a,(hl) //красим экран - здесь уже естественно не 0 and c ld (de),a inc hl inc de exx ld sp,$ draw_c1 equ $-2 inc e ret nz ld a,d add a,8 ld d,a ret draw_charfv //отрисовка перевернутого по вертикали отзеркаленного изображения pop hl //снимаем адрес чара ld (draw_c3),sp ld sp,hl ld l,e ld a,d or #07 ld h,a ld d,ROTTAB dup 3 pop bc ld e,c ld a,(de) ld (hl),a dec h ld e,b ld a,(de) ld (hl),a dec h edup pop bc pop bc ld e,c ld a,(de) ld (hl),a dec h ld e,b ld a,(de) ld (hl),a ex de,hl exx ld a,(hl) //красим экран - здесь уже естественно не 0 and c ld (de),a inc hl inc de exx ld sp,$ draw_c3 equ $-2 inc e ret nz ld a,d add a,8 ld d,a ret2. Определяем элемент в текущей клетке.
3. По таблице, в зависимости от элемента клетки, определяем адрес спрайта, процедуру его вывода (1/4, 2/4, 3/4 или 4/4) и координаты спрайта на экране (на самом деле, в таблице хранится только горизонтальная координата, т.к. вертикальная всегда равна нулю).
3а. При этом в 1/4 спрайт будет выводиться как есть, в 2/4 - зеркально отраженным, в 3/4 - перевернутым, в 4/4 - перевернутым и зеркально отраженным. Спрайты, которые не симметричны, будут выводиться процедурой 1/4. Процедуры обозначают только способ вывода, а координаты вывода могут быть любыми, т.е. например 2/4 означает не то, что спрайт выводится только в 2/4 экрана, а то, что в любую координату экрана зеркально отраженным.
3б. В спрайтах хранятся для каждого знакоместа горизонтальная и вертикальная координаты, параметр занятости знакоместа ("краевой параметр") и 8 байтов изображения. Краевой параметр может иметь значения:
- знакоместо полностью перекрывает всё, что за ним;
- знакоместо на левом краю спрайта, поэтому знакоместо другого спрайта, если попадет под это знакоместо, должно будет выводиться с правой маской;
- знакоместо на правом краю спрайта, поэтому знакоместо другого спрайта, если попадет под это знакоместо, должно будет выводиться с левой маской.
4. Выводим спрайт соответствующей процедурой 1/4, 2/4, 3/4 или 4/4 на виртуальный экран.
4а. В каждой процедуре есть 3 блока вывода:
- вывод знакоместа непосредственно без маски;
- вывод знакоместа с левой маской;
- вывод знакоместа с правой маской.
4б. При выводе каждого знакоместа спрайта сначала проверяется хранящийся в байте атрибутов на виртуальном экране занесенный ранее другим спрайтом краевой параметр, в зависимости от этого процедура переходит на нужный блок вывода:
- если краевой параметр равен "знакоместо перекрывает всё, что за ним", то вывод данного знакоместа вообще не осуществляется, сразу переходим на следующее;
- если краевой параметр равен "знакоместо пустое" (т.е. еще сюда ничего не выводили), то выводим знакоместо спрайта без маски;
- если краевой параметр равен "знакоместо на левом краю спрайта", то подсовываем знакоместо спрайта под изображение на экране, затем накладываем правую маску для этого изображения, затем возвращаем сверху изображение на место;
- если краевой параметр равен "знакоместо на правом краю спрайта", то подсовываем знакоместо спрайта под изображение на экране, затем накладываем левую маску для этого изображения, затем возвращаем сверху изображение на место.
4в. В байт атрибутов заносятся, помимо цвета, краевой параметр текущего выводимого спрайта в биты flash и bright.
значит так5. После завершения обхода всех выводимых клеток, копируем виртуальный экран на реальный. При этом в атрибутах сбрасываем биты flash и bright.
--
Т.е., если кратко, просматриваем знакоместа спрайтов и выводим в знакоместа экрана, если они не заняты или заняты частично. Пустые знакоместа в спрайтах не хранятся и на экран не выводятся.
А можно подумать для убыстрения вывода, как сделать наоборот - просматривать знакоместа экрана и выводить в них только ближние знакоместа необходимых спрайтов. Собственно, похожее на это ты и предлагаешь.
В твоем алгоритме пока непонятно, как учитывать краевые параметры (маски). Как подсовывать один спрайт под другой, т.к. мы сначала выводим ближние спрайты, а потом дальние (или сделать обратно, как было в первых тормозных версиях?).
А также сами таблицы должны быть динамическими, т.к. элементов клеток 15, и под каждый элемент свой спрайт.
берем самые дальние элементы
заносим адрес обработчика и адрес тайла в соответствии с твоей картой тайлов
заносим цвет (младшие 6 битов) а в старшие 2 бита заносим статус тайла
00 стандартный
01 стандартный зеркаленный
10 перевернутый
11 перевернутый зеркаленный
это просто
далее если более ближний элемент накладывается поверх дальнего,
то:
1 проверяем атрибут накладываемого тайла
2.1 если он не краевой, то грубо меняем старый обработчик и адрес на новый
2.2 если он краевой, то перемещаем в соответствии с флагами (переворот и отзеркаливание)
и накладываем поверх, после чего заносим адрес обработчика и адрес тайла уже из буфера
3 заносим атрибут и флаги в таблицу отрибутов
кстати надо бы уже задуматьсяпока некогда, еще основную часть пишем.
Последний раз редактировалось jerri; 04.04.2011 в 13:24.
С уважением,
Jerri / Red Triangle.
С любовью к вам, Yandex.Direct
Размещение рекламы на форуме способствует его дальнейшему развитию
Andrew771, сделай,пожалуйста, две версии:
С музоном под ГС или АЮшку для буржуев
И одну под 48кб со спикером для босяков типа меня
AY насолько понимаю, не получится - не хватает процессорного времени. А GS нужно токо один раз загрузить вначале игры, а "босякам" беспокоиться нечего, если GS нет, то и так один спикер останется. Так что достаточно одной версии. Разве что при загрузке картинок можно попробовать переключать AY/спикер.
Этот алгоритм будет работать медленнее, чем текущий. Это то, от чего мы с Novastorm в своё время ушли. Зайди на первое сообщение этой темы, скачай 29-ю версию и посмотри, как она шевелится по сравнению с нынешней. Там как раз вывод осуществляется начиная с дальних клеток и кончая ближними. К тому же, там нет отзеркаливания и перевертывания, а всё задано сразу в спрайтах. Т.е., если применить еще отзеркаливание и перевертывание, то будет еще медленнее.
Зачем выводить дальние спрайты, если они будут закрыты ближними? Причем, слава Аллаху, ближние спрайты по размеру намного больше дальних, так что выводом одной какой-нибудь ближней стены мы перекрываем сразу полэкрана, и все дальние спрайты просто пробегаются без вывода.
У тебя хоть и нет вывода сразу, но приходится перековыривать все спрайты, да еще переворачивать и отзеркаливать тайлы, которые впоследствии всё равно будут перекрыты, так что сизифов труд.
Самый главный фактор, который наверно ты не учел, повторяю, - это то, что ближние спрайты намного больше дальних, поэтому они сразу перекрывают огромные области экрана, которые больше не нужно обрабатывать.
---------- Post added at 15:27 ---------- Previous post was at 15:19 ----------
Я кстати думал над тем, чтобы в памяти изначально создать список спрайтов, которые перекрываются текущим спрайтом, чтобы даже не пробегать по ним. Но не придумал, как эффективно и экономично по памяти.
---------- Post added at 15:28 ---------- Previous post was at 15:27 ----------
вот такую и сделаем первой версией. Я тоже, как буржуи, признаю только чистый 48 спек![]()
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)