This media is not supported in your browser
VIEW IN TELEGRAM
Пусть игра и не идет, зато Go зашел. Действительно прикольный язык. Не очень сложный, код получается очень чистый (чего не скажешь о каком-нибудь Python). Короче я искал что-то похожее на C++, я его нашел=)
Но есть и особенности:
1. Нельзя объявить переменную, а потом ее не использовать. Компилятор ругается. А я очень люблю объявлять переменные на будущее при разработке. Привыкну, думаю.
2. Нет классов, а все ООП на структурах построено. И... это нереально удобно. Когда я пытался учить C#, меня оттолкнуло именно то, что все в нем - объект, а язык построен полностью вокруг ООП. В Go это все реализовано непринужденно.
3. Указатели... И тут я хочу сказать, что ассемблер и Commodore очень помогли в понимании того, что такое указатели, и зачем они нужны. Я так понял, что в Go нельзя делать с указателями любую дичь на свете (типа арифметики с адресами и указателей на функции). Здесь они используются в основном в структурах. И это тоже очень удобно.
Я начал переносить на Go редактор графики для Commodore 64, который писал на Pyhton недавно, и уже могу похвастаться. В реализации на Python редактор жутко тормозил (но и написан он был на коленке). В текущей реализации на Go он работает в 60 FPS.
Для графики я использую фреймворк Ebiten Engine (не смейтесь над названием). Это что-то вроде PyGame для Python, но с меньшим набором возможностей (например, мне пришлось с нуля писать систему коллизий с мышкой для экранных кнопок).
Но я постоянно помню про игру. Я не могу про нее просто так забыть, с учетом того, сколько времени я на это потратил. Так что скоро будет обновление...
Но есть и особенности:
1. Нельзя объявить переменную, а потом ее не использовать. Компилятор ругается. А я очень люблю объявлять переменные на будущее при разработке. Привыкну, думаю.
2. Нет классов, а все ООП на структурах построено. И... это нереально удобно. Когда я пытался учить C#, меня оттолкнуло именно то, что все в нем - объект, а язык построен полностью вокруг ООП. В Go это все реализовано непринужденно.
// Объявляем транспортное средство
type Vehicle struct {
doors int
wheels int
}
// Объявляем машину, которая тоже транспортное средство
type Car struct {
Vehicle
engine string
}
// Транспортное средство умеет ездить. (v *Vehicle) значит, что это метод структуры Vehicle. При этом мы передаем эту структуру по ссылке (указателю)
func (v *Vehicle) drive() {
fmt.Println("I'm driving")
}
3. Указатели... И тут я хочу сказать, что ассемблер и Commodore очень помогли в понимании того, что такое указатели, и зачем они нужны. Я так понял, что в Go нельзя делать с указателями любую дичь на свете (типа арифметики с адресами и указателей на функции). Здесь они используются в основном в структурах. И это тоже очень удобно.
Я начал переносить на Go редактор графики для Commodore 64, который писал на Pyhton недавно, и уже могу похвастаться. В реализации на Python редактор жутко тормозил (но и написан он был на коленке). В текущей реализации на Go он работает в 60 FPS.
Для графики я использую фреймворк Ebiten Engine (не смейтесь над названием). Это что-то вроде PyGame для Python, но с меньшим набором возможностей (например, мне пришлось с нуля писать систему коллизий с мышкой для экранных кнопок).
Но я постоянно помню про игру. Я не могу про нее просто так забыть, с учетом того, сколько времени я на это потратил. Так что скоро будет обновление...
👍5
Весь день писал функцию для конвертации двоичных 16 битных чисел в десятичный формат (BCD, не так давно про него говорил).
Растянулось все так из-за моей невнимательности. Обожаю ассемблер=)
Если вкратце, то программа проверяет каждый бит числа и, если он равен 1, то прибавляет к финальному результату число, соответствующее позиции этого бита. Например:
1000 0000 0000 0000 - 32768;
0000 0000 1000 0000 - 128;
0000 0000 0000 0001 - 1.
Вся программа выглядит как-то так. Не очень презентабельно, но зато работает. Все на таблицах и самомодифицирующемся коде:
Ну и на картинке я взял число $54C3, или 21 699 в десятичной. Каждая цифра этого числа помещается в отдельный адрес памяти для того, чтобы потом было удобно переносить их на экран.
А все это нужно для ролевой системы. Как минимум, количество опыта игрока будет именно 16 битным числом.
Растянулось все так из-за моей невнимательности. Обожаю ассемблер=)
Если вкратце, то программа проверяет каждый бит числа и, если он равен 1, то прибавляет к финальному результату число, соответствующее позиции этого бита. Например:
1000 0000 0000 0000 - 32768;
0000 0000 1000 0000 - 128;
0000 0000 0000 0001 - 1.
Вся программа выглядит как-то так. Не очень презентабельно, но зато работает. Все на таблицах и самомодифицирующемся коде:
decimal_to_bcd_converter_16bit
lda #$00
ldy #4
@clear_loop
sta decimal_result_16bit,y
dey
bpl @clear_loop
ldx #15
@loop_1
clc
rol binary_input
rol binary_input+1
bcs @add_digits
@next_loop_1
dex
bpl @loop_1
@end
rts
@add_digits
clc
ldy #4
lda dec_tbl_lo,x
sta @set_address+1
lda dec_tbl_hi,x
sta @set_address+2
@set_address
lda $ffff,y
adc decimal_result_16bit,y
cmp #$0a
bcc @next
sbc #$0a
@next
sta decimal_result_16bit,y
dey
bpl @set_address
jmp @next_loop_1
Ну и на картинке я взял число $54C3, или 21 699 в десятичной. Каждая цифра этого числа помещается в отдельный адрес памяти для того, чтобы потом было удобно переносить их на экран.
А все это нужно для ролевой системы. Как минимум, количество опыта игрока будет именно 16 битным числом.
🔥1
https://dtf.ru/2532867
Опробовал тут Daggerfall Unity. Не смог устоять и написал небольшую статейку по этому поводу
Опробовал тут Daggerfall Unity. Не смог устоять и написал небольшую статейку по этому поводу
DTF
Daggerfall Unity - от людей и для людей — Александр Логачев на DTF
Недавно я узнал, что в релиз вышла фанатская оболочка для TES: Daggerfall, которая переносит великую игру на движок Unity.
🔥4❤🔥1
И снова не ролевая система...
Хотя предпосылки к ней уже есть. Я нашел исходники ремастера Doom RPG на PC, и там много чего можно подглядеть. Но главное - почти все параметры игрока и врагов умещаются в 8 бит, что очень упрощает работу.
https://github.com/Erick194/DoomRPG-RE
А так - немного реструктурировал код. Теперь в нем проще ориентироваться и работает немного быстрее. Ну и дописал функции для аптечек и ремонтного набора. Теперь они восстанавливают здоровье и броню игрока до максимального значения (пришлось ввести еще две переменные).
Ну и продолжаю писать редактор графики на Go. Очень крутой язык, всем советую. Пока что не так много сделал, но уже можно порисовать одним цветом, удалить пиксель, и включить/выключить сетку и селектор знакоместа. Но хочу сказать, что код на Go уже получается более понятным и чистым, чем на Python, А еще оно не тормозит в отличие от Python (ну или это я более ответственно к делу подхожу😅)
Хотя предпосылки к ней уже есть. Я нашел исходники ремастера Doom RPG на PC, и там много чего можно подглядеть. Но главное - почти все параметры игрока и врагов умещаются в 8 бит, что очень упрощает работу.
https://github.com/Erick194/DoomRPG-RE
А так - немного реструктурировал код. Теперь в нем проще ориентироваться и работает немного быстрее. Ну и дописал функции для аптечек и ремонтного набора. Теперь они восстанавливают здоровье и броню игрока до максимального значения (пришлось ввести еще две переменные).
Ну и продолжаю писать редактор графики на Go. Очень крутой язык, всем советую. Пока что не так много сделал, но уже можно порисовать одним цветом, удалить пиксель, и включить/выключить сетку и селектор знакоместа. Но хочу сказать, что код на Go уже получается более понятным и чистым, чем на Python, А еще оно не тормозит в отличие от Python (ну или это я более ответственно к делу подхожу😅)
🔥3👍2❤🔥1
This media is not supported in your browser
VIEW IN TELEGRAM
Продолжаю писать редактор графики для Commodore на Go.
В отличие от Python (точнее PyGame) приходится прописывать новые структуры, например, экранные кнопки.
Ну и я стараюсь все делать красиво, поэтому работа идет несколько медленно. Но зато все работает в 60 FPS.
Уже можно выбрать 3 цвета для каждого знакоместа, переключить цвет фона. Немного переписал управление для удобства. В общем, работа потихоньку движется=)
В отличие от Python (точнее PyGame) приходится прописывать новые структуры, например, экранные кнопки.
Ну и я стараюсь все делать красиво, поэтому работа идет несколько медленно. Но зато все работает в 60 FPS.
Уже можно выбрать 3 цвета для каждого знакоместа, переключить цвет фона. Немного переписал управление для удобства. В общем, работа потихоньку движется=)
❤🔥6
This media is not supported in your browser
VIEW IN TELEGRAM
Начались подвижки в ролевой системе. Наконец-то...
В общем я немного полазил по исходному коду Doom RPG и не придумал ничего лучше, чем просто скопировать некоторые моменты.
Вышло как-то так:
Здоровье и броня:
P.S. Добавил еще поле NXP - количество опыта для получения следующего уровня.
P.P.S. Для теста кинул эту функцию на кнопку SAVE=)
В общем я немного полазил по исходному коду Doom RPG и не придумал ничего лучше, чем просто скопировать некоторые моменты.
Вышло как-то так:
Здоровье и броня:
така, защита, уклонение и точность:
8 бит.
30 при старте игры.
Увеличение каждый уровень: текущее значение + 3 + (random % 3).
Максимум - 100 (в оригинале было 99, но у меня есть 3 свободных знакоместа)
А
пыт:
8 бит.
При старте равны 16, 12, 14, 16. И так всегда.
Увеличивается как: текущее + 1 + (random % 2).
Максимум 100.
О
Ну и в итоге все это выводится на экран (как и меняется текст всех показателей во вкладках меню).
16 бит.
Количество опыта для нового уровня в оригинале высчитывается как: (номер уровня * 20) + 60.
Не понял, зачем так сложно, если можно просто прибавлять 20.
P.S. Добавил еще поле NXP - количество опыта для получения следующего уровня.
P.P.S. Для теста кинул эту функцию на кнопку SAVE=)
🔥4❤🔥2
Начал разбираться в устройстве 2600, и это конечно очень забавная консоль.
Во-первых, процессор 6507, может адресовать всего 8Кб памяти.
Во-вторых, у нас есть всего 128 байт (sic!) оперативки. Да уж, память и правда была в те времена дорогая.
В-третьих, размер картриджа всего 4Кб.
Если посмотреть на адреса, то это выглядит как-то так:
TIA - это местный видеочип, а RIOT - оперативка, ввод/вывод и таймер.
Но есть и плюс - PAL версия (как у меня) поддерживает аж 104 уникальных цвета. В Commodore 64, для сравнения, палитра состоит всего из 16 цветов. Хотя кажется, что все это будет с кучей ограничений.
Буду разбираться дальше=)
Во-первых, процессор 6507, может адресовать всего 8Кб памяти.
Во-вторых, у нас есть всего 128 байт (sic!) оперативки. Да уж, память и правда была в те времена дорогая.
В-третьих, размер картриджа всего 4Кб.
Если посмотреть на адреса, то это выглядит как-то так:
0000-002C TIA (Write)
0030-003D TIA (Read)
0080-00FF RIOT RAM
0280-0297 RIOT I/O, TIMER
F000-FFFF ROM
TIA - это местный видеочип, а RIOT - оперативка, ввод/вывод и таймер.
Но есть и плюс - PAL версия (как у меня) поддерживает аж 104 уникальных цвета. В Commodore 64, для сравнения, палитра состоит всего из 16 цветов. Хотя кажется, что все это будет с кучей ограничений.
Буду разбираться дальше=)
👍5❤🔥1
Это жесть, господа=)
Полдня потратил на то, чтобы добавить на экран спрайт. А все потому что это не Commodore, где ты просто кидаешь в нужные регистры позицию, изображение и цвета спрайта, а видеочип налету все подхватывает.
Здесь у спрайтов вообще нет такого понятия, как позиция. Все приходится вычитывать исходя из линии растра.
Более того, каждый кадр процессор должен четко следовать за лучом растра (если на определенной линии ему ничего делать не надо, то есть возможность притормозить работу процессора до следующей линии). На каждую линию нам дается всего 76 тактов, за которые надо успевать что-либо сделать с логикой или графикой.
Короче, я сам еще не до конца понимаю, что тут происходит, но это довольно интересно.
Полдня потратил на то, чтобы добавить на экран спрайт. А все потому что это не Commodore, где ты просто кидаешь в нужные регистры позицию, изображение и цвета спрайта, а видеочип налету все подхватывает.
Здесь у спрайтов вообще нет такого понятия, как позиция. Все приходится вычитывать исходя из линии растра.
Более того, каждый кадр процессор должен четко следовать за лучом растра (если на определенной линии ему ничего делать не надо, то есть возможность притормозить работу процессора до следующей линии). На каждую линию нам дается всего 76 тактов, за которые надо успевать что-либо сделать с логикой или графикой.
Короче, я сам еще не до конца понимаю, что тут происходит, но это довольно интересно.
😱5❤🔥1
А вот, как выглядит код для определения позиции спрайта по Y. С позицией по X там еще веселее, и я пока не разобрался.
И данные спрайта. Нули в начале для очистки регистра, если спрайт рисовать не надо.
; цикл для каждой линии отрисовки на экране
ldx #0
graph_loop
; вычитаем позицию спрайта из текущей линии
; и сравниваем с высотой спрайта
txa
sec
sbc #50
cmp #13
bcc next
lda #0
next
;кидаем в регистр спрайта значение из таблицы со смещением
;(#0, если спрайт рисовать не надо)
tay
lda player_data,y
sta GRP0
;тоже самое с цветом
lda player_colors,y
sta COLUP0
; тормозим процессор до следующей линии отрисовки
stx WSYNC
; меняем цвет фона
stx COLUBK
inx
cpx #242
bne graph_loop
И данные спрайта. Нули в начале для очистки регистра, если спрайт рисовать не надо.
player_data
.byte #0
.byte %00111100
.byte %01111110
.byte %01011101
.byte %01111110
.byte %00111100
.byte %00011000
.byte %11111111
.byte %00011000
.byte %00011000
.byte %01100110
.byte %01100110
.byte %01100110
player_colors
.byte #0
.byte #$2c
.byte #$2c
.byte #$2c
.byte #$2c
.byte #$2c
.byte #$2c
.byte #$d2
.byte #$d2
.byte #$64
.byte #$64
.byte #$64
❤🔥1
Я тут подумал.
Так как в Atari нет видеопамяти как таковой, а только отдельные регистры для двух игроков, мяча (пикселя) и ракеты (пикселя), то с помощью каких-нибудь жестких хаков можно в качестве видеопамяти использовать эти два регистра игроков.
Допустим, у нас есть изображение, зашитое в памяти.
Надо учесть, что весь экран таким образом закодировать не получится, так как на одну линию отрисовки надо 20 байт (160 пикселей/8 бит). В PAL версии, как у меня, 242 линии отрисовки основного экрана, что в сумме дает 4840 байт, а это превышает размер картриджа.
Но если это не учитывать, то, думаю можно добиться нужного эффекта. Пока луч рисует спрайт первого игрока, мы кладем в спрайт второго игрока следующий байт, и vice versa. Думаю, что таким же образом можно менять цвета каждого спрайта на линии. Хотя я так прикинул, процессор должен будет успевать менять нужные регистры в худшем случае за 3 такта, а это очень мало. Но есть также вариант расширить спрайты, что снизит разрешение, но позволит выбить немного тактов для процессора (и уменьшит размер изображения в памяти).
И конечно, не получится таким образом делать динамическую графику, потому что динамика подразумевает RAM, а у нас оперативки 128 байт...
Короче, я пока что пребываю в шоке от архитектуры этой консоли=)
Так как в Atari нет видеопамяти как таковой, а только отдельные регистры для двух игроков, мяча (пикселя) и ракеты (пикселя), то с помощью каких-нибудь жестких хаков можно в качестве видеопамяти использовать эти два регистра игроков.
Допустим, у нас есть изображение, зашитое в памяти.
Надо учесть, что весь экран таким образом закодировать не получится, так как на одну линию отрисовки надо 20 байт (160 пикселей/8 бит). В PAL версии, как у меня, 242 линии отрисовки основного экрана, что в сумме дает 4840 байт, а это превышает размер картриджа.
Но если это не учитывать, то, думаю можно добиться нужного эффекта. Пока луч рисует спрайт первого игрока, мы кладем в спрайт второго игрока следующий байт, и vice versa. Думаю, что таким же образом можно менять цвета каждого спрайта на линии. Хотя я так прикинул, процессор должен будет успевать менять нужные регистры в худшем случае за 3 такта, а это очень мало. Но есть также вариант расширить спрайты, что снизит разрешение, но позволит выбить немного тактов для процессора (и уменьшит размер изображения в памяти).
И конечно, не получится таким образом делать динамическую графику, потому что динамика подразумевает RAM, а у нас оперативки 128 байт...
Короче, я пока что пребываю в шоке от архитектуры этой консоли=)
🤯2❤🔥1
А дальше больше!
Нам нужно конце каждого ROM (картриджа) указывать векторы для прерываний, которые этот процессор поддерживает. Но, насколько я понимаю, Atari 2600 вообще с этим не дружит. Тут никакие прерывания не помогут...
Не получится, как в Commodore, внезапно изменить метод отрисовки. А если я захочу добавить текст, то это нужно будет делать с уже имеющимся спрайтами.
И тем не менее, меня удивило то, что ребята реально делают рейкастинг на этой штуке.
https://www.youtube.com/watch?v=zk-QhYE4jxw
Как будто бы, надо попробовать перенести текстурированный рейкастинг с Commdoore 64, если это вообще возможно.
Нам нужно конце каждого ROM (картриджа) указывать векторы для прерываний, которые этот процессор поддерживает. Но, насколько я понимаю, Atari 2600 вообще с этим не дружит. Тут никакие прерывания не помогут...
Не получится, как в Commodore, внезапно изменить метод отрисовки. А если я захочу добавить текст, то это нужно будет делать с уже имеющимся спрайтами.
И тем не менее, меня удивило то, что ребята реально делают рейкастинг на этой штуке.
https://www.youtube.com/watch?v=zk-QhYE4jxw
Как будто бы, надо попробовать перенести текстурированный рейкастинг с Commdoore 64, если это вообще возможно.
❤🔥1
Наконец-то начал двигаться в сторону переноса всех данных уровней на дискету.
Создал новое игровое состояние для загрузки нового уровня и... два часа переносил его в новый файл, потому что пришлось повозиться с адресами меток. Раньше то все файлы вместе компилировались.
Ну и возникла вот такая проблема, как на первом видео. Понятное дело, что из-за прерываний.
Попробовал отключить прерывания на время загрузки и сделал вот такой эффект, как на втором видео: пишем, что надо приготовиться к загрузке, меняем цвет рамки, ждем 4 секунды и выключаем на время видеочип. Кривовато, но пока сойдет.
Надеюсь, что прерывания правильно отключаю и в будущем не придется ничего чинить=)
Создал новое игровое состояние для загрузки нового уровня и... два часа переносил его в новый файл, потому что пришлось повозиться с адресами меток. Раньше то все файлы вместе компилировались.
Ну и возникла вот такая проблема, как на первом видео. Понятное дело, что из-за прерываний.
Попробовал отключить прерывания на время загрузки и сделал вот такой эффект, как на втором видео: пишем, что надо приготовиться к загрузке, меняем цвет рамки, ждем 4 секунды и выключаем на время видеочип. Кривовато, но пока сойдет.
Надеюсь, что прерывания правильно отключаю и в будущем не придется ничего чинить=)
👍3🔥2❤🔥1