在java中分离逻辑和GUI

OiR*_*iRc 10 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();
         }
      
      }
      
      Run Code Online (Sandbox Code Playgroud)
  • 游戏管理

    • 我让这个课程控制游戏的每个方面(更新,图形)

      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);
           }
      }
      
      Run Code Online (Sandbox Code Playgroud)
  • 游戏状态

    • GameState是一个抽象类,它接收构造函数参数作为GameManager的一个实例,它在每个GameState (Menu,Game,MultiPlayer等)中实现了抽象方法.

    • 这个类有这些抽象方法:

      • controller() - >验证状态逻辑

      • update() - >如果currentState是一个MultyPlayer,这个方法调用类Player等的update方法...

      • draw(Graphics g) - > draw to screen the currentState的对象

我想过制作一个实用程序类单例,它实现了每个状态的所有draw(),但是在单个类中插入all是非常讨厌的.

例:

而不是打电话给gameState.draw(graphic);我称Render.getRenderInstance().draw(graphic,gameState); 这个解决方案有效,但我不喜欢它.

那么如何以一种漂亮的方式将draw方法与其余逻辑分开呢?

一些忠告?谢谢.

luk*_*985 3

通常的做法是将游戏分为两部分:

  • 逻辑,在你的情况下看起来没问题

  • 场景,事物被绘制的地方

下面是我的伪代码:

the main loop:
  gamestate.update()
  scene.render();
Run Code Online (Sandbox Code Playgroud)

在场景中你应该有所有的图形操作。您应该能够使用类似于以下的调用将新图形添加到场景中:

scene.addObject(SomeGraphic graphic);
Run Code Online (Sandbox Code Playgroud)

因此场景会在每次主循环迭代时渲染该图形。

为了实现这种情况,您应该在 Scene 类中保留一个列表或另一个集合,并在每个刻度时渲染每个对象。所以实际的 scene.render() 看起来像这样:

public void render() {
  for(SomeGraphic graphic : objects) {
    graphic.draw()
  }
}
Run Code Online (Sandbox Code Playgroud)

然后,您将能够通过游戏逻辑控制场景中的内容 - 您将能够添加和删除对象等。