Я работаю над простой блочной игрой-головоломкой.
Игровой процесс состоит в основном из перемещения блоков в игровой зоне, так что это тривиальная физическая симуляция. Моя реализация, однако, на мой взгляд, далека от идеала, и мне интересно, можете ли вы дать мне какие-либо советы о том, как сделать это лучше.
Я разделил код на две части: игровую логику и пользовательский интерфейс, как я делал во многих играх-головоломках:
- Логика игры отвечает за общие правила игры (например, формальная система правил в шахматах).
- Пользовательский интерфейс отображает игровую область и фигуры (например, шахматную доску и фигуры) и отвечает за анимацию (например, анимированное движение шахматных фигур)
Логика игры представляет игровое состояние в виде логической сетки, где каждая единица представляет собой ширину / высоту одной ячейки в сетке. Таким образом, для сетки шириной 6 вы можете перемещать блок шириной 2 четыре раза, пока он не столкнется с границей.
Пользовательский интерфейс берет эту сетку и рисует ее путем преобразования логических размеров в размеры в пикселях (то есть умножает их на константу). Однако, поскольку в игре почти нет игровой логики, мой уровень игровой логики [1] не имеет ничего общего, кроме обнаружения столкновений. Вот как это работает:
- Игрок начинает перетаскивать фигуру
- Пользовательский интерфейс запрашивает игровую логику для области легального перемещения этой фигуры и позволяет игроку перетащить ее в эту область
- Игрок отпускает кусок
- Пользовательский интерфейс привязывает кусок к сетке (чтобы он находился в правильной логической позиции)
- Пользовательский интерфейс сообщает игровой логике новую логическую позицию (с помощью методов-мутаторов, которых я бы предпочел избежать)
Я не совсем доволен этим:
- Я пишу юнит-тесты для своего игрового уровня логики, но не для пользовательского интерфейса, и оказалось, что весь хитрый код в пользовательском интерфейсе: предотвращение столкновения части с другими или границей и привязка ее к сетке.
- Мне не нравится тот факт, что пользовательский интерфейс рассказывает игровой логике о новом состоянии, я бы предпочел, чтобы он вызывал
movePieceLeft()
метод или что-то в этом роде, как в других моих играх, но я не продвинулся далеко с этим подходом, потому что игровая логика ничего не знает о перетаскивании и привязке, которые возможны в пользовательском интерфейсе.
Я думаю, что лучше всего было бы избавиться от моего игрового логического слоя и вместо этого реализовать физический слой. У меня есть несколько вопросов по этому поводу:
- Является ли такой физический слой обычным, или это более типично, чтобы игровой логический слой делал это?
- Будет ли привязка к сетке и коду перетаскивания принадлежать пользовательскому интерфейсу или физическому слою?
- Будет ли такой физический слой работать с размерами пикселей или с какой-то логической единицей, например, с моим игровым логическим слоем?
- Однажды я видел обнаружение столкновений на основе событий в базе кода игры, то есть игрок просто перетаскивал фигуру, пользовательский интерфейс послушно отображал бы ее и уведомлял физическую систему, а физическая система вызывала метод onCollision (). на части, как только столкновение обнаружено. Что чаще встречается? Этот подход или просить области легального движения в первую очередь?
[1] слой , вероятно, не подходит для того, что я имею в виду, но подсистема звучит раздутой, а класс вводит в заблуждение, потому что каждый слой может состоять из нескольких классов.