(бухай): программируй
148 subscribers
465 photos
96 videos
3 files
65 links
Мысли, дегустация и код
Download Telegram
This media is not supported in your browser
VIEW IN TELEGRAM
Немного доработал рендеринг. Теперь не требуется очищать полностью экран, а только экранный буфер.
Благодаря этому пропало раздражающее мерцание между кадрами
😱1
Media is too big
VIEW IN TELEGRAM
Видео-отчет за последние несколько дней безудержного веселья.
Нет, серьезно, мне уже снятся эти байты.
Вчера мне приснилось, что для того, чтобы проснуться, надо поменять значение будильника в регистре памяти.
Я во сне написал программу на ассемблере и спокойно проснулся под будильник🤦‍♂
😁2
А они все ждут своего часа ....
Когда-нибудь я напишу что-нибудь на ассемблере для МК-90, починю арифмометры.

Но Commodore, он постоянно где-то в тени и наблюдает за мной. Требует новых игр

Видимо, надо вызывать ведьмака
1😱1
Думаю, как реализовать триггеры.
Пока придумал такую штуку. Каждый триггер будет иметь такие параметры:
Позиция X и Y на карте;
Номер ключа (будет проверяться наличие ключа у игрока);
Флаги Single use и Available.
Первый флаг будет означать, что триггер срабатывает один/бесконечное количество раз и переключает флаг Available в ноль в первом случае.
Второй флаг будет означать, что в данный момент триггер можно/нельзя активировать.

Допустим, я хочу сделать триггер для двери. Так как я отказался от отрисовки "комнаты за комнатой", дверь будет обычным блоком. К этом блоку надо привязать два триггера. Первый будет телепортировать игрока в одну сторону, второй - в другую. К тому же каждый триггер будет Single use (то есть флаг Available будет выставляться в 0) и должен активировать противоположный триггер (флаг Available выставляется в 1).

Получится так:
00000001 - тип триггера "дверь".
00000011 - флаги выставлены в 1.
Два байта - позиция на карте.
Один байт - номер ключа.
Два байта - позиция для телепортации игрока.
Один байт - номер триггера, который нужно будет активировать после телепортации.

Пока что я предполагаю, что на 1 уровне будет как минимум 64 триггера. Один триггер занимает 8 байт, то есть в сумме 512 байт.
😱1
Планируются такие триггеры:
— Телепортация (односторонняя);
— Дверь (телепортация + активация другого триггера);
— Смена видимости блока (выставляем флаг Textured на блоке в 0 или 1);
— Смена коллизии блока (флаг Solid в 1 или 0);
— Смена текстуры блока (меняется номер текстуры блока от 0 до 15);
— Смена флага Single use триггера (пока не придумал конкретные ситуации, где это можно использовать);
— Смена флага Available триггера (таким образом можно активировать будущие сюжетные триггеры, которые в начале уровне не будут доступны);
— Вывод текста на экран (будет определяться адрес текста в памяти)
— Триггер для смены уровня (тут будет номер следующего уровня, на основе которого уже будут считываться нужные файлы с дискеты. Осталось разобраться, как эти файлы считывать).
Как вариант, можно сделать триггер на смену параметров другого триггера, но конкретные примеры я пока тоже не придумал.
Чувствую. что большинство триггеров я буду придумать по ходу создания уровней для конкретных ситуаций.
🤡1
Немного о том, как я создаю текстуры для игры=)

Сперва я их рисую в Multipaint - программа, в которой можно рисовать для большого количества старых компьютеров, включая Commodore 64, VIC-20, ZX Spectrum и Amstrad.

Потом я своими руками переношу данные текстур попиксельно в Excel, где уже с помощью формул СЦЕП и ДВ.В.ШЕСТН создаю нужное представление последовательности байт для ассемблера.
Но я уже устал так делать😂 Пора бы что-нибудь на питоне написать для облегчения жизни
❤‍🔥1
Media is too big
VIEW IN TELEGRAM
Ну и наконец видео-обновление. Перенес все текстуры в игру. Может быть потом еще придумаю, как это дело улучшить:)
🔥2
Прикинул, как будет выглядеть спрайт оружия.
Здесь он состоит из двух спрайтов в столбец.
И, похоже, придется отказаться от видимого оружия в руках (либо использовать 1 спрайт, а не два), так как оно занимает половину экрана. За ним ничего видно не будет=)
❤‍🔥1
Раздумываю тут, как лучше сделать ролевую систему. Она должна быть простой - это главное условие.

И опять я обратился к Doom RPG.
Так же как и там я хочу добавить всего 4 параметра:
Attack - сила удара.
Defence - модификатор защиты.
Dexterity - ловкость (шанс уклониться).
Accuracy - точность (шанс попасть).

Плюс у игрока будет уровень здоровья и брони. И вот это все как-то надо совместить и выдать адекватные формулы расчетов при битвах.

Но еще в Doom RPG мне нравилось, что разные враги могут по разному реагировать на разное оружие. То есть, например, зомби очень быстро отлетает от дробовика, но почти не получет урон от автомата.

И я придумал, как довольно просто это сделать.
Всего будет 8 видов оружия, а у каждого монстра 1 байт будет отвечать за флаги подверженности конкретному виду.
Если, например, нулевой бит выставлен в 0, то враг получает пониженный урон от первого оружия. Если бит == 1, то двойной урон.
Ну или как-то так
👍2
This media is not supported in your browser
VIEW IN TELEGRAM
Вышла очень дурацкая ситуация, когда я добавил триггер двери.
На словах это выглядело нормально, но когда дошло до дела, все оказалось иначе.

Дело в том, что у меня триггер прикрепляется к определенному блоку на карте по координатам.

Триггер двери перемещает игрока за дверь и включает второй триггер, который позволит перенести игрока обратно. Так должно было работать.

Но так как оба триггера прикреплены к одному блоку, то функция проверяет их оба в цикле.
Первый триггер срабатывает нормально. Он перемещает игрока и включает второй триггер.

А вот второй триггер перемещает игрока, включает первый триггер. Но тут же в цикле отрабатывает первый триггер, который переключает все обратно😂

Пока что единственное решение, которое я нашел - поставить две двери в ряд.
Второе решение - поставить один триггер на дверь и менять координаты, куда он будет вести.
Третье решение - забить на телепортацию и убирать блок-дверь полностью.
❤‍🔥1
Ну и четвертый вариант - забить на триггеры, привязанные к блокам и прикреплять их к граням блока. Но в таком случае придется проверять пересечения отрезков. Но пока неясно, насколько это замедлит работу программы
👍1
This media is not supported in your browser
VIEW IN TELEGRAM
В итоге пошел по второму варианту=)
Теперь триггер меняет свои собственные аргументы (координаты, куда отправляется игрок) после выполнения. И места в памяти меньше занимает и работает также быстро
❤‍🔥1
Ну и наконец понял, как лучше хранить информацию.

До этого триггеры у меня хранились таким образом:

trigger_1
атрибут 1, атрибут n
trigger_n
атрибут 1, атрибут n

Теперь я перевернул таблицу:

triggers_attribute_1
триггер 1, триггер n
triggers_attribute_2
триггер 1, триггер n

Такой вариант позволил избавиться от indirect indexed адресации. То есть теперь используются только команды типа lda byte,x.
И во-вторых, я избавился от таблиц ссылок на адреса триггеров, которые нужны были как раз для непрямой адресации)

Думаю, что таким же образом надо перевернуть таблицу для кастинга лучей и выиграть еще немного в быстродействии и памяти
🔥3
❤‍🔥1
This media is not supported in your browser
VIEW IN TELEGRAM
Сегодня не так много сделано, потому что я полвечера разбирался, почему вылезает ошибка.
Оказалось, что ошибка исключительно из-за моей тупости, потому что где-то в 2000 строках кода я оставил команду LDA без операнда. Правда и IDE указывала, что ошибка находится совершенно в другом месте=)

Зато я сделал еще несколько триггеров. Первый переключает текстуру блока на другую. Второй - удаляет блок с карты (или возвращает, в зависимости от текущей его кондиции).

И вот так, как на видео их можно комбинировать: кнопка (смена текстуры) + исчезающий соседний блок.
🔥3
😁2🙈1
Вспомнил наконец-то про Tiled. Теперь рисовать карты стало гораздо приятнее. Осталось только скрипт написать, который все это дело бы переводил в удобоваримый для Commodore формат
👍2
This media is not supported in your browser
VIEW IN TELEGRAM
Я мог бы сегодня сделать что-то полезное, но вместо этого полвечера залипал в дебаггер Commodore, который мне посоветовал Кирилл Лейфер.
Это просто визуальный оргазм=)

Сама эмуляция в 10% от скорости реального компа, чтобы можно было все разглядеть.

На видео можно заметить, как при каждом перемещении обновляется буфер экрана (самая яркая зона), и как он потом моментально перемещается на экран. Там же синим отображается считывание данных карты и таблиц для рейкастинга.

Но в программе надо разбираться, оно довольно не интуитивно.
5
Второй день думаю о том, нужна ли мне в игре миникарта, как, например в этой игре (Boom 64).

С одной стороны, отрисовка уровня происходит всего на 3 блока перед игроком, и если есть большие пустые пространства, можно заблудиться.

Но минусов миникарты я нашел больше:

1. Я не хочу еще больше нагружать процессор попиксельными отрисовками.
2. Уровень не такой большой - всего 24*24 блока. Если не делать много пустых пространств, то миникарта не понадобится.
3. Когда я играю в старые игры с картой, я всегда смотрю на нее и не смотрю на сам экран. Особенно, если это какой-нибудь лабиринт.
4. Делать миникарту размером меньше 7*7 блоков смысла нет, так как она будет неинформативна. Но и делать размером 7*7 смысла тоже нет, так как уровень маленький.

Как вариант, можно сделать секрет в стиле Doom: если игрок нашел карту - ее можно открыть. Или сделать обновление карты по нажатию кнопки.
Или вообще забить на нее, чтобы нужно было самому искать дорогу. К тому же, во всех старых Dungeon Crawler карт не было.
🔥3💯2
Сегодня тоже особо нет обновлений. Времени особо не было.
Но я понял, как сохранить еще немного памяти для программы.

Отрисовка экрана у меня работает в двух режимах: Multicolor Hires и Standard Text Mode.
Переключаются они с помощью прерывания на 209 растровой линии.
Так вот я наконец додумался, что память экрана с того места, где начинается Text Mode и до конца не будет использоваться, потому что Text Mode берет данные вообще из другого места.
А это аж 1600 свободных байт!
🔥2
Media is too big
VIEW IN TELEGRAM
Но когда я сместил расчетные таблицы наверх в освободившееся место, случилась наркомания, как на видео.
Все из-за того, что одна таблица ссылается на другую, но в коде далала это в абсолютном, а не относительном виде.
Было так:
rays_tex_table_lo_adr
byte $90,$20,$d8,$14,$20,$d8,$9c,$20,$d8,$28,$20,$d8,$b8,$20,$d8,$4c

А я сделал так, и все заработало:
rays_tex_table_lo_adr
byte <tex_128,<tex_96,<tex_48,<tex_124,<tex_96,<tex_48,<tex_120,<tex_96
🔥2