(бухай): программируй
148 subscribers
465 photos
96 videos
3 files
65 links
Мысли, дегустация и код
Download Telegram
Нарисовал текстуры для второго уровня. Как-то получилось более объемно, чем в прошлый раз. Но надо смотреть, как они будут выглядеть в игре. И видимо надо перерисовать текстуры для первого уровня.

А еще на каждом уровне будет отсылка к какой-нибудь классике. Здесь попытался нарисовать какодемона, но в условиях трех цветов вышло так себе)
🔥6❤‍🔥1
Изучил я исходники Doom 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 уровней. А что будет дальше, с музыкой, новыми спрайтами и ролевой системой? Десять штук максимум?

Есть вариант, сжать уровни на дискете. Это будет неплохой вариант, потому что там много повторяющихся байт, но я никогда не имел дело с архиваторами, поэтому придется еще повозиться=)
❤‍🔥1🔥1
Это надо брать. Поставлю рядом со своей Atari 2600)
❤‍🔥32🔥2
Ироничная фотография :)
❤‍🔥2
И даже поучаствовал в турнире по Quake 3. Но так как никогда особо в эту игру не играл, то финал получился довольно предсказуемым...
❤‍🔥1
Подумал я еще над формулами для битвы и остановился на следующем:
Урон:
damage = (weapon min. strength + random weapon strength * int(player attack/enemy defence)) << 1

Если враг предрасположен к оружию, то сдвигаем еще на 1 влево. Даже, если защита врага больше, чем атака игрока, то все равно можно нанести фиксированный урон. Но я буду стараться добавлять врагов на уровни таким образом, чтобы подобных ситуаций не возникало.

Попадание:
chance = (int(((player accuracy << 2) / enemy dexterity) * 128) >> 4)

Получается число, которое увеличивается (но не более 255 == 100%) при увеличении разрыва между этими двумя числами. Потом на основе случайного числа уже высчитывается фактическое попадание.

А еще написал функции для 16-ти битного деления и умножения. В целом, работают быстро, а так как эти операции потребуются 4 раза за ход, то вообще не страшно. Я даже хочу сделать небольшую случайную задержку перед ходом врага, как будто он думает.
❤‍🔥1
Опять немного поправил функцию для расчета урона и перенес ее в ассемблер. Получилась конечно та еще дичь, но вроде работает.
        ; ---------------------- CALCULATE DAMAGE ------------------------------
; weapon_min + (rand(weapon_min; weapon_max) * ((((player_attack << 4)/enemy_defence)*32)>>6))
; ----------------------------------------------------------------------
; rotate left player attack 4 times
lda fight_player_attack
sta rotate_inout
lda #0
sta rotate_inout+1
ldy #3
jsr rol_16bit
; divide player_attack by enemy_defence
lda rotate_inout
sta div_dividend
lda rotate_inout+1
sta div_dividend+1
lda fight_enemy_defence
sta div_divisor
lda #0
sta div_divisor+1
jsr divide_16bit
; multiply the previous result by 32
lda div_dividend
sta mult_f_number
lda div_dividend+1
sta mult_f_number+1
lda #32
sta mult_s_number
lda #0
sta mult_s_number+1
jsr mult_16bit
; rotate right the previous result 6 times
lda mult_result
sta rotate_inout
lda mult_result+1
sta rotate_inout+1
ldy #5
jsr ror_16bit
; get random weapon strength
jsr get_random_number
lda rnd_1
ldy curr_weapon_mod
jsr mod
clc
adc curr_weapon_add
; multiply random number by the previous result
sta mult_f_number
lda #0
sta mult_f_number+1
lda rotate_inout
sta mult_s_number
lda rotate_inout+1
sta mult_s_number+1
jsr mult_16bit
; add minimum weapon strength
lda mult_result
clc
adc curr_weapon_add
sta mult_result
lda mult_result+1
adc #0
sta mult_result+1
❤‍🔥1
А вообще возникла такая идея.
У игрока будет всего 4 возможных варианта в бою (не считая аптечки и брони):
— Атака - обычная атака;
— Защита - defence * 2;
— Уклонение - dexterity * 2;
— Побег - dexterity / 2;

А вот с врагами интереснее!
Будет три типа атаки:
— Обычная атака;
— Усиленная атака - attack * 2
— Хитрая атака - accuracy * 2
И также будут уклонение и защита, как и у игрока.

И игроку надо будет выбирать, как поступить дальше. Например, если враг использует усиленную атаку, логичным вариантом будет встать в защиту.
На экран будут выводиться подсказки, но думаю, что для каждого врага нужно будет придумать свою собственную подсказку, как в старых jrpg.

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

Пока работают только 3 кнопки: атака, защита и уклонение.
— При атаке урон высчитывается по уже известной формуле. При этом, 25% урона всегда идет на броню, а остаток на здоровье. Если урон броне перевалил за количество брони, то остаток урона прибавляется к урону здоровья. Возможно над этим надо еще подумать.
— При нажатии на "Защиту", показатель defence умножается на 2.
— Аналогично с "Уклонением". Но на 2 умножается dexterity.
— После хода игрока все показатели врага сбрасываются до дефолтных значений и vice versa.

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

Когда-нибудь это закончится, а то 14 мая будет уже ровно полгода, как мне в голову пришла идея снова заняться игрой на коммодор...
🔥5❤‍🔥2
https://youtu.be/LnzuMJLZRdU?si=S59nYuS6Pftfr8tw

Офигенная серия видео. Мужик на макетной плате собирает компьютер на базе процессора 6502 и тут же программирует его.

После этого видео захотелось тоже чем-то таким заняться, но с чего начать, не могу сообразить.

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

Один игровой спрайт в моей игре состоит из 4 хардварных спрайтов. Я сперва рисовал игровые спрайты в Aseprite (двойные пиксели трудно рисовать), а потом переносил вручную изображение в редактор спрайтов для Commodore, где рисовал их уже по отдельности (и это очень неудобно).

Поэтому я не придумал ничего лучше, чем создать собственный редактор спрайтов исключительно для своей игры. Это очень сырая версия, которую потом я конечно же доработаю (нет). Осталось добавить только функции для сохранения изображений в json, png и asm.

А писал я кстати на Godot. Обожаю этот движок за то, что на нем можно спроектировать все что угодно за день-два.

Редактор поддерживает все возможности Commodore:
Во-первых, можно отдельно отключить сетку для каждого пикселя и сетку для каждого спрайта.
Во-вторых, можно выбрать цвет для каждого спрайта и два цвета, общих для всех спрайтов.
В-третьих, можно выбрать, каким из цветов рисовать конкретный пиксель (или стереть его)
В-четвертых, все это работает в 60 FPS.

Короче, как допишу сохранение и загрузку, станет намного проще.

А то, как я реализовал в итоге шанс попадания по врагу в игре потом покажу)
🔥5❤‍🔥1
Короче повозился я с этой программой, а все потому что ассемблер приучил меня все усложнять ради производительности. В Godot импорт изображений в рантайме осуществляется одной строкой, а я написал аж 4. Из-за этого, после экспорта в .exe, она перестала работать нормально (уже починил).

Но рисовать спрайты реально стало удобнее. Теперь не приходится подгонять пиксели под сетку 2*1, а потом переносить каждый спрайт по отдельности в другой редактор.

Но проблема все равно есть. Для редактора я брал цвета с Commodore Wiki, и они должны быть правильными. Но вот в эмуляторе это все выглядит совершенно иначе (на реальном железе еще не проверял).

Вот, нарисовал кривую собаку) В редакторе выглядит ну... нормально, а в самой игре ИМХО хуже.

Хотя и в этом есть вайб 80-х. Там и не таких уродцев можно было встретить=)
👍4❤‍🔥1
А вообще жесть. Я тут посчитал, что раз у меня на каждый уровень уникальные текстуры стен и спрайты врагов и объектов, то получается, что мне надо нарисовать:
— 16 * 10 уровней = 160 текстур;
— 4 * 10 = 40 врагов;
— 4 * 10 = 40 объектов;
Итого 240 изображений.
Кажется, что я буду использовать уже имеющиеся текстуры на других уровнях, но менять окраску (как в Doom RPG), и это должно сработать.

Немного цветовой магии, и вот обычная собака превращается в посланника ада (нет)

В общем, это можно использовать)
😁3❤‍🔥2👍2
This media is not supported in your browser
VIEW IN TELEGRAM
Почти дописал боевую систему!!!
Правда не очень понятно, насколько она вышла адекватной. Надо тестировать. А еще обязательно надо будет проверить пошагово на правильность кода. Визуально он вроде работает, но где-нибудь могла закрасться ошибка.
А еще надо бы как-то показывать на экране, чей ход. Сейчас, в принципе, это видно по тексту, но хотелось бы более понятный индикатор.

Когда враг планирует сильную или хитрую атаку, это отображается на экране. При этом игроку надо угадать, что делать дальше: защищаться или уклоняться. Ну и после каждого хода врага есть задержка в 2 секунды, чтобы игрок успевал прочитать текст. Да, вроде кривого кода дофига с кучей деления и умножения, но отрабатывает моментально.

Ну и последнее. Я решил пойти по простому пути в части поведения врагов. У каждого врага будет тип (или характер). Будут тупые или аккуратные враги, которые только атакуют и/или защищаются. Будут враги-маньяки, которые будут чаще бить усиленными атаками и т.д. Все паттерны поведения будут храниться в таблице
👍2🔥2❤‍🔥1
И тут я подумал, что неплохо было бы на экране как-нибудь визуально отображать попадания и промахи.

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

И скорее всего это все нужно будет делать в прерываниях. Надеюсь, у меня там еще осталось время для такого.

И конечно, на все это надо наложить какие-нибудь звуки, а это вообще моя больная тема 😢
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤‍🔥2