Media is too big
VIEW IN TELEGRAM
Ну и наконец видео-обновление. Перенес все текстуры в игру. Может быть потом еще придумаю, как это дело улучшить:)
🔥2
Раздумываю тут, как лучше сделать ролевую систему. Она должна быть простой - это главное условие.
И опять я обратился к Doom RPG.
Так же как и там я хочу добавить всего 4 параметра:
Attack - сила удара.
Defence - модификатор защиты.
Dexterity - ловкость (шанс уклониться).
Accuracy - точность (шанс попасть).
Плюс у игрока будет уровень здоровья и брони. И вот это все как-то надо совместить и выдать адекватные формулы расчетов при битвах.
Но еще в Doom RPG мне нравилось, что разные враги могут по разному реагировать на разное оружие. То есть, например, зомби очень быстро отлетает от дробовика, но почти не получет урон от автомата.
И я придумал, как довольно просто это сделать.
Всего будет 8 видов оружия, а у каждого монстра 1 байт будет отвечать за флаги подверженности конкретному виду.
Если, например, нулевой бит выставлен в 0, то враг получает пониженный урон от первого оружия. Если бит == 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.
И во-вторых, я избавился от таблиц ссылок на адреса триггеров, которые нужны были как раз для непрямой адресации)
Думаю, что таким же образом надо перевернуть таблицу для кастинга лучей и выиграть еще немного в быстродействии и памяти
До этого триггеры у меня хранились таким образом:
trigger_1
атрибут 1, атрибут n
trigger_n
атрибут 1, атрибут n
Теперь я перевернул таблицу:
triggers_attribute_1
триггер 1, триггер n
triggers_attribute_2
триггер 1, триггер n
Такой вариант позволил избавиться от indirect indexed адресации. То есть теперь используются только команды типа lda byte,x.
И во-вторых, я избавился от таблиц ссылок на адреса триггеров, которые нужны были как раз для непрямой адресации)
Думаю, что таким же образом надо перевернуть таблицу для кастинга лучей и выиграть еще немного в быстродействии и памяти
🔥3
This media is not supported in your browser
VIEW IN TELEGRAM
Сегодня не так много сделано, потому что я полвечера разбирался, почему вылезает ошибка.
Оказалось, что ошибка исключительно из-за моей тупости, потому что где-то в 2000 строках кода я оставил команду LDA без операнда. Правда и IDE указывала, что ошибка находится совершенно в другом месте=)
Зато я сделал еще несколько триггеров. Первый переключает текстуру блока на другую. Второй - удаляет блок с карты (или возвращает, в зависимости от текущей его кондиции).
И вот так, как на видео их можно комбинировать: кнопка (смена текстуры) + исчезающий соседний блок.
Оказалось, что ошибка исключительно из-за моей тупости, потому что где-то в 2000 строках кода я оставил команду LDA без операнда. Правда и IDE указывала, что ошибка находится совершенно в другом месте=)
Зато я сделал еще несколько триггеров. Первый переключает текстуру блока на другую. Второй - удаляет блок с карты (или возвращает, в зависимости от текущей его кондиции).
И вот так, как на видео их можно комбинировать: кнопка (смена текстуры) + исчезающий соседний блок.
🔥3
This media is not supported in your browser
VIEW IN TELEGRAM
Я мог бы сегодня сделать что-то полезное, но вместо этого полвечера залипал в дебаггер Commodore, который мне посоветовал Кирилл Лейфер.
Это просто визуальный оргазм=)
Сама эмуляция в 10% от скорости реального компа, чтобы можно было все разглядеть.
На видео можно заметить, как при каждом перемещении обновляется буфер экрана (самая яркая зона), и как он потом моментально перемещается на экран. Там же синим отображается считывание данных карты и таблиц для рейкастинга.
Но в программе надо разбираться, оно довольно не интуитивно.
Это просто визуальный оргазм=)
Сама эмуляция в 10% от скорости реального компа, чтобы можно было все разглядеть.
На видео можно заметить, как при каждом перемещении обновляется буфер экрана (самая яркая зона), и как он потом моментально перемещается на экран. Там же синим отображается считывание данных карты и таблиц для рейкастинга.
Но в программе надо разбираться, оно довольно не интуитивно.
❤5
Второй день думаю о том, нужна ли мне в игре миникарта, как, например в этой игре (Boom 64).
С одной стороны, отрисовка уровня происходит всего на 3 блока перед игроком, и если есть большие пустые пространства, можно заблудиться.
Но минусов миникарты я нашел больше:
1. Я не хочу еще больше нагружать процессор попиксельными отрисовками.
2. Уровень не такой большой - всего 24*24 блока. Если не делать много пустых пространств, то миникарта не понадобится.
3. Когда я играю в старые игры с картой, я всегда смотрю на нее и не смотрю на сам экран. Особенно, если это какой-нибудь лабиринт.
4. Делать миникарту размером меньше 7*7 блоков смысла нет, так как она будет неинформативна. Но и делать размером 7*7 смысла тоже нет, так как уровень маленький.
Как вариант, можно сделать секрет в стиле Doom: если игрок нашел карту - ее можно открыть. Или сделать обновление карты по нажатию кнопки.
Или вообще забить на нее, чтобы нужно было самому искать дорогу. К тому же, во всех старых Dungeon Crawler карт не было.
С одной стороны, отрисовка уровня происходит всего на 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 свободных байт!
Но я понял, как сохранить еще немного памяти для программы.
Отрисовка экрана у меня работает в двух режимах: 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
This media is not supported in your browser
VIEW IN TELEGRAM
Сделал триггер вывода текста.
Всего зона для текста будет занимать 120 символов (24 символа на 5 строк). Маловато, конечно.
К тому же придется так подбирать выражения, чтобы они попадали в ширину этой зоны.
Либо есть второй вариант:
Написать прерывание, которое каждые несколько обновлений экрана будет выводить по одной строке текста. Если экран переполнится, то произойдет смещение строк.
Но у второго подхода есть свой минус - можно не успеть прочитать текст.
Второй минус большого количества текста - он занимает ну очень много памяти. Один символ кодируется одним байтом, и более-менее осмысленное выражение займет не менее 200-300 байт, что слишком много.
Да даже это тестовое выражение уже занимает 53 байта.
Всего зона для текста будет занимать 120 символов (24 символа на 5 строк). Маловато, конечно.
К тому же придется так подбирать выражения, чтобы они попадали в ширину этой зоны.
Либо есть второй вариант:
Написать прерывание, которое каждые несколько обновлений экрана будет выводить по одной строке текста. Если экран переполнится, то произойдет смещение строк.
Но у второго подхода есть свой минус - можно не успеть прочитать текст.
Второй минус большого количества текста - он занимает ну очень много памяти. Один символ кодируется одним байтом, и более-менее осмысленное выражение займет не менее 200-300 байт, что слишком много.
Да даже это тестовое выражение уже занимает 53 байта.
❤1
Так, ну как будто бы все перенеслось... но мне не нравится.
Пока я рисовал, это смотрелось весело и интересно, но в самой игре картинка выглядит ужасно. Буду переделывать.
Для конвертации PNG в коммодоровский формат я написал самый ужасный питоновский скрипт в своей жизни. Не пишите код под пивом, ребята=)
Пока я рисовал, это смотрелось весело и интересно, но в самой игре картинка выглядит ужасно. Буду переделывать.
Для конвертации PNG в коммодоровский формат я написал самый ужасный питоновский скрипт в своей жизни. Не пишите код под пивом, ребята=)
❤2
Но это не окончательное решение проблемы...
Я могу загрузить в память все значения пикселей, но не могу загрузить все значения цветов.
Дело в том, что цвета для режима Multicolor Hires определяются в области памяти, которая отвечает за основной экран компьютера. И это ломает всю программу.
То есть получается так:
1. Программа загружается
2. Значения цветов помещаются на основной экран, и видеочип воспринимает их как символы.
3. Программа ломается видимо на каком-то прерывании.
Самый оптимальный вариант - это подгружать значения цветов с дискеты (или образа дискеты). То есть порядок действий будет такой:
1. Загружаем основную программу.
2. Подгружаем с дискеты значения цветов на основной экран.
3. Ничего не ломается.
4. ...
5. Profit
Надеюсь, это сработает
Я могу загрузить в память все значения пикселей, но не могу загрузить все значения цветов.
Дело в том, что цвета для режима Multicolor Hires определяются в области памяти, которая отвечает за основной экран компьютера. И это ломает всю программу.
То есть получается так:
1. Программа загружается
2. Значения цветов помещаются на основной экран, и видеочип воспринимает их как символы.
3. Программа ломается видимо на каком-то прерывании.
Самый оптимальный вариант - это подгружать значения цветов с дискеты (или образа дискеты). То есть порядок действий будет такой:
1. Загружаем основную программу.
2. Подгружаем с дискеты значения цветов на основной экран.
3. Ничего не ломается.
4. ...
5. Profit
Надеюсь, это сработает
❤1
Наконец-то разобрался, как подгружать данные с дискеты.
Для этого используются функции KERNAL (местная операционная система):
SETLFS (устанавливает логический номер файла и логический номер устройства);
SETNAM (устанавливает длину и адрес имени файла)
LOAD (загружает данные из файла).
Все параметры, которые принимают функции - стандартные, только имя файла будет отличаться. Поэтому можно создать триггер, который будет подгружать данные с дискеты (например, триггер смены уровня).
Для этого используются функции KERNAL (местная операционная система):
SETLFS (устанавливает логический номер файла и логический номер устройства);
SETNAM (устанавливает длину и адрес имени файла)
LOAD (загружает данные из файла).
Все параметры, которые принимают функции - стандартные, только имя файла будет отличаться. Поэтому можно создать триггер, который будет подгружать данные с дискеты (например, триггер смены уровня).
❤1