Осталось попробовать что-нибудь свое написать и запустить на реальной консоли.
И, насколько я понимаю, этот картридж поддерживает бэнк-свитчинг и вообще современные игры на Атари, но это не так интересно.
Но сперва, конечно, Коммодор!! У меня одна идея появилась, как сделать внутригровую карту, и это не так много ресурсов должно занять:)
И, насколько я понимаю, этот картридж поддерживает бэнк-свитчинг и вообще современные игры на Атари, но это не так интересно.
Но сперва, конечно, Коммодор!! У меня одна идея появилась, как сделать внутригровую карту, и это не так много ресурсов должно занять:)
🔥2❤🔥1
У меня дилемма. Не могу понять, как лучше сделать мини-карту.
В первом случае я могу использовать схематические одноцветные значки. Это займет чуть больше места в памяти, но имплементировать такой вариант в код будет проще.
А во втором случае я буду использовать уже имеющиеся текстуры. Это будет сложнее в плане алгоритма, но позволит убрать из каждого файла уровня лишнюю таблицу на 576 байт и отказаться от дополнительных текстур.
Вот не могу решить...
В первом случае я могу использовать схематические одноцветные значки. Это займет чуть больше места в памяти, но имплементировать такой вариант в код будет проще.
А во втором случае я буду использовать уже имеющиеся текстуры. Это будет сложнее в плане алгоритма, но позволит убрать из каждого файла уровня лишнюю таблицу на 576 байт и отказаться от дополнительных текстур.
Вот не могу решить...
❤🔥1
И за два вечера справился с проблемой.
Решил пойти по сложному пути. И пусть это потребовало лишних 768 байт, но зато выглядит вроде неплохо. Тем более, что у меня есть еще больше 18 Кб свободных. И это довольно много.
Но как же я задолбался подстраивать текстуры для их отрисовки на мини-карте (для этого и потребовалась память и новые таблицы). Текстуры лежат в памяти в кривом виде для более быстрого рейкастинга и не очень подходят для отрисовки в обычном виде, поэтому пришлось помучиться.
Карту можно двигать на WASD, и на ней рисуется значок игрока. А еще отображаются только те блоки, которые игрок уже видел (туман войны).
А если изменить текстуру на карте или убрать блок, то мини-карта тоже поменяется.
Ну и конечно при создании уровня можно отметить блоки, которые никогда не будут отображаться на мини-карте. Это я буду использовать для секретов.
Решил пойти по сложному пути. И пусть это потребовало лишних 768 байт, но зато выглядит вроде неплохо. Тем более, что у меня есть еще больше 18 Кб свободных. И это довольно много.
Но как же я задолбался подстраивать текстуры для их отрисовки на мини-карте (для этого и потребовалась память и новые таблицы). Текстуры лежат в памяти в кривом виде для более быстрого рейкастинга и не очень подходят для отрисовки в обычном виде, поэтому пришлось помучиться.
Карту можно двигать на WASD, и на ней рисуется значок игрока. А еще отображаются только те блоки, которые игрок уже видел (туман войны).
А если изменить текстуру на карте или убрать блок, то мини-карта тоже поменяется.
Ну и конечно при создании уровня можно отметить блоки, которые никогда не будут отображаться на мини-карте. Это я буду использовать для секретов.
❤🔥4👍2
После того как добавил мини-карту, вылез жесткий баг.
Некоторые текстуры в случайном порядке начинали съезжать на 1 пиксель вверх (верхняя линия не рисуется, а нижняя берется из следующей текстуры).
Опытным путем я выяснил, что некоторые байты в таблице указателей на текстуры почему-то иногда увеличиваются на 1. Но из-за чего они увеличиваются, было непонятно.
Хорошо, что в Vice есть замечательная возможность записать процесс работы компьютера и потом все это дело изучить в отладчике.
Я записал небольшую часть геймплея до момента смещения текстур. Нашел в памяти изменившийся адрес, поставил на него watchpoint и изучил запись.
В общем, по цепочке я выявил баг.
Оказалось, что дело в том самом "тумане войны".
Когда игрок переходит на следующий блок, перед ним считывается 9 блоков. И некоторые из этих блоков могут быть вне координат уровня.
Для рендеринга уровня пофиг, потому что он огорожен стенами (и я ничего не пишу в таблицу уровня), но не для мини-карты.
Сами блоки мини-карты хранятся в таблице 24*24. Есть другая таблица с указателями на строки мини-карты. Я беру блок в нужной строке со смещением по X и включаю первый бит (отображение на карте).
Но что, если блок находится за пределами карты?
Правильно, мы выходим за пределы таблицы указателей и включаем первый бит в совершенно другом месте.
Хорошо, что под раздачу попали только текстуры, и косяк было видно визуально...
Некоторые текстуры в случайном порядке начинали съезжать на 1 пиксель вверх (верхняя линия не рисуется, а нижняя берется из следующей текстуры).
Опытным путем я выяснил, что некоторые байты в таблице указателей на текстуры почему-то иногда увеличиваются на 1. Но из-за чего они увеличиваются, было непонятно.
Хорошо, что в Vice есть замечательная возможность записать процесс работы компьютера и потом все это дело изучить в отладчике.
Я записал небольшую часть геймплея до момента смещения текстур. Нашел в памяти изменившийся адрес, поставил на него watchpoint и изучил запись.
В общем, по цепочке я выявил баг.
Оказалось, что дело в том самом "тумане войны".
Когда игрок переходит на следующий блок, перед ним считывается 9 блоков. И некоторые из этих блоков могут быть вне координат уровня.
Для рендеринга уровня пофиг, потому что он огорожен стенами (и я ничего не пишу в таблицу уровня), но не для мини-карты.
Сами блоки мини-карты хранятся в таблице 24*24. Есть другая таблица с указателями на строки мини-карты. Я беру блок в нужной строке со смещением по X и включаю первый бит (отображение на карте).
Но что, если блок находится за пределами карты?
Правильно, мы выходим за пределы таблицы указателей и включаем первый бит в совершенно другом месте.
Хорошо, что под раздачу попали только текстуры, и косяк было видно визуально...
🔥4❤🔥1
Я вообще думаю, а не убивает ли мини-карта всю атмосферу исследования.
Anonymous Poll
93%
Оставляй. В твоих трёх текстурах запутаться проще простого. Хочу подсказку.
7%
Убери эту дичь. Становится слишком просто, а я за олдскул.
❤🔥1
Media is too big
VIEW IN TELEGRAM
Немного помучился с Atari 2600 и наконец-то сделал движущийся спрайт, который даже в разные стороны смотрит при повороте:)
Интересно, были ли в те времена похожие адские консоли для программистов.
Потому вроде даже в прямых конкурентах: Intellivision и ColecoVision была экранная память...
Интересно, были ли в те времена похожие адские консоли для программистов.
Потому вроде даже в прямых конкурентах: Intellivision и ColecoVision была экранная память...
👍2❤🔥1
В общем, что здесь происходит:)
Как я уже сказал, у объектов Atari нет понятия координат. Нельзя просто выставить спрайту X и Y. Вместо этого, когда луч доходит до нужной линии, а главное - нужной точки на линии, мы говорим: "Рисуй прямо сейчас".
С Y все понятно, хотя все равно непривычно, что Y идет от наибольшего значения к наименьшему и означает, сколько линий до конца экрана осталось.
Как я уже сказал, у объектов Atari нет понятия координат. Нельзя просто выставить спрайту X и Y. Вместо этого, когда луч доходит до нужной линии, а главное - нужной точки на линии, мы говорим: "Рисуй прямо сейчас".
С Y все понятно, хотя все равно непривычно, что Y идет от наибольшего значения к наименьшему и означает, сколько линий до конца экрана осталось.
👍2❤🔥1
А вот с X сложнее. Нам надо высчитать, сколько тактов займет у видеочипа пройти по линии именно столько пикселей, сколько нам надо. А после этого записать что-нибудь в регистры RESxx (для разных объектов), что сбросит спрайт до текущей позиции луча.
Проблема в том, что это надо делать в цикле, особенно, если предполагается, что объект будет двигаться. Но одна итерация цикла занимает аж 5 тактов. За это время луч успевает пройти 15 пикселей, что делает движения дерганными.
Но Atari это предусмотрели в своем стиле. Есть регистры HMxx. Запись в последние 4 бита смещает спрайт от -7 до +8 пикселей от текущей позиции.
То есть надо взять текущую координату X, поделить на 15. Получаем количество итераций (по 5 тактов каждая). А потом берем остаток от деления X на 15. Получаем количество пикселей, на которое надо сместить спрайт влево или вправо.
А потом записью в регистр HMOVE двигаем спрайт.
Проблема в том, что это надо делать в цикле, особенно, если предполагается, что объект будет двигаться. Но одна итерация цикла занимает аж 5 тактов. За это время луч успевает пройти 15 пикселей, что делает движения дерганными.
Но Atari это предусмотрели в своем стиле. Есть регистры HMxx. Запись в последние 4 бита смещает спрайт от -7 до +8 пикселей от текущей позиции.
То есть надо взять текущую координату X, поделить на 15. Получаем количество итераций (по 5 тактов каждая). А потом берем остаток от деления X на 15. Получаем количество пикселей, на которое надо сместить спрайт влево или вправо.
А потом записью в регистр HMOVE двигаем спрайт.
🔥3💊3❤🔥1
Нарисовал текстуры для второго уровня. Как-то получилось более объемно, чем в прошлый раз. Но надо смотреть, как они будут выглядеть в игре. И видимо надо перерисовать текстуры для первого уровня.
А еще на каждом уровне будет отсылка к какой-нибудь классике. Здесь попытался нарисовать какодемона, но в условиях трех цветов вышло так себе)
А еще на каждом уровне будет отсылка к какой-нибудь классике. Здесь попытался нарисовать какодемона, но в условиях трех цветов вышло так себе)
🔥6❤🔥1
https://alexlogachev.itch.io/commodore-64-dungeon-crawler-prototype/devlog/684092/unnamed-commodore-64-dungeon-crawler-devlog-0
Наконец-то дописал devlog на itch.io. Стало интересно, насколько вообще реально продвинуть игру на зарубежной площадке.
Наконец-то дописал devlog на itch.io. Стало интересно, насколько вообще реально продвинуть игру на зарубежной площадке.
itch.io
Unnamed Commodore 64 Dungeon Crawler Devlog #0
Hello everyone! Half a year ago I decided to launch my new Commodore 64 game project. My previous project by the name of "The Last Effort" was published in the august of 2023. It was not fully complet...
❤🔥4❤2
Изучил я исходники Doom RPG и понял, что все не так, как мне бы хотелось.
Во-первых, вот эта формула высчитывает количество нанесенного урона:
Commodore такое потянет, но с натяжкой. По моим подсчетам, тут числа могут выйти даже в 32 бита. А хотелось бы остаться в 8-ми, максимум в 16-ти.
Во-вторых, в Doom RPG используются дополнительные параметры (например, при каждом выстреле высчитывается мощность оружия в 16 битах, которая потом используется при расчете). Да, можно перенести как есть, но я не хочу все усложнять.
В общем, после сотен вариантов я пришел к такой формуле:
В целом, получаются нормальные цифры, но они немного зависят от случайности. Минус в том, что придется писать функции деления и умножения, которые мне пока что ни разу не пригодились. И все это в 16-ти битах.
Но и это еще не все! Есть же еще два показателя: accuracy и dexterity. Они должны влиять на вероятность попадания (как и на вероятность уклониться от атаки и избежать боя).
А еще у врагов и игрока есть броня! То есть помимо базового урона придется еще высчитывать урон, который на себя принимает броня (скорее всего, это будут какие-нибудь фиксированные проценты).
Короче, ролевка для меня - пока что самая сложная часть игры. Как бы я ни любил RPG, писать систему - это та еще дичь=)
Во-первых, вот эта формула высчитывает количество нанесенного урона:
calDmg = (((((((wpn->strMin << 8) + ((randStr * ((wpn->strMax - wpn->strMin) << 8)) >> 8)) * (strength / defense)) >> 8) * i) >> 8) * calWpnDmg) >> 8;
Commodore такое потянет, но с натяжкой. По моим подсчетам, тут числа могут выйти даже в 32 бита. А хотелось бы остаться в 8-ми, максимум в 16-ти.
Во-вторых, в Doom RPG используются дополнительные параметры (например, при каждом выстреле высчитывается мощность оружия в 16 битах, которая потом используется при расчете). Да, можно перенести как есть, но я не хочу все усложнять.
В общем, после сотен вариантов я пришел к такой формуле:
полученный урон = мин. урон оружия + (((случайный урон оружия)*атака)*(атака/защита врага))
смещаем результат на 4 бита вправо (делим на 4) и прибавляем 1 (для того, чтобы даже при очень большом разрыве прилетал урон в 1 пункт)
если для врага оружие смертельно, то смещаем биты на 2 влево (умножаем на 2)
В целом, получаются нормальные цифры, но они немного зависят от случайности. Минус в том, что придется писать функции деления и умножения, которые мне пока что ни разу не пригодились. И все это в 16-ти битах.
Но и это еще не все! Есть же еще два показателя: accuracy и dexterity. Они должны влиять на вероятность попадания (как и на вероятность уклониться от атаки и избежать боя).
А еще у врагов и игрока есть броня! То есть помимо базового урона придется еще высчитывать урон, который на себя принимает броня (скорее всего, это будут какие-нибудь фиксированные проценты).
Короче, ролевка для меня - пока что самая сложная часть игры. Как бы я ни любил RPG, писать систему - это та еще дичь=)
❤🔥2
А еще я понял, как сохранять текущий прогресс на дискету (правда для этого потребуется 6 Кб памяти).
Карту вместе с активированными триггерами, спрайтами и так далее, сохранить не сложно. Благо в KERNAL есть функция, которая за это отвечает.
То есть надо банально скопировать текущее состояние карты (которая изначально подгружается с дискеты и изменяется в процессе прохождения) в нужный файл.
Вопрос возникает с показателями игрока.
Вариант 1 — создать второй файл, где будут храниться только параметры игрока.
Вариант 2 — выделить отдельный участок памяти, в котором параметры игрока будут расположены перед данными карты (сложно, т.к. потребует нарушения логики кода).
Вариант 3 — использовать пароли и забить на состояние карты. Вышел из игры — начинаешь с начала карты.
Вариант 4 — вместо паролей — показатели сохраняются в отдельный файл, но начинаешь с начала уровня.
Суть в том, что на дискете ограниченное пространство. Уже сейчас выходит не более 17 уровней. А что будет дальше, с музыкой, новыми спрайтами и ролевой системой? Десять штук максимум?
Есть вариант, сжать уровни на дискете. Это будет неплохой вариант, потому что там много повторяющихся байт, но я никогда не имел дело с архиваторами, поэтому придется еще повозиться=)
Карту вместе с активированными триггерами, спрайтами и так далее, сохранить не сложно. Благо в KERNAL есть функция, которая за это отвечает.
То есть надо банально скопировать текущее состояние карты (которая изначально подгружается с дискеты и изменяется в процессе прохождения) в нужный файл.
Вопрос возникает с показателями игрока.
Вариант 1 — создать второй файл, где будут храниться только параметры игрока.
Вариант 2 — выделить отдельный участок памяти, в котором параметры игрока будут расположены перед данными карты (сложно, т.к. потребует нарушения логики кода).
Вариант 3 — использовать пароли и забить на состояние карты. Вышел из игры — начинаешь с начала карты.
Вариант 4 — вместо паролей — показатели сохраняются в отдельный файл, но начинаешь с начала уровня.
Суть в том, что на дискете ограниченное пространство. Уже сейчас выходит не более 17 уровней. А что будет дальше, с музыкой, новыми спрайтами и ролевой системой? Десять штук максимум?
Есть вариант, сжать уровни на дискете. Это будет неплохой вариант, потому что там много повторяющихся байт, но я никогда не имел дело с архиваторами, поэтому придется еще повозиться=)
❤🔥1🔥1
И даже поучаствовал в турнире по Quake 3. Но так как никогда особо в эту игру не играл, то финал получился довольно предсказуемым...
❤🔥1