Навигация по сайту
- Игры / Образы
- Игры на русском языке
- Коды / Советы / Секреты
- Наши переводы
- Наши проекты
- Игры на русском языке (OnLine)
- Эмуляторы
- Обзоры игр
- Информация
- Статьи
- Интервью
- Мануалы / Инструкции
Случайная игра
Вступай!!!
Облако тегов
Показать все теги
Pac-man Saw (Battle City Hack)
Название: Pac-man Saw (Battle City Hack)
Платформа: NES
Жанр: классическая аркада
Язык: английский
Автор, хакер: TiberiyLTim (TOF Team)
Благодарю за советы, помощь и просто общение: Griever'а, AnS'а и Cari
Сложность хака: гемплей, графика, текст, уровни, звук
Исходная игра: Battle City (J).nes
Количество игроков: 1
Дата: 2008-30.09.2009, общий релиз - 12.2010
• Изменено управление персонажем - направления перемещения зажимаются одним нажатием кнопки направления.
• В игрока внесена пуля, которая постоянно стреляет.
• Графика пули стёрта.
• Игрок перерисован, ускорено его перемещение (свойство быстрого танка).
• Перерисована графика противников (теперь они - бонусы-фрукты).
• Противники сделаны проницаемыми, чтобы игрок проходил сквозь них.
• Противники не двигаются и не стреляют - постоянно включен таймер заморозки (бонус часы).
• Переставлены точки появления противников.
• Включено одновременное появление противников не больше 3х (Selected_1player: LDA #4. По умолчанию в режиме одного игрока стоит (LDA #5) не больше 4х.
• Блок "орла" сделан проницаемым, чтобы игрок проходил сквозь него.
• Тайлы "орла" перерисованы в шипы.
• Штаб стёрт, расставлены шипы со свойством "орла".
• Затёрта графика взрыва.
• Затёрли графику появления противников и игрока.
• Убрали броню при появлении игрока.
• Отключено появление бонусов, бонусные танки не появляются.
• Отредактирован интерфейс.
• Изменено меню, включена опция перехода на секретный экран - просто меняем функцию второго игрока на переход к секретному посланию разработчиков, наместо которого мы написали наши титры (авторы хака и т.д.).
• Запрещён "highs core" экран.
• Запретили выбор конструктора уровней, т.к. нам он не нужен.
• Запретили демонстрацию игры, если ждать на заставке.
• Отключен выбор уровня.
• Сделаны новые уровни для игры.
• Подкорректированы звуки: некоторые переставлены, некоторые стёрты.
• Полностью изменена и подкорректирована палитра.
• Изменена и исправлена палитра фона для всех объектов.
• И многое-многое другое.
До...
После!
Далее будут пояснены некоторые (не все!) важные и не очень манипуляции, сделанные для этого хака.
Так как дружище Griver отлично поработал над сырцом BattleCity, то многие вещи проще делать в BattleCitySRC, где нужно только логически мыслить и знать немного команды ассемблера M6502 (в некоторых случаях достаточно знать только JMP), чтобы переставить несколько функций в Code.ASM. Кстати, рекомендуется всем начинающим ромхакерам препарирующим BC, использовать именно откомментированный исходник, т.к. это намного проще. Т.к. я не имею спортивного азарта в плане хакинга этой игры, то воспользуюсь им. При этом, если проводились ручные манипуляции с помощью хекс-редактора, то возможна некоторая несовместимость или баги - нужно всё сопоставить, откорректировать адреса, чтобы один код не ложился на другой, затирая оный. Либо нужно работать, используя исключительно один из вариантов: хекс-редактор или сырец. Т.к. у меня некоторые заготовки были для хекса, то я в этот раз работаю в хекс-редакторе и сырце. Уж извиняйте.
Первое, что нам нужно сделать в хаке - движок. Вернее нужно переработать имеющийся движок BC под наши нужды.
; Обрабатывает столкновение пули с объектом. Реагирует на попадание в "орла". Нам в данном хаке ненужно, чтобы вызывался Game Over, поэтому заменяем #$73 на #$EA. Но при этом ещё "орёл" (в хаке как триггер "шипы") перерисовывается (Draw_Destroyed_HQ) в камень - это нам не нужно, нам нужно, чтобы триггер был всегда активным, значит, нужно ещё перейти для работы с функцией Draw_Destroyed_HQ.
BulletToObject_Impact_Handle: ; CODE XREF: Bullet_Fly_Handle+58p
; Bullet_Fly_Handle+84p
JSR Temp_Coord_shl; Преобразует Temp в зависимости от Spr_Coord
JSR Check_Object; Возвращает ноль, если нулевой тайл
BEQ BulletToObject_Return0; Если перед пулей пустота, выходим с 0
LDA (LowPtr_Byte),Y
AND #$FC; '№'
CMP #$C8; '?' ; Сравниваем с индексом тайла штаба
BNE +
LDA HQ_Status; 80=штаб цел, если ноль то уничтожен
BEQ + ; Если 0, взрываем штаб
LDA #$EA; ''' ; Взрываем штаб
STA HQ_Status; Начальный кадр анимации взрыва
; (7 кадров по 4 фрейма)
LDA #1
STA Sns_HQExplode
STA Snd_PlayerExplode
JSR Draw_Destroyed_HQ; Рисует разрушенный штаб
LDX Counter
LDA #$33; '3' ; Делаем рикошет на пулю
STA Bullet_Status,X
JMP BulletToObject_Return0
BulletToObject_Impact_Handle: ; CODE XREF: Bullet_Fly_Handle+58p
; Bullet_Fly_Handle+84p
JSR Temp_Coord_shl; Преобразует Temp в зависимости от Spr_Coord
JSR Check_Object; Возвращает ноль, если нулевой тайл
BEQ BulletToObject_Return0; Если перед пулей пустота, выходим с 0
LDA (LowPtr_Byte),Y
AND #$FC; '№'
CMP #$C8; '?' ; Сравниваем с индексом тайла штаба
BNE +
LDA HQ_Status; 80=штаб цел, если ноль то уничтожен
BEQ + ; Если 0, взрываем штаб
LDA #$EA; ''' ; Взрываем штаб
STA HQ_Status; Начальный кадр анимации взрыва
; (7 кадров по 4 фрейма)
LDA #1
STA Sns_HQExplode
STA Snd_PlayerExplode
JSR Draw_Destroyed_HQ; Рисует разрушенный штаб
LDX Counter
LDA #$33; '3' ; Делаем рикошет на пулю
STA Bullet_Status,X
JMP BulletToObject_Return0
Меняем джамп BulletToObject_Return0 на Explode_Player_Tank_Impact - чтобы при попадании срабатывала указанная функция, будто попали в танк игрока. После чего, попав в "орла", производится взрыв игрока и отъём одной жизни - то, что нам нужно.
Переходим для работы с функцией Draw_Destroyed_HQ.
; Рисует разрушенный штаб. Нам в данном хаке ненужно, чтобы триггер "орёл" после попадания заменялся на "бетон", т.к. нам нужно, чтобы "шипы" работали и после первого попадания на них. А "шипы" = "орёл". Просто заменяем все байты в функции на EA, чтобы долго не думать. Это просто отключит перерисовку верхних 2х тайлов (первая линия) и нижних 2х тайлов (вторая линия) "орла" на "надгробный камень".
Draw_Destroyed_HQ: ; CODE XREF: BulletToObject_Impact_Handle+20p
LDA #>DestroyedHQ_TSA_Line1
STA HighPtr_Byte
LDA #<DestroyedHQ_TSA_Line1
STA LowPtr_Byte
LDX #$E
LDY #$EA
JSR String_to_Screen_Buffer
LDA #>DestroyedHQ_TSA_Line2
STA HighPtr_Byte
LDA #<DestroyedHQ_TSA_Line2
STA LowPtr_Byte
LDX #$E
LDY #$EA
JSR String_to_Screen_Buffer
RTS
; End of function Draw_Destroyed_HQ
Draw_Destroyed_HQ: ; CODE XREF: BulletToObject_Impact_Handle+20p
LDA #>DestroyedHQ_TSA_Line1
STA HighPtr_Byte
LDA #<DestroyedHQ_TSA_Line1
STA LowPtr_Byte
LDX #$E
LDY #$EA
JSR String_to_Screen_Buffer
LDA #>DestroyedHQ_TSA_Line2
STA HighPtr_Byte
LDA #<DestroyedHQ_TSA_Line2
STA LowPtr_Byte
LDX #$E
LDY #$EA
JSR String_to_Screen_Buffer
RTS
; End of function Draw_Destroyed_HQ
Проделав эти два редактирования, мы получаем постоянный триггер "орёл", который визуально изображаем как "шипы". При этом этот триггер выполняет нужные нам функции при попадании игрока (в игроке пуля) на него: производится отъём одной жизни, игрок переводится в исходную точку и положение. Цель достигнута. Обратите внимание, что взрывается любой танк, попавший в "орла", даже если это враг. Но в нашем хаке враги будут постоянно заморожены, поэтому нас это не волнует.
Однако, тут возникают две небольшие проблемы: если штаб был взорван, то пройдя уровень, после подсчета очков вы не перейдете на следующий уровень, вас переместят на экран Game Over. Нужно обезвредить счетчик, заменив #$80 на #$EA в функции Check_GameOver.
Check_GameOver: ; CODE XREF: ROM:C26Dj
LDA Player1_Lives
CLC
ADC Player2_Lives
BEQ Make_GameOver; Если жизней ни у кого не осталось, геймовер
LDA HQ_Status; 80=штаб цел, если ноль, то уничтожен
CMP #$EA; 'А'
BNE Make_GameOver; Если штаб разрушен, то геймовер
JMP Start_StageSelScrn; Если мы вышли из уровня победителями, то переходим к следующему уровню
LDA Player1_Lives
CLC
ADC Player2_Lives
BEQ Make_GameOver; Если жизней ни у кого не осталось, геймовер
LDA HQ_Status; 80=штаб цел, если ноль, то уничтожен
CMP #$EA; 'А'
BNE Make_GameOver; Если штаб разрушен, то геймовер
JMP Start_StageSelScrn; Если мы вышли из уровня победителями, то переходим к следующему уровню
А также, если статус штаба "взорван", после уничтожения последнего врага на уровне, то игрок замораживается - управление не срабатывает. Если это не исправить, то игрок в конце уровня обязательно бы врублялся в "шипы" (если они есть в его направлении), что приводило к потери жизни. Это исправляется небольшой корректировкой в функции FreezePlayer_OnHQDestroy, заменой байта #$80 на #$EA.
FreezePlayer_OnHQDestroy: ; CODE XREF: ROM:C23Bp
LDA HQ_Status; 80=штаб цел, если ноль, то уничтожен
CMP #$EA; 'А'
LDA HQ_Status; 80=штаб цел, если ноль, то уничтожен
CMP #$EA; 'А'
Завершающим штрихом я хочу отключить Конструктор уровней, который в этом хаке использовать, на мой взгляд, не нужно.
Заменяем байт по адресу $3f6c c $02 на $03 - запрет выбора конструктора. Режим двух игроков не запрещаем, а просто переводим на новую функцию - переход на секретный экран, который мы приспособили под титры.
Из-за того, что система коллизий неидеальна, шипы не всегда опасны.
Дизайн уровней построен так, что вы можете «на удачу» пройти через шипы.
И так далее. Играйте в новый хак, в новую игру, созданную TOF на движке BC. Всем эмуляторщикам посвящается!
Автор: TLT
Журнал: TOF