Найти в Дзене
ZDG

Игра Apple на Rust: Финал

Оглавление

Ну, вот и доделал ремейк игры Apple с БК-0010 на Rust.

Предыдущие части: Перечислимые структуры, Трусливый код и Event Loop, Первый результат, Лыко-мочало, Время жизни, Графическая прокладка, Дженерики, Композиция, Модули, Начальное проектирование, Итоги про память, Что там с памятью, Колхозим интерфейсы, Где у него классы, Поддержка SDL2, Полируем ржавчину

Смотреть можно здесь:

GitHub - nandakoryaaa/rust-apple: Rust adaptation of "Apple" game from BK-0010

Правда, не совсем доделал. Нужна ещё музыка, но я не хочу просто проигрывать внешний WAV-файл, так как оригинальная игра этого не делает. Я попробую сделать генерацию звука программно, как положено. Но это на потом.

Текущая версия полностью функциональна.

Разберём, что и как в ней получилось.

Объём кода составил 48 килобайт. С одной стороны, для языка высокого уровня это немного, но с другой подобную игру можно уложить наверное в один килобайт (не считая графики). Что же помешало?

Как я и писал изначально, я делал не одну игру, а скорее архитектуру под неё и другие игры. Соответственно, архитектура получилась такая:

MVC

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

-2

Далее, у каждой активности есть своё представление: в заставке рисуется логотип, в меню меню, в игре игровой уровень и т.д. Соответственно, каждое представление представлено своим объектом.

Наконец, у каждой активности есть своя модель данных.

-3

Игра эмулирует экран БК-0010, который имеет разрешение 256*256 пикселов. При этом реальный экран игры имеет разрешение 1024*768. А собственно логика игры (движения человека и яблока) происходит в сетке 32*32.

Контроллер ничего не знает о графике и работает только с сеткой и с габаритами объектов в единицах сетки. Поэтому, например, для контроллера игрок смещается не на 8 пикселов, а на 1 ячейку сетки. Представление работает с виртуальным БК-экраном 256*256 пикселов, переводя объекты из координат сетки в координаты виртуального экрана. И наконец компонент сцены (Stage) рисует объекты с помощью SDL2, перенося их в координаты реального экрана, при этом каждый пиксел становится размером 4*3 (у БК в цветном режиме пикселы не квадратные).

Абсолютно всё рисование делается цветными прямоугольниками, битмапов и блиттинга как таковых нет.

Управление

Контроллер опять же не знает о том, как физически устроено управление, клавиатура это или что-то другое. Вместо этого есть компонент Input, который может обрабатывать события от физической клавиатуры или от чего-то ещё, и генерировать уже собственные события стандартного вида, которые понятны контроллеру.

Например, на входе Input получает событие "нажата стрелка влево", а на выходе он отдаёт контроллеру уже собственное событие "активно движение влево", так что контроллер не должен думать, это была клавиатура или что-то ещё, у него есть готовый и понятный ему результат.

При этом у каждого контроллера может быть собственный компонент Input, который обрабатывает события специально для него.

Например, у контроллера, отвечающего за заставку, Input принимает нажатие любой клавиши, а порождает единственное событие GameStateEvent::Continue, то есть продолжить. Тот же самый Input работает в конце игры, где также ожидается нажатие любой клавиши. А вот во время игры подставляется другой Input, который различает нажатия стрелок и генерирует разные события.

-4

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

Ну, остальное уже обсуждалось в предыдущих частях.

Я рад, что наконец-то можно перейти к другим проектам. И особенно рад, что они будут не на Rust (Пирог заждался, например).