设计一个mvc卡牌游戏。

3

我正在尝试使用MVC模式创建一个回合制卡牌游戏。我对正确的设计有一些疑问。

我创建了由以下类组成的模型:

  • Card (使用Suit)
  • Deck (40张牌, 抽取牌的方法, 剩余牌数)
  • Table
  • Suit (枚举)
  • Player(手牌, 玩家名称, 手牌数量, 搜集到的卡牌)
  • GameModel (包含对Deck、Table的引用,并在构造函数中接收两个玩家对象)

当用户按下“新游戏”按钮时,我将创建两个Player对象和GameModel(计算机和玩家)。这是正确的方式吗?(我想我不需要策略模式)

我创建了一个GameController类,该类具有对GameModel类和GameFrame(视图)类的引用。

当电脑在进行游戏或有人赢得手牌并拿起桌子上的牌时,我需要实现某种形式的“暂停”,所以我想我需要创建一个带有游戏循环的Runnable类。正确吗?

这些类应该如何互动? (这样的英语是否正确?xD)

玩家操作示例:

点击卡牌按钮 --> actionListener --> 调用GameController方法以检查操作是否可行(轮到我并可以出牌,电脑已出牌) --> 如有可能,GameController将更新GameModel --> GameLoop注意到GameModel的变化,并调用一些UI方法来升级视图(使用一些Thread.sleep(...))。这有用吗?

但在所有这些中,我应该把AI放在哪里? 谢谢你的帮助 :)


你可能想把这个问题转移到http://programmers.stackexchange.com/。 - merours
@fxm 为什么不使用http://gamedev.stackexchange.com? - Val
谢谢,我不知道这个网站。 - Loris
@val也可以,但在我看来,软件架构问题更适合属于第一个(主观意见,这点我承认 :)) - merours
实际上,这是 http://gamedev.stackexchange.com/questions/74346 的副本。 - Val
1个回答

3
这不是只有一种答案的问题。您想让它成为单人玩家还是多人玩家游戏?对于单人玩家游戏,您可能不需要任何线程。我建议从以下几点开始:
  • 您的游戏循环应该放在GameController中。类似这样:while(gameNotFinished()) { player = determineNextPlayer(); player.makeTurn(); }
  • 添加另一个MVC层次结构:PlayerView,PlayerController和PlayerModel。这将使您的代码更加易读。在这种情况下,PlayerController(带有makeTurn())可以是一个接口,因此您可以使用HumanPlayerController和ComputerPlayerController来实现它(后者没有视图并且不需要视图)。
  • GameController实现ActionListener:因此,您只需将控制器添加到每个按钮或其他任何您拥有的东西中,然后它将处理用户输入。
  • 确保您不会将控制代码编写到视图中。视图仅将用户请求发送到控制器
  • 使用观察者模式进行查看和模型。请参见java.util.Observer和java.util.Observable。当模型发生更改(例如放置卡片)时,它会通知观察者(所有视图),然后视图会在其上获取新卡片。

这是正确的进行方式吗?
我不明白为什么“新游戏”按钮和您描述的操作会有问题。也许考虑在此操作中“重置”一切,以便玩家可以随时按下该按钮。

当计算机在玩耍时需要一种“暂停”吗?
您想等待额外的时间直到计算机玩家完成他的回合吗?我会说让他尽可能快地玩。只要人类玩家完成回合游戏就可以继续。

这可行吗?
我会将其更改为以下内容:
单击卡按钮--> GameController(是ActionListener)-->检查操作是否可行的方法(我的回合和我可以玩,计算机已经玩过了可以放置卡片。当控制器为您的回合时,请禁用卡片按钮,makeTurn()将再次启用它)-->如果可能,GameController更新GameModel--> GameModel通知所有观察者(视图),然后它们得到更新

我应该把AI放在哪里?
如上所述,靠近HumanPlayerController实现PlayerController接口。


目前游戏将非常简单,人类对抗电脑,没有多人游戏。当电脑或用户已经玩过时,我需要“暂停”,并且有必要确定谁赢了这一手,否则用户将无法理解。无论如何,感谢您的建议,这可能是一个不错的开始,但并非游戏的所有动作都可以瞬间完成。 - Loris
在一个可运行的程序之外使用“Thread.sleep(...)”是安全的吗?我不想冒着冻结视图的风险。但是,我注意到你上面写了“GameModel implements ActionListener”。也许你想说的是“GameController”而不是“GameModel”?另外,我的GameController类是单例模式。 - Loris
1
当然,GameController 实现了 ActionListener(已修复)。是的,你是对的,Thread.sleep() 可能会导致问题。我找到了这个解释这个问题的问题:https://dev59.com/FGzXa4cB1Zd3GeqPVZgB - Thomas
1
makeTurn()函数要么启用人类玩家视图中的按钮,要么只是在GameController中设置一个布尔值,以防止视图中的ActionEvents实际执行任何操作。 - Thomas
1
是的,视图只与它自己的控制器通信,这主要通过 ActionEvents(也可以是其他事件类型)来实现。我发现这篇关于分层MVC的文章非常有用:http://www.javaworld.com/article/2076128/design-patterns/hmvc--the-layered-pattern-for-developing-strong-client-tiers.html - Thomas
显示剩余4条评论

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