Важная информация

User Tag List

Страница 7 из 14 ПерваяПервая ... 34567891011 ... ПоследняяПоследняя
Показано с 61 по 70 из 136

Тема: HWYENC

  1. #61
    Veteran Аватар для nzeemin
    Регистрация
    20.12.2005
    Адрес
    Москва
    Сообщений
    1,995
    Спасибо Благодарностей отдано 
    1,059
    Спасибо Благодарностей получено 
    1,222
    Поблагодарили
    478 сообщений
    Mentioned
    15 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Так, дальше у нас рубрика "нас не спрашивали -- мы отвечаем".
    О внутреннем устройстве игры.

    Сначала очевидное.
    Вы управляете Vorton, всего их пять, текущий с белой шапкой это Main Vorton, остальные это Auto-Vorton, все они толкают вперёд Lasertron, который нужно довести до конца зоны 0.
    Мир игры разбит на зоны, всего их 31., визуально они нумеруются 30..0, внутри наоборот 0..30 и больше.

    Мир игры описывается в виде записей длиной 16 байт, всего их 260 (с адреса 7B00). Это все объекты всех зон -- таблица игрового мира.
    Поля каждой записи объекта:
    ; +$00 -- горизонтальное смещение объекта; FE -- пустая запись, FF -- конец таблицы
    ; +$01,+$02 -- позиция объекта
    ; +$03,+$04 -- смещение объекта; это значение плюс смещение текущей зоны ($8F03) даёт адрес на теневом экране
    ; +$05 -- базовый номер спрайта -- индекс в таблице 7A00
    ; +$06 -- паттерн движения: 000 = Vorton, 006 = Fire, 012 = Block, 026 = Flat blocker, 032 = Barrel
    ; +$07 -- направление движения, копия из (IX+$0С) AND $07, значения 0..7
    ; +$08 -- флаги движения; 0 = останов, 1 = движение; bit 7 = 1: взрыв
    ; +$09 -- горизонтальное смещение (только биты 2-3)
    ; +$0A -- фаза спрайта, смещение от $8F00: 015,017,020,021,022,023
    ; +$0B -- номер точки продолжения по таблице $9000
    ; +$0C -- начальное направление движения, копируется в +$07
    ; +$0D,+$0E,+$0F -- начальные значения для +$00,+$01,+$02
    Объекты мира -- это препятствия и враги.

    Дальше, есть блок игровых объектов с которыми мы работаем сейчас, формат записей тот же что и выше.
    Начинается он по адресу 8A00, сначала идут 5 Vortons, затем Lasertron, затем три fireball (выстрелы/пули).
    Затем за этим блоком из девяти зафиксированных игровых объектов идут текущие игровые объекты, числом до 44 записей.
    При смене текущей зоны обновляется и набор текущих игровых объектов -- перебираются все объекты игрового мира, выбираются только те которые вблизи текущей зоны, с некоторым порогом. Поэтому получается что объекты мира "живут" только когда они находятся внутри текущей зоны или вблизи её.
    При помещении в таблицу текущих объектов, копируются 14 байт записи, в остальные два байта записывается адрес откуда взята запись в игровом мире. При переходе в другую зону (пересоздание списка текущих объектов), текущие записи копируются обратно по этому сохранённому адресу -- возвращаются в общую таблицу игрового мира.

    Отрисовка.
    В памяти держится два теневых экрана, оба 1 бит на пиксель (чёрно-белые). Первый теневой экран это фон, рисунок зоны без объектов. Этот экран формируется один раз при заходе в зону, меняется только при смене зоны. Но в этот экран выводятся плоские площадки-препятствия: они не двигаются и не могут загораживать другие объекты, поэтому их можно рисовать на фоне.
    Второй теневой экран это копия первого, но поверх ещё рисуются спрайты объектов. Спрайты имеют размер 24x24 пикселей, каждый спрайт имеет маску.
    При отрисовке перебираются все текущие игровые объекты (включая Vortons, Lasertron и выстрелы). Сначала по адресу 8D52 собирается список объектов -- гориз.смещение + адрес записи, причём эта таблица собирается сортированной от дальних объектов к ближним -- сделано для того чтобы при отрисовке спрайты правильно наложились друг на друга. Объекты не попадающие в экран не попадают в эту таблицу. После составления таблицы сразу выполняется рисование спрайтов на втором теневом экране, при этом в отдельной таблице отмечаются знакоместа в которые попал спрайт (таблица флагов отрисовки, байт на знакоместо 8x8).
    Следующий шаг -- отрисовка второго теневого экрана на реальный экран. Причём полностью он рисуется только один раз при входе в зону, после этого отрисовка опирается на таблицу флагов отрисовки, т.е. выводим только то что реально изменилось.
    И последний шаг отрисовки -- восстановление второго теневого экрана, т.е. стирание спрайтов. Это делается копированием знакомест 8x8 с первого теневого экрана, опираясь на таблицу флагов отрисовки, т.е. тоже восстанавливается только то что изменялось.
    Сама отрисовка спрайтов выполняется с горизонтальной точностью в 2 пиксела -- есть 4 процедуры отрисовки спрайтов, со смещениями +4, +2, 0, -2. Т.е. точность движения объектов по вертикали -- 1 пиксел, по горизонтали 2 пиксела.

    Движение и столкновения объектов.
    Пробегаем по таблице текущих игровых объектов, сравнивая записи каждый-с-каждым. Если выявили столкновение, делается такая штука. Берётся значение паттерна движения обоих объектов (поле +$06), они складываются, полученное значение используется как индекс в таблице адресов продолжений -- просто происходит переход по указанному в таблице адресу продолжения. Например, для статичных препятствий все адреса продолжений одинаковы, по ним код который говорит что объект должен остановится. Или например, у "солнышка" при столкновении с препятствием получаем адрес продолжения, где направление движения меняется на противоположное.
    Движение объектов обрабатывается вместе с расчётом столкновений, если нет столкновений, то отрабатывается то что указано байтом "паттерн движения" в записи объекта. Обычно это просто движение без изменений в текущем направлении, но есть и необычные паттерны, например "взять случайное число и с вероятностью 10/256 повернуть влево или вправо".

    В таблице объекта есть два байта про спрайт -- базовый номер спрайта, плюс смещение фазы спрайта. Реальный номер спрайта получается так. Берём смещение фазы спрайта, добавляем адрес 8F00 -- получаем адрес где лежит фаза спайта, это значение складываем с базовым номером спрайта, получаем индекс в таблице 7A00, где уже лежит реальный адрес спрайта. Что это даёт? во-первых, фазу спрайта по 8F00+смещение можно крутить -- и там есть несколько таких переменных, которые крутятся по-разному. Во-вторых, базовый номер спрайта задаётся отдельно -- можно иметь разные по виду объекты, у которых фаза крутится одинаково.

    Что сделано отлично:
    - Идея с общим миром в 260 записей из которого выбирается набор в максимум 44 текущих записи + 9 фиксированных записей. Причём мир легко восстанавливается в исходное состояние из тех же самых записей -- очень эффективно.
    - Отрисовка с двумя теневыми экранами плюс таблицей флагов отрисовки -- получилась довольно быстрой.
    - 9 фиксированых записи игровых объектов + 44 переменных идут одни за другим -- однородная таблица игровых объектов, что упрощает логику работы с объектами и отрисовки. Начало этого списка хранится в переменной 8F01. Смысл тут в том, что когда Main Vorton умирает, то просто сдвигается адрес начала таблицы в 8F01.
    - Все переменные собраны в один блок по адресу 8F00, инициализация всех переменных при старте игры выполняется копированием всего блока целиком из блока констант.
    - Расчёт столкновений через таблицу адресов продолжений -- это круто, прям магия.

    - - - Updated - - -

    Набор спрайтов:


    - - - Updated - - -

    Реальный экран и два теневых экрана:


  2. #61
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

  3. #62
    Guru
    Регистрация
    08.10.2005
    Адрес
    Москва
    Сообщений
    13,550
    Спасибо Благодарностей отдано 
    1,213
    Спасибо Благодарностей получено 
    1,748
    Поблагодарили
    680 сообщений
    Mentioned
    67 Post(s)
    Tagged
    1 Thread(s)

    По умолчанию

    Цитата Сообщение от nzeemin Посмотреть сообщение
    Реальный экран и два теневых экрана:
    Два теневых зачем? Да еще такой неровной формы краев?

  4. #63
    Veteran Аватар для nzeemin
    Регистрация
    20.12.2005
    Адрес
    Москва
    Сообщений
    1,995
    Спасибо Благодарностей отдано 
    1,059
    Спасибо Благодарностей получено 
    1,222
    Поблагодарили
    478 сообщений
    Mentioned
    15 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Titus Посмотреть сообщение
    Два теневых зачем? Да еще такой неровной формы краев?
    Мне кажется, я описал зачем.
    Частичное перекрытие этих двух экранов, очевидно, для экономии памяти.

  5. #64
    Veteran
    Регистрация
    22.11.2009
    Адрес
    Москва
    Сообщений
    1,584
    Спасибо Благодарностей отдано 
    66
    Спасибо Благодарностей получено 
    156
    Поблагодарили
    102 сообщений
    Mentioned
    12 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от nzeemin Посмотреть сообщение
    Тут уже просили God Mode.
    Моё мнение такое -- старые игры были сложными. И они должны были быть сложными.
    Потому что ты не мог пойти и купить ещё одну. Тебе приходилось ждать, пока ещё одна появится, пока ещё одну напишут.
    О, будут еще игры?

  6. #65
    Banned
    Регистрация
    05.07.2010
    Адрес
    Москва
    Сообщений
    1,058
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    1
    Поблагодарили
    1 сообщение
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Удаление в знак протеста против действий MM
    Последний раз редактировалось MacBuster; 26.01.2019 в 00:37. Причина: Удаление в знак протеста против действий MM

  7. #66
    Guru
    Регистрация
    27.02.2005
    Адрес
    москва
    Сообщений
    13,754
    Записей в дневнике
    1
    Спасибо Благодарностей отдано 
    141
    Спасибо Благодарностей получено 
    1,172
    Поблагодарили
    769 сообщений
    Mentioned
    18 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от nzeemin Посмотреть сообщение
    О внутреннем устройстве игры.
    а этот момент как обыграли ?

    Код:
    loop	LD   A,R
    	SLL  A
    	LD   HL,(36609)
    	LD   A,(36631)
    	LD   C,A
    	JR   NC,loop
    	LD   A,(HL)

  8. #67
    Veteran
    Регистрация
    22.11.2009
    Адрес
    Москва
    Сообщений
    1,584
    Спасибо Благодарностей отдано 
    66
    Спасибо Благодарностей получено 
    156
    Поблагодарили
    102 сообщений
    Mentioned
    12 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от MacBuster Посмотреть сообщение
    Это вы как такой вывод сделали из фразы о том что старые игры были сложными и при портировании должны такими оставаться?
    А вы вдумайтесь.
    Последний раз редактировалось shattered; 14.01.2018 в 17:57.

  9. #68
    Veteran Аватар для nzeemin
    Регистрация
    20.12.2005
    Адрес
    Москва
    Сообщений
    1,995
    Спасибо Благодарностей отдано 
    1,059
    Спасибо Благодарностей получено 
    1,222
    Поблагодарили
    478 сообщений
    Mentioned
    15 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от goodboy Посмотреть сообщение
    а этот момент как обыграли ?

    Код:
    loop	LD   A,R
    	SLL  A
    	LD   HL,(36609)
    	LD   A,(36631)
    	LD   C,A
    	JR   NC,loop
    	LD   A,(HL)
    Пока никак, я убрал все задержки которые нашёл.
    И всё равно пока порт работает примерно в 1.5 раза медленнее оригинала.

    - - - Updated - - -

    Кстати, понравился код Costa Panayi.
    Ошибку в оригинальном коде нашёл только одну:
    Код:
    ; We come here after we drawn ZONE digits
    ; First, we select objects from $7B00 table to $8A90 table
    L93B7:	MOV	#L7B00, R4	; 93B7	LD IX,$7B00	global objects table
    	MOV	#L8A90, R2	; 93BB	LD DE,$8A90	current zone objects
    	MOV	#44., R5	; 93BE	LD A,$2C	max number of objects to select
    				; 93C0	EX AF,AF'	
    L93C1:	MOVB	(R4), R0	; 93C1	LD A,(IX+$00)	<
    	BIC	#177400, R0	;			|
    ...
    				; 93EC	INC DE	
    				; 93ED	EX AF,AF'	
    	DEC	R5		; 93EE	DEC A		reached max records?
    				; 93EF	EX AF,AF'	
    	BEQ	L93FD		; 93F0	JR Z,$93FD	yes => jump
    Это начало цикла, обратите внимание на запись $2C в регистр A.
    Затем далее делается DEC A, но сразу после этого мы убираем результат операции через EX AF,AF'.
    В результате проверка JR Z бессмысленна.
    Но думаю что число текущих объектов никогда не превышает 2C (44 dec), поэтому эта ошибка не важна.

  10. #69
    Guru
    Регистрация
    27.02.2005
    Адрес
    москва
    Сообщений
    13,754
    Записей в дневнике
    1
    Спасибо Благодарностей отдано 
    141
    Спасибо Благодарностей получено 
    1,172
    Поблагодарили
    769 сообщений
    Mentioned
    18 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от nzeemin Посмотреть сообщение
    Ошибку в оригинальном коде нашёл только одну
    Код:
    	LD   HL,23296
    	LD   DE,23295
    	LD   A,(46287)
    	LD   (HL),A
    	LD   BC,768
    	LDDR
    на спеке аттрибуты лежат в области 22528,768
    тут затирается лишний байт

  11. #70
    Veteran Аватар для nzeemin
    Регистрация
    20.12.2005
    Адрес
    Москва
    Сообщений
    1,995
    Спасибо Благодарностей отдано 
    1,059
    Спасибо Благодарностей получено 
    1,222
    Поблагодарили
    478 сообщений
    Mentioned
    15 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Могу точно сказать что игра проходима.
    Прошёл на эмуляторе EmuStudio v0.12f

Страница 7 из 14 ПерваяПервая ... 34567891011 ... ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •