Отдельная логика и GUI в java
Я реализую игру на Java, используя приведенные ниже классы для управления логикой игры. Я стараюсь быть предельно ясным, когда объясняю свой вопрос.
-
GamePanel
-
Я использую этот класс для запуска игрового цикла с потоком (только игровой цикл)
public void run() {
init(); //initialize gamePanel components
// game loop
while (running) {
start = System.nanoTime();
gameManager.update();
KeyInput.update();
MouseInput.update();
gameManager.draw(graphic);
Graphics g2 = getGraphics();
g2.drawImage(image, 0, 0, null);
g2.dispose();
elapsed = System.nanoTime() - start;
wait = targetTime - elapsed / 1000000;
if (wait < 0)
wait = 5;
try {
Thread.sleep(wait);
} catch (Exception e) {
e.printStackTrace();
}
}
-
GameManager
-
Я сделал этот класс для управления каждым аспектом игры как (обновление, графика)
private void loadState(int state) {
if (state == States.MENU.getValue())
gameState = new Menu(this);
else if (state == States.GAME.getValue())
gameState = new Game(this);
else if (state == States.PATHSELECT.getValue())
gameState = new SelectPath(this);
}
public void update() {
if (gameState != null)
gameState.update();
}
public void draw(java.awt.Graphics2D graphic) {
if (gameState != null)
gameState.draw(graphic);
else {
JOptionPane.showMessageDialog(null, JOptionPane.ERROR_MESSAGE);
}
}
-
GameState
-
GameState - абстрактный класс, который получает в качестве параметра конструктора экземпляр GameManager и имеет абстрактные методы, реализованные в каждом GameState (меню, игра, мультиплеер и т.д.).
-
Этот класс имеет эти абстрактные методы:
-
controller() → , которые проверяют логику состояния
-
update() → в случае, если currentState является многопользовательским, этот метод вызывает метод обновления класса Player и т.д.
-
draw (Graphics g) → рисовать для экранирования объектов currentState
Я думал о создании одноуровневого класса утилиты, который реализует все draw() каждого состояния,
но очень неприятно вставлять все в один класс.
Пример:
вместо вызова gameState.draw(graphic);
Я вызываю Render.getRenderInstance().draw(graphic,gameState);
эти решения работают, но мне это не нравится.
Итак, как можно красиво разделить метод draw от остальной логики?
Некоторые советы? Спасибо.
Ответы
Ответ 1
Обычный подход состоит в том, чтобы разделить игру на две части:
-
логика, которая выглядит как ОК в вашем случае
-
сцена, где рисуются предметы
Здесь, в псевдокоде, я это делаю:
the main loop:
gamestate.update()
scene.render();
В сцене вы должны иметь все графические операции. Вы можете добавить новую графику в сцену, используя вызов, подобный этому:
scene.addObject(SomeGraphic graphic);
Таким образом, сцена сделает визуализацию каждой основной итерации цикла.
Чтобы это произошло, вы должны хранить список или другую коллекцию внутри класса Scene и каждый раз показывать каждый объект. Таким образом, actall scene.render() будет выглядеть так:
public void render() {
for(SomeGraphic graphic : objects) {
graphic.draw()
}
}
Затем вы сможете контролировать то, что находится на сцене из логики игры - вы сможете добавлять и удалять объекты и т.д.