OO游戏设计问题

6
我正在用Java编写一个简单的游戏,但我想以良好的设计和没有黑客技巧的方式完成。我有两个类GamePanel接收点击和按键事件,Model包含所有实体并负责它们的更新。模型需要知道用户的鼠标位置,但我无法决定正确的方法。
应该让Model和每个Entity保留对GamePanel的引用,还是只缓存最后已知的鼠标位置,并定期从GamePanel接收更新?使用第一种选项时,当创建模型时,需要给它一个对GamePanel的引用;使用第二种选项时,最后的鼠标位置将作为参数发送到World.update()方法中。
这些解决方案都不太优雅,所以我想知道是否有我错过的“正确”方法。
谢谢, Ben。

所以我猜大家的共识是,如果只偶尔需要鼠标位置,可以使用观察者或事件监听器;而如果在大多数更新中都需要鼠标位置,则将模型与面板关联起来,以便能够轮询它。 - Ben Page
5个回答

3
在我看来,这将取决于你的类如何交互。改变鼠标位置是否会触发Model类中的实体?还是Model类独立于GamePanel,并仅在当前鼠标位置值上工作?
如果是后者,在这种情况下,我同意Jeff之前所说的。在创建Model类时,将GamePanel的句柄传递给它,并让每个实体使用该句柄在需要时访问鼠标位置。这样,始终使用更新后的鼠标位置。
如果是前者,我建议使用观察者模式,让Model类知道鼠标位置值何时发生了变化。然后,Model类可以使用相同的设计(即始终让Model类拥有GamePanel类的句柄)并访问GamePanel中的当前值。
总之,我认为让GamePanel保存鼠标位置的值,并使用GamePanel实例让其他类访问该信息符合OO概念和逻辑。
谢谢, Rohan.

3

一种常见的解决方案是触发事件。在这种情况下,GamePanel会触发一个事件,通知Model中所有感兴趣的对象(已订阅该事件),新鼠标位置的信息。

这样,GamePanel不需要明确知道要通知哪些实体,而实体也不需要保留GamePanel的实例。

我的建议:详细了解事件监听器。(Java.util)


Java.util 是什么意思?鼠标事件和监听器在 java.awt.event 包中。 - akarnokd
1
你们两个都是正确的。java.awt.event.MouseListener扩展了java.util.EventListener(http://java.sun.com/javase/6/docs/api/java/util/EventListener.html)。 - Nelson
我想象中的情况是OP没有使用awt或swing,所以我指向了util。 - NomeN

2
您可以将当前坐标设置为GamePanel的公共属性,这样Entitys/Models就可以从那里轻松访问它。请保留HTML标记。

1
如果您想轮询当前鼠标位置,您可以随时在事件分派线程中运行此代码片段:
Point pt = MouseInfo.getPointerInfo().getLocation();
Point cpt = GamePanel.getLocationOnScreen();
Point rel = new Point(pt.x - cpt.x, pt.y - cpt.y);

rel 包含鼠标的相对位置。

或者,您可以查看 JInput,因为它专门处理键盘/鼠标/任何输入。


1

模型是否总是需要知道鼠标的位置。即:您是否需要在每次更新时获取鼠标位置,还是仅在特定点获取。

如果需要在每个点或每次更新期间使用它,则您已记录的任何解决方案或此处的任何解决方案都应该很好。

如果您只需要在特定点使用它,请仅获取该点。 (即:如果您的游戏响应鼠标单击,请在单击时执行某些操作。)意味着阅读有关事件侦听器的信息。

祝你好运!希望能帮到您。


有一种情况可以使用基于轮询的方法 - 如果您不想在“拖动”鼠标时与“鼠标拖动”事件作斗争(例如射击和转向)。 - akarnokd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接