| Разработка и ромхакинг > Разработка игр |
| [SMD] Battle City (форк от battlecity-md от KRIKzz) |
| << < (3/7) > >> |
| Sharpnull:
Werton, остаток Game Over тоже видел и в Gens, ловил ещё в версии 1.07. Если найду причину, напишу. |
| Sharpnull:
* Исправил остатки спрайтов Game Over и других, дело в этом цикле: --- Код: ---u16 spr_kl2 = sprite_counter; for (ttt=0; ttt<(spr_kl-sprite_counter)+2; ttt++) { VDP_setSpriteFull(sprite_counter, -8, -8, SPRITE_SIZE(1, 1), 0, sprite_counter+1); sprite_counter++; } --- Конец кода --- sprite_counter изменяется и используется в условии, из-за этого не все спрайты затираются. * Также убрал обновление спрайтов из коллбэка VBlank и перенёс перед VDP_waitVSync() (т. е. перед VBlank, а не сразу после), это приводило к мерцанию при 9+ танков на поле и остаткам тайлов на экране подсчёта экрана. Хотя 9+ танков быть всё равно не должно, в этом случае начинаются тормоза. * Написал VDP_updateSprites(1, FALSE); вместо VDP_updateSprites(1,1);, чтобы спрайты танков сразу исчезали после экрана очков. * Убрал мерцание в начале уровня, не тот слой становился серым. SYS_disableInts() не понадобилось :) В Kega Fusion почему-то последние полосы открытия видны чуть дольше, чем должны. Это было и до моих правок. -------- Из багов, которые кажется не были озвучены: - В оригинале если стрелять по центру блока, а слева или справа осталась тонкая стенка, то она не задевается: --- Код: ---0001 или 1000 0001 1000 /\ /\ || || --- Конец кода --- - Петух не задевается, если стрелять со смещением. Нужно в detectBulletToStaffCollision() дописать по аналогии с detectBulletToWallCollision(). - Если зажать кнопку выстрела (не турбо), то при движении или повороте происходят выстрелы. - При заморозке (оглушении?) игрока, он может один раз выстрелить. |
| Werton:
Sharpnull, отличная работа :thumbup: Добавлено позже: --- Цитата: Sharpnull от 01 Май 2018, 01:09:10 ---Хотя 9+ танков быть всё равно не должно, в этом случае начинаются тормоза. --- Конец цитаты --- Вот поэтому я не стал особо увеличивать кол-во танков в моде, заметил эту тормозню, видимо надо код оптимизировать, явно консоль на большее способна. |
| Werton:
Добавил еще возможность стрельбы при заморозке, собрал описание фиксов для наглядности, за сами фиксы дружно благодарим Sharpnull), отметил его как тестера и багфиксера в стартовых титрах :) --- Код: ---===== версия 1.08-4 ===== -добавлено возможность стрельбы при заморозке игрока (как было в оригинале) -устранено невозможность уничтожить блоки возле границ поля внизу и справа -устранено заезд танков за правую и нижнюю границы поля -устранено остатки спрайтов Game Over -устранено при смене экрана подсчета очков спрайта танков исчезали с задержкой -устранено мерцание в начале уровня -устранено смещение взрыва со всеми стенами -устранено иногда при выстреле происходило пробитие двух кирпичей вместо одного -устранено потенциальное мерцание танков -устранено враг после взятия часов размораживался слишком быстро --- Конец кода --- battlecity-md_1.08-4.zip (158.14 КБ - загружено 422 раз.) |
| Sharpnull:
Werton, принял pull request, возможно стоило объединить в один коммит (squash), добавил как есть. Добавил вас в Collaborators, если что. |
| Sharpnull:
Важное исправление. Было смещение спрайта пули и её начальной позиции вылета: Случайно заметил, что пули летящие вниз и вправо дольше в полёте, стал отнимать 8 пикселей при отрисовки и оказалось, что пуля вылетает прямо из позиции танка, которая в левом верхнем углу, поэтому стреляя влево/вверх вылет был прямо из ствола, а в другие стороны пуля пролетала через весь танк. Думаю баг "-Снаряд появляется поверх танка ближе к центру (второй скриншот). ..." можно убрать из багов, я наверно ловил как раз тот момент пролёта через танк (обновление: посмотрел ещё раз оригинал, кажется всё-таки ближе к стволу, а не из центра). Возможно +/- пиксель не точно, пули при рикошете кажутся чуть дальше слева. Новый баг: смещение спрайта танка врага, раньше не замечал пока не стал им. Приложил скриншоты. Это оказался не баг, а оригинальное смещение с NES. Правда спрайты танков всё равно имеют немного другое положение, это не так важно. |
| Sharpnull:
Новые исправления: * В прошлом исправлении смещение спрайта стояло от балды. Я посмотрел на спрайты пули и сделал точные смещения, теперь центр пули как на скриншоте. * Убраны нежелательные выстрелы, если зажать A или C (с вкл. турбо) и двигать танк. Если это была фишка, тогда я её сломал :) * Возможность разрушить орла, если пуля смещена. Но не как в оригинале, где разрушение уже после 3-го выстрела, а после 4-го. На скриншоте после 3-го выстрела орёл цел. Чтобы как на NES, обработку столкновений с орлом нужно перенести туда же, где и кирпичи, но придётся решать проблемы со звуком: когда я пробовал, звук разрушенного кирпича перебивал. Werton, убийство себя рикошетом с вкл. PVP модом считается нормальным поведением? |
| Werton:
--- Цитата: Sharpnull от 02 Май 2018, 14:39:52 ---убийство себя рикошетом с вкл. PVP модом считается нормальным поведением? --- Конец цитаты --- Да, так и задумывал, чтобы эффект модов суммировался и жизнь медом не казалась :lol: |
| Sharpnull:
Важные исправления, так как влияют на столкновения пули и танков: * Раньше можно было убивать стоя задом к врагу. В версиях до моих фиксов такое было возможно только в двух направления, а после - во всех направлениях, так как снаряд летел из центра, а не из угла. * В двух направлениях пуля нагоняла на 6 пикселей раньше. * Раньше пуля была не пикселем, а летящей палкой перпендикулярно направлению полёта. Из-за этого окно попадания поперёк пули было 28 пикселей (30 - 2*1 отступа), а вдоль было 14 (16 - 2*1) пикселей. Теперь 16x16, как размер спрайта, можно выглядывать и тебя не убьют, но проехать через вас не получиться как в оригинале. Найден новый баг: сохраняются моды после игры в Mad Mode и последующую игру в другой режим. Werton, * Если можете, посмотрите конфиг, чтобы сбрасывалось правильно. Если сохранять нужно только Options, то проще config_init() вызывать перед выбором режима, тогда и моя правка в modeMenu() config.game_mode = 0; не нужна будет. * Я ошибся что анимации взрывов длились меньше, не знаю почему мне так казалось. Сверил по кадрам: в NES маленький взрыв 10 кадров, а здесь 11, что достаточно точно. Кадры считал в FCEUX с замедлением времени, а для SMD через GensKMod. Из history.txt этот пункт не убирал. * Тормоза при 9+ вражеских танков из-за проверки столкновений, так как проверяются все со всеми в gamelogic.c: --- Код: ---delta_1 = moveAvailableInUnits(&game_player[i]); game_player[i].posx += speed_x[game_player[i].rotate]; game_player[i].posy += speed_y[game_player[i].rotate]; if (!moveAvailableInWalls(&game_player[i])) { game_player[i].posx -= speed_x[game_player[i].rotate]; game_player[i].posy -= speed_y[game_player[i].rotate]; game_player[i].collision++; } delta_2 = moveAvailableInUnits(&game_player[i]); if (delta_1 > delta_2) { game_player[i].posx -= speed_x[game_player[i].rotate]; game_player[i].posy -= speed_y[game_player[i].rotate]; game_player[i].collision++; } --- Конец кода --- Этот код выполняется для каждого танка, а в moveAvailableInUnits() проверка также для всех танков. Я пробовал хак и перед delta_2 = moveAvailableInUnits(&game_player[ i ]); дописывал if (delta_1 == 32) continue;, это отсекало один вызов moveAvailableInUnits(), если танки были далеки друг от друга, и FPS оставался на уровне 60, но если были близки - тормоза оставались такими же. В NES, как следует из этой статьи, танки рисовали под себя невидимые стены, это позволяло избежать вычислений и поэтому по стволу игрока могли проехать. Переделывать как в оригинале было бы долго, лучше оставить как есть. * Подробности исправлений столкновений. Из collision.c, в detectBulletToUnitsCollision() стало: --- Код: ---s16 bx = bull->posx; s16 by = bull->posy; // Этих переменных и условий не было. Если margin_x = 1 и margin_y = 1, то обработка столкновений 14x14 s16 margin_x = 0; s16 margin_y = 0; // (game_player[i].rotate & 1) и !(game_player[i].rotate & 1) можно убрать, но если margin_x > 0 или margin_y > 0, // то танк стоящий вдоль пули, но со смещением поперек пули (8 пикселей), не будет убит, что может считаться правильным поведением, только не в оригинале if ((game_player[i].rotate & 1) && !(bull->rotate & 1)) { margin_x += 7; // Корректировка для поперечного столкновения с пулей, фактически она шириной 2 пикселя } else if (!(game_player[i].rotate & 1) && (bull->rotate & 1)) { margin_y += 7; // ... } if (bull->rotate == 3) { bx -= 15; // Было 9, на 6 пикселей раньше прилетало } else if (bull->rotate == 2) { by -= 15; // Было 9, ... } delta_x = bx - game_player[i].posx; delta_y = by - game_player[i].posy; // Don't kill with ass // Ниже проверки отсекают убийство задом if ((delta_x < 0 && bull->rotate == 1) || (delta_x > 0 && bull->rotate == 3) || (delta_y < 0 && bull->rotate == 0) || (delta_y > 0 && bull->rotate == 2)) continue; if (delta_x < 0) delta_x = -delta_x; if (delta_y < 0) delta_y = -delta_y; // Было delta_x < 15 && delta_y < 15, это давало отступ 1 по сторонам (28x14 или 14x28), теперь 16x16 if (delta_x < 16 - margin_x && delta_y < 16 - margin_y) { // Дальше убийство --- Конец кода --- -------- Ещё одно замечание, так как код запутанный. Если margin_x = margin_y = 1..n, то отступ дальней стороны от пули всё равно будет 0. Для того, чтобы были честные отступы, нужно ещё проверку делать вроде delta_x >= margin_x, delta_y >= margin_y, при этом только одно из них в зависимости от направления пули. Проще было бы заменить код на проверку пикселя внутри прямоугольника, но я следовал духу кода :) |
| Werton:
--- Цитата: Sharpnull от 03 Май 2018, 14:31:29 ---сохраняются моды после игры в Mad Mode и последующую игру в другой режим. --- Конец цитаты --- Исправил на гите, а также исправил найденный баг с продолжением движения замороженного в движении игрока. |
| Sharpnull:
--- Цитата: Werton от 03 Май 2018, 16:41:24 ---баг с продолжением движения замороженного в движении игрока. --- Конец цитаты --- Хотел спросить об этом, думал может это специально, как паралич в Road Rash (мотоцикл едет дальше). В сообщении выше в самом низу я добавил ещё замечание о столкновении, на всякий случай. -------- Как я и боялся, остались некоторые переменные. Из mutator.c: --- Код: ---case 13: mods.en_on_map_inc = 1; config.max_enemies_on_map = MAX_ENEMIES + 2; config.units_on_map = config.max_enemies_on_map + 2; config.max_explode = config.units_on_map << 1; config.max_bullets = config.units_on_map << 1; --- Конец кода --- Количество врагов остаётся после этого, остальное тоже, кроме en_on_map_inc. Ещё эти (mods_count - точно) из config_init(): --- Код: ---config.mods_count = MODS_COUNT; config.mods_inc_lvl = MODS_INC; --- Конец кода --- А config.random_mods = RANDOM_MODS; всегда имеет это значение. Но это уже по рефакторингу, там есть ещё лишние переменные вроде config.difficulty и дублировании mods.en_on_map_inc = 0; в reset_modes(). |
| Werton:
--- Цитата: Sharpnull от 03 Май 2018, 17:00:25 ---А config.random_mods = RANDOM_MODS; всегда имеет это значение. Но это уже по рефакторингу, там есть ещё лишние переменные вроде config.difficulty и дублировании mods.en_on_map_inc = 0; в reset_modes(). --- Конец цитаты --- RANDOM_MODS это флаг для дебага так сказать, чтобы отключить случайность и можно было моды потестить config.difficulty да не используется, это остатки от было начатой реализации настройки сложности, но заброшенной т.к. тупо надоело это все. Остальное справедливо, честно я полностью потерял интерес к этой затеи, поправь все как сам считаешь нужным, если есть такое желание конечно. |
| Sharpnull:
Исправления, в основном визуальные для соответствия оригиналу: * Сброс настроек после игры с модами. * Исправлены положения: GAME OVER (во время игры), жизней, PAUSE. * GAME OVER (во время игры) рисуется поверх танков. * Мерцание PAUSE быстрее. * Вместо иконки второго игрока IIP отображалось IP. * Жизни отображаются на одну меньше как на NES. Не знаю сколько макс. количество жизней в NES, здесь нет ограничений. При 20000 очках в NES прибавляется жизнь, здесь нет. К слову, о неточностях с оригиналом: При игре вдвоём, после смерти игрока сбоку прибегает GAME OVER для проигравшего игрока. При переходе на следующий уровень шторки закрываются для карты уровня, а не для подведения рекордов, как здесь. GensKMod мусор конечно, кадры он неправильно сохранял. Запись экрана в 60FPS дала точнее результат. Маленький взрыв происходит по-разному от 6 до 9 кадров, а в оригинале около 10. Время анимации не буду трогать. -------- Ещё одно исправление: * Проверка столкновений снарядов была смещена, это сказывалось на перпендикулярных столкновениях. Вражеский танк даже мог отбить летящий в его бок снаряд, выпустив свой в другом направлении. Теперь видно как снаряд подлетает к другому и сбивает. Обновил файл. |
| Sharpnull:
Исправления, в этот раз со звуком: * Был звук разбивки кирпичной стены вместо звука разбивки снаряда в некоторых случаях. Также сейчас: если одновременно бить по стали и кирпичу, будет оба звука в разных каналах (SOUND_PCM_CH3 и SOUND_PCM_CH4). Баг был известен как: -звук попадания как в кирпич при попадании в вертикальную броню (2 кубика), снизу и сверху справа (вообще глюки со звуком) * Использовался неверный звук снятия HP с танка. Теперь "заморозка" тоже с таким звуком, на NES же при "заморозке" другого игрока никакого звука не было. * Если у первого игрока закончились жизни, второго игрока нельзя было убить бомбой, взятой противником. Из звуковых несоответствий остаются, исправлять нет смысла: - Звук стоящего танка должен прерываться после убийства всех врагов. Но если это звук нашего танка, почему он прерывается в оригинале? Затишье после войны или это был звук не нашего танка? - Звук взрыва базы во время стартовой музыки отсутствует. Такое возможно только когда игрок себя убивает сразу. |
| Sharpnull:
Исправления, теперь с очками: * Не работала загрузка рекорда из SRAM. Была в 1.07b, в 1.08 сломалась. Ваш эмулятор сохраняет это в файле название_игры.srm обычно в папке с эмулятором. * Было ошибочное удвоение очков. * Теперь за взятые бонусы дают очки. * Не давали очки за врагов в оболочке игрока. С этим багов связаны другие: много очков за убийство такого врага, а после смерти появлялся спрайт рождения вместо количества очков. С врагом в оболочке игрока остались проблемы. Даже если оболочка начальная, поведение всё равно будет как у обычных танков, а очки дают за оболочку. То есть за жирного врага с начальной оболочкой игрока будет 100 очков вместо 400, но если враг возьмёт звезду, то очки будут +100. Исправлять это не буду, но чтобы не сбивать с толку на подведении очков отображаются оболочки игрока. * После первого запуска игры движения врагов были одинаковыми, кроме режима Mad Mode. --- Ещё одно исправление на сегодня: * Мод жоподёр (ass killer) работал неправильно, враг убивался если игрок имел такой же поворот танка во время попадания. |
| Sharpnull:
Мой последний релиз. Напоминаю, что исходный код находится здесь: https://github.com/infval/battlecity-md. Исправления: * Была проблема с модом ass killer, когда вторая пуля выпущена в другом направлении, пока первая в полёте. * Танк застревал в воде, если у него сбивали способность плавать. Теперь танк уничтожается сразу. * За убийство себя или другого игрока с модом "игрок убивает игрока" (pvp_kills) давали очки и отображался неправильный спрайт очков после убийства. Теперь очков не дают и спрайта нет. * Теперь последний результат второго игрока показывается на главном экране, но в отличие от оригинала он не скрывается, если в последний раз игрок был один. * Редактор уровней: была анимация танка (из-за неинициализированного объекта структуры _tank), мерцание танка не работало, обновление спрайта танка задерживалось. Замечания по коду и проекту: - Остались ещё баги и сам код написан плохо. Добавление модов запутало код ещё больше. - При реорганизации кода были изменены положения графики (gfx.s), что видно на скриншотах (видеопамять до и после). Во втором ряду не используются тайлы: '!' (на NES рядом с BONUS при игре вдвоём), где стоят '?', какой-то мусор в виде клизмы после 'STAGE'. Убраны gfx/bonus.bin, tiles.s так как дублировали бонусные тайлы, кроме "корабля" и рамки для танка, отображающей взятие бонуса "корабль". Эта рамка находится в конце gfx.s, но её можно переместить вместо "клизмы". - Символы 0-9, A-Z, -, ., "пробел", [, _, ] расположены в видеопамяти по ASCII таблице, поэтому их не стоит трогать. - kzzlogo.s не используется. В папке .vscode настройки для работы в Visual Studio Code. _make_clean_project.bat - очистить проект, нужно если изменения были сделаны в .h-файлах и в некоторых других случаях, _make_project.bat - компиляция проекта без очистки (это быстрее). Что можно улучшить или добавить: - При проверки столкновений использовать паттерн проектирования "Двойная буферизация" (http://gameprogrammingpatterns.com/double-buffer.html). Сейчас проверка происходит в текущем кадре на основе текущего положения, которое зависит от порядка проверки. Пример: танк игрока 1 едет, а за ним игрок 2 впритык. Так как сначала проверка у первого игрока, они едут без зазора, но если поменять танки местами, то игрок 1 будет отставать на одно смещение, потому что игрок 2 ещё не сдвинулся в этом кадре. - Сжимать уровни. Сейчас каждый маленький блок (8x8 пикселей) кодируется одним байтом: 70 уровней * 26 ширина * 26 высота = 47320 байт (~46КБ). Если уровни строятся как в режиме конструктор (нужно проверить), то каждый блок (16x16) кодируется 4 битами: 70 уровней * 13 ширина * 13 высота / 2 = 5915 байт (~6КБ). - Порядок появления и состав врагов в оригинале всегда одинаковый, в сети есть информация о составе. Здесь используются случайные танки. - Бонусы (Power-Ups) дают только 3 раза на уровне. Здесь 5 раз. Видел упоминание, что бонусы располагают в 16 местах. Здесь по всей карте и могут попасть в воду или в сталь. - В оригинале даётся 1000 бонуса игроку, который набрал больше очков при игре вдвоём. - Более точное начальное расположение пули. Сейчас разница в один пиксель в зависимости от направления. Плюс там странный код, который смещает иногда ещё на один пиксель (функция GLog_shot). Наверно стоило убрать. - Только 2 типа скоростей пуль, в оригинале 3. - На NES вода не двигается во время паузы. - На NES звук гусениц прерывается после убийства всех врагов. Баги: - Звук взрыва базы во время стартовой музыки отсутствует. - Музыка пропадает на следующем уровне, если взять в конце уровня бонус. Также остаётся след от взятия бонуса. - После первого выстрела, второй быстрее выпускается, чем последующие с зажатой кнопкой. -------- Увеличил скриншоты. Добавил загадочную "клизму" (или капля). |
| Werton:
Sharpnull, хорошо поработал, респект :thumbup: |
| vovan225:
Парни спасибо за игру! вспомнил 90-стые. Хотел сказать ещё про одну очень важную фитчу - в игре на приставке ещё можно было брать жизнь у второго игрока нажатием двух кнопок А и B одновременно. Можно это реализовать??? Было бы офигенно!!! Без этого играть в двоем не очень интересно, если одного убили то ему тупо остаётся ждать пока доиграет другой. |
| Sharpnull:
--- Цитата: vovan225 от 11 Январь 2019, 22:02:40 --- брать жизнь у второго игрока нажатием двух кнопок А и B одновременно --- Конец цитаты --- Тестируйте. |
| vovan225:
:wow: Спасибо!!! ща будем тестить! Добавлено позже: Протестили - первый игрок может брать жизни а второй нет, по крайней мере в танк 1990 так. И вот бы ещё добавить прикольный звук "тррррр" при рубке леса заметил что его нет ;) |
| Навигация |
| Главная страница сообщений |
| Следующая страница |
| Предыдущая страница |