在OS-X的Objective-C / Cocoa中使用游戏,我完成了原型,因为它值得完成。这是一堆乱七八糟的代码,是我的第一款游戏,但一切正常。我一直在阅读将事情放在一起的最佳方式,而MVC似乎最有意义,但我有点困惑。
从哪里开始?用控制器?这似乎对我来说最有意义,但它是如何开始的?在我的原型混乱中,我从视图的init
开始,从那里开始。我是否会对控制器执行相同操作,并将init
中需要的内容放入其中?或者还有什么我可以用来做这个?如果它是从init
开始的,我如何init
控制器?
我如何建立游戏世界?我目前使用两个阵列,一个用于世界(墙壁,地板,门,水,熔岩等),一个用于项目(我将为角色添加第三个)。加载地图(.plist),然后创建对象并将其添加到它所属的数组中。阵列在哪里?在原型中,它们也是视图的一部分,所以我想你可以说我将两者(视图和控制器)结合在一起。是否会为每个地图创建一个Map对象?是否会有包含所有地图的Maps对象?
它们如何一起工作?玩家按下一个键,在游戏中移动角色。视图将处理输入,对吗?你会把它发送到控制器,它会检查地图/其他数组中的所有东西(墙壁,怪物等),然后返回结果吗?或者你会把它发送到播放器,它会转到控制器,它会做所有的检查,然后返回结果?
我以为我把它放在脑子里很漂亮,但我想的越多,我的想法越不固定,我就越困惑。如果您认为可以更有效地获得重点,请务必毫不犹豫地画出一些东西。
如果您花时间阅读所有这些内容,请感谢您的耐心等待。从我收集到的,大多数编写代码的人都不使用任何设计。在阅读完这篇文章后,我可以看到为什么有些人会避免它,这让人感到困惑,人们似乎认为这不值得花时间。我个人认为这些优点完全超出了缺点(有没有?)而且只有在每次想要实现新功能时都不需要完全重写的情况下保持组织有意义才有意义。你不会在没有设计的情况下建造房屋,汽车或设备,为什么你会在没有设计的情况下编写一个复杂的程序呢?
我问了这个问题,因为我想以正确的方式做到这一点,而不是通过黑客攻击和半途径来实现“胜利”。
答案 0 :(得分:17)
答案 1 :(得分:7)
似乎您的主要困惑是在应用启动期间如何构建事物。很多人都对此感到困惑,因为感觉就像是魔术正在发生,但让我看看是否可以将其分解。
请注意,应用程序委托在NSApplication(子)类之前初始化。这就是为什么应用程序(Will | Did)FinishLaunching:接受通知而不是NSApplication它是委托。
这样做的一般结果是您的视图是通过nibs为您创建的,并且您的控制器是作为nib启动的副作用而创建的,因为它们往往是nib中的根级对象,或者是nib的File's Owners。您的模型通常是在应用程序委托中创建的,或者是在首次访问它时被懒惰地初始化的单例。
答案 2 :(得分:4)
你应该为整个游戏创建一个模型。除了GUI交互之外,它应该包含有关游戏的所有内容。另一方面,视图包含所有GUI内容,而不了解游戏流程。
重点是模型和视图预计可以重复使用。模型类应该与任何GUI(甚至可能是控制台或命令行)一起使用。视图类应该能够与其他类似的游戏一起使用。模型和视图应该完全分离。
然后,控制器填补了空白。它响应用户输入,要求模型类执行特定的游戏移动,并要求视图显示新的情况。控制器预计不可重复使用。它是将游戏结合在一起的粘合剂。控制器确保模型类和视图类保持独立且可重用。
此外,不要试图从一开始就使设计完美。不要犹豫,随时重构。糟糕的设计决策得到纠正的速度越快,它就越不邪恶。预先设计所有内容意味着根本不会纠正糟糕的设计决策,除非您提前完成一个完美的设计,即使拥有数十年的经验,这也是不可能的。
永远记住X Window系统的第三个设计规则:“唯一比通过一个例子推广更糟糕的事情就是从没有例子推广出来。”
答案 3 :(得分:0)
对于您的游戏,模型将包括角色的当前位置,健康点的数量以及涉及游戏“状态”的其他值。它会在发生变化时通知视图,以便视图可以自行更新。视图只是向用户显示所有内容所需的代码。控制器负责响应用户输入,并在必要时更新模型。
控制器是其中的核心组件,它应该实例化模型和视图。
当玩家按下某个键时,视图应该只是将该命令传递给控制器,控制器决定该做什么。
你错了,大多数人都没有设计。也许是大多数业余爱好者,或者也许是那些在网上提出最多问题的人,但也许没有任何人在一个甚至有点复杂的项目上工作。专业程序员都具有软件设计经验;没有它,他们实际上将无法完成他们的工作(编写软件来做X)。
你的游戏听起来很复杂,足以保证像MVC这样的架构模式。在某些情况下,一个软件很简单,MVC过度使用并且不必要地使事情变得复杂,但使用MVC的门槛非常低。
答案 4 :(得分:0)
您可能会发现这篇文章Introduction to MVC design using C#很有用。虽然示例是在C#中,但原则应该适用。