【问题标题】:MVC in a simple Java game?一个简单的Java游戏中的MVC?
【发布时间】:2011-01-03 18:09:35
【问题描述】:

嘿,我正在用 Java 实现一个 简单 Breakout 克隆,并尝试使其符合 MVC 模式。我承认,我来自网络背景,只在 Php 框架 Symfony 中使用过 MVC,从未在桌面应用程序中使用过。所以我的问题是决定哪个实体负责哪些任务。

我将我的项目分为以下几类:

  • Breakout extends JFrame(主类)启动 MainViewController 并将其视图添加到内容窗格。
  • MainViewController extends TimerTask 启动 MainView 并处理其鼠标和键盘事件。还运行游戏循环(计算游戏对象的位置和状态,即BallPaddleBricks),是不是在这个地方?
  • MainView extends JPanel 只是在屏幕上绘制BallPaddleBricks,这里没有逻辑。但是,它也会启动这些对象。恐怕这不正确吧?

最后是游戏元素:

  • Ball extends Ellipse2DPaddle extends Rectangle2DBrick extends Rectangle2D 提供了在屏幕上移动它们的方法,但也在这里完成了碰撞检测。再次,我怀疑这是正确的位置,将其移至控制器?

模型是什么?我想,正是这些游戏元素,因为它们代表了游戏期间唯一更改的数据。但这些都是控制器元素,因为它们也提供碰撞检测逻辑。它们最好的一点是,它们是在 view 类中启动的。我敢肯定,我的设计决策出了点问题。

【问题讨论】:

    标签: java model-view-controller


    【解决方案1】:

    开发游戏是一个有点不同的概念,但仍然是一个 MVC。

    您的模型是游戏的实体,例如球、桨和砖。

    一个游戏是基本的三个步骤。

    1° 读取输入(你的 ViewController 计算)

    2° Process Pieces AI(喜欢行为并使用来自控制器的新值移动)

    3° 在屏幕上绘制(您在屏幕上绘制所有实体)

    在第一步中,如果用户输入左或右,您应该使用这些值更新桨实体。

    应该在第二步中测试碰撞,以你的例子来说,球应该测试它是否与任何砖块或桨相交以击退,球不需要用户动作来移动,所以它应该不断移动某个方向,直到它相交。

    第三步只是在屏幕上绘制所有元素。

    游戏的第一个对象应该在 View init 中的 setup() 方法中创建,其他对象(例如划桨射击或从碎砖上掉落的特殊奖励)应该在第二步中创建,在桨的情况下,控制器应该告诉桨用户按下按钮进行射击,在您创建射击实体并将其添加到实体游戏循环的过程中,与砖相同,但是当它创建奖励时注意它被破坏了。

    【讨论】:

    • 是的,谢谢你的回答!一个问题:你的意思是我应该只通知桨叶按下了特定的按钮,还是我解释了控制器中已经存在的事件?我的意思是paddle.buttonPressed() 还是paddle.shoot()?桨如何与控制器通信?我想,我必须将控制器设置为桨对象的委托。这真的是个好设计吗?
    • 我看不出有任何理由通知控制器。你应该这样做: //在控制器上 public void actionPerformed(MouseEvent evt){ paddle.notifyMove(evt.getX(), evt.getY()); //if a click paddle.shoot() } 但你实际上只是在 processAI 中创建了镜头。因为你的游戏循环不能在输入步骤中创建对象,(可能你会得到一个 ConcurrentCollectionModificationException 因为你的线程事件会与可以运行的进程重叠,你永远不会知道)
    【解决方案2】:
    • 我会切换 Breakout 和 MainViewController。让控制器启动视图。
    • 您的模型实际上是 Ball、Paddle 和 Bricks,所以我认为 MainViewController 应该创建它们而不是 MainView。
    • 否则我不会强调模型的某些父类具有对绘制有用的方法。这不是视图和模型的完美分离,但它保持简单。

    【讨论】:

    • 如果您计划实现多个布局,模型也可以是关卡。这没有在这里解决,但我想我会把它扔在那里。
    • 感谢您的回答! 1) 我想我可以忍受 Breakout 是一个 JFrame,如果这是你的意思的话。 2)是的,我同意。我只是在视图中创建它们,因为我认为它们是从 Rectangle2D 派生的视图对象。您建议如何将它们传递给视图?调用 view.repaint() 时?也许将此方法重载为 view.repaint(paddle, ball, bricks) 之类的方法? @Riggy:好主意,谢谢!所以关卡包含它的所有对象(桨、球、..)?
    • @nubbel 就将模型传递给视图而言,MainView 类可以在构造函数或单独的方法中接收引用。
    猜你喜欢
    • 2016-02-16
    • 1970-01-01
    • 1970-01-01
    • 2012-09-20
    • 2012-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多