如何才能最好地将OOP原则应用于游戏和其他输入驱动的GUI应用程序?

时间:2021-05-31 11:25:44

Whenever I try to write graphical programs (whether a game or really any GUI app) I always wind up with one or two god classes with way too many methods (and long methods, too), and each class having far too many responsibilities. I have graphics being done at the same time as calculations and logic, and I feel like this is a really bad way to go about organizing my code. I want to get better at organizing my code and abstracting out responsibilities to different classes. Here's an example of where I'd like to start - I want to write a Minesweeper clone, just sort of as practice and to try to improve my software engineering skills. How would I go about making this nice and object-oriented? For the sake of discussion, let's just say I'm using Java (because I probably will, either that or C#). Here's some things I would think about:

每当我尝试编写图形程序(无论是游戏还是任何GUI应用程序)时,总是会遇到一两个上帝类,方法太多(也有很长的方法),每个类都有太多的责任。我在计算和逻辑的同时完成了图形处理,我觉得这是一个非常糟糕的方法来组织我的代码。我想更好地组织我的代码并将责任抽象到不同的类。这是我想要开始的一个例子 - 我想写一个Minesweeper克隆,只是作为练习,并试图提高我的软件工程技能。我将如何使这个漂亮和面向对象?为了便于讨论,我们只是说我正在使用Java(因为我可能会使用Java或C#)。这是我想到的一些事情:

  • should each tile inherit from JButton or JComponent and handle drawing itself?
  • 每个tile应该从JButton还是JComponent继承并处理绘图本身?

  • or should the tiles just be stored as some non-graphical MinesweeperTile object and some other class handles drawing them?
  • 或者瓷砖是否应该存储为一些非图形化的MinesweeperTile对象以及其他一些类处理它们?

  • is the 8-segment display countdown timer (pre-Vista, at least) a separate class that handles drawing itself?
  • 8段显示倒数计时器(至少在Vista之前)是一个单独的类来处理绘图本身?

  • when the user clicks, do the tiles have mouse event listeners or does some other collision detection method loop through the tiles and check each one to see if it's been hit?
  • 当用户点击时,瓷砖是否有鼠标事件监听器,或者是否有其他一些碰撞检测方法在瓷砖上循环并检查每个瓷砖以查看它是否被点击?

I realize that there's not just one way to write a GUI application, but what are some pretty basic things I can start doing to make my code more organized, manageable, object-oriented, and just over all write better programs?

我意识到编写GUI应用程序不仅仅有一种方法,但是我可以开始做些什么非常基本的事情来使我的代码更有条理,更易于管理,面向对象,而且只是编写更好的程序?


edit: I guess I should add that I'm familiar with MVC, and I was originally going to incorporate that into my question, but I guess I didn't want to shoehorn myself into MVC if that's not necessarily what I need. I did searched for topics on MVC with GUI apps but didn't really find anything that answers my specific question.

编辑:我想我应该补充一点,我对MVC很熟悉,而且我原本打算将其纳入我的问题,但我想我不想把自己搞砸到MVC,如果那不一定是我需要的。我确实用GUI应用程序搜索了MVC的主题,但没有真正找到任何能够回答我特定问题的内容。


edit2: Thanks to everyone who answered. I wish I could accept more than one answer..

edit2:感谢所有回答的人。我希望我能接受不止一个答案..

6 个解决方案

#1


Here is a simple (but effective) OO design to get you started:

这是一个简单(但有效)的OO设计,可以帮助您入门:

First create a Game object that is pure Java/C# code. With no UI or anything else platform specific. The Game object handles a Board object and a Player object. The Board object manages a number of Tile objects (where the mines are). The Player object keeps track of "Number of turns", "Score" etc. You will also need a Timer object to keep track of the game time.

首先创建一个纯Java / C#代码的Game对象。没有UI或任何其他平台特定的。 Game对象处理Board对象和Player对象。 Board对象管理许多Tile对象(地雷所在的地方)。 Player对象跟踪“Number of turn”,“Score”等。您还需要一个Timer对象来跟踪游戏时间。

Then create a separate UI object that doesn't know anything about the Game object. It is completely stand alone and completely platform dependent. It has its own UIBoard, UITile, UITimer etc. and can be told how to change its states. The UI object is responsible for the User Interface (output to the screen/sound and input from the user).

然后创建一个单独的UI对象,该对象对Game对象一无所知。它完全独立,完全依赖于平台。它有自己的UIBoard,UITile,UITimer等,可以告诉它如何改变它的状态。 UI对象负责用户界面(输出到屏幕/声音和用户输入)。

And finally, add the top level Application object that reads input from the UI object, tells the Game what to do based on the input, is notified by the Game about state changes and then turns around and tells the UI how to update itself.

最后,添加从UI对象读取输入的*Application对象,根据输入告知Game要做什么,由Game通知状态更改然后转向并告诉UI如何更新自身。

This is (by the way) an adaption of the MVP (Model, View, Presenter) pattern. And (oh by the way) the MVP pattern is really just a specialization of the Mediator pattern. And (another oh by the way) the MVP pattern is basically the MVC (Model, View, Control) pattern where the View does NOT have access to the model. Which is a big improvement IMHO.

这是(顺便说一下)MVP(模型,视图,演示者)模式的适应。而且(顺便说一句)MVP模式实际上只是Mediator模式的一个特化。而且(顺便说一句哦)MVP模式基本上是MVC(模型,视图,控制)模式,其中View无法访问模型。这是一个很大的改进恕我直言。

Have fun!

#2


use a MVC framework that handles all the hard organization work for you. there's a ton of MVC framework topics on SO.

使用MVC框架来处理所有硬组织工作。 SO上有大量的MVC框架主题。

using high quality stuff written by others will probably teach you faster - you will get further and see more patterns with less headache.

使用其他人写的高质量的东西可能会更快地教你 - 你会进一步看到更多的模式,减少头痛。

#3


I'm not suggesting this is the only way to do it, but what I would suggest is something like the following. Other people, please feel free to comment on this and make corrections.

我并不是说这是唯一的方法,但我建议的是以下内容。其他人,请随时对此发表评论并进行更正。

  • Each tile should inherit from something and handle drawing itself. A button seems like the best solution because it already has the button drawing functionality (pressed, unpressed, etc) built in.
  • 每个tile应该从某些东西继承并处理绘图本身。按钮似乎是最好的解决方案,因为它已经内置了按钮绘图功能(按下,未按下等)。

  • Each tile should also be aware of its neighbors. You would have eight pointers to each of its eight neighbors, setting them to null of course if there is no neighbor. When it goes to draw, it would query each neighbor's IsMine() function and display the count.
  • 每个瓦片也应该知道它的邻居。如果没有邻居,你可能会有八个指向其八个邻居的八个指针,当然将它们设置为null。当它进行绘制时,它将查询每个邻居的IsMine()函数并显示计数。

  • If none of its neighbors are a mine, it would then recurse into each neighbor's Reveal() method.
  • 如果它的邻居都不是我的,那么它会递归到每个邻居的Reveal()方法中。

  • For the 7-segment display, each digit is its own class that handles drawing. Then I would make a CountdownSegmentDigit class that inherits from this class, but has additional functionality, namely CountDown(), Set(), and Reset() methods, as well as a HitZero event. Then the display timer itself is a collection of these digits, wired up to propagate zeroes left. Then have a Timer within the timer class which ticks every second and counts down the rightmost digit.
  • 对于7段显示,每个数字都是它自己的处理绘图的类。然后我将创建一个继承自此类的CountdownSegmentDigit类,但具有其他功能,即CountDown(),Set()和Reset()方法,以及HitZero事件。然后显示计时器本身就是这些数字的集合,连接起来向左传播零。然后在计时器类中有一个Timer,它每秒都会滴答,并向下计数最右边的数字。

  • When the user clicks, see above. The tile itself will handle the mouse click (it is a button after all) and call its Reveal() method. If it is a mine, it will fire the MineExploded event, which your main form will be listening to.
  • 用户点击时,请参阅上文。磁贴本身将处理鼠标单击(毕竟它是一个按钮)并调用其Reveal()方法。如果它是我的,它将触发MineExploded事件,您的主要表单将听取。

For me, when I think of how to encapsulate objects, it helps to imagine it as a manufacturing process for physical parts. Ask yourself, "How can I design this system so it can be most efficiently built and reused?" Think about future reuse possibilities too. Remember the assembly process takes small pieces and builds them up into larger and larger pieces until the entire object is built. Each bit should be as independent as possible and handle its own logic, but be able to talk to the outside world when necessary.

对我来说,当我想到如何封装对象时,有必要将其想象为物理零件的制造过程。问问自己,“我如何设计这个系统,以便最有效地构建和重用它?”考虑未来的重用可能性。请记住,装配过程需要很小的部分,然后将它们构建成更大和更大的部分,直到构建整个对象。每个位应尽可能独立并处理自己的逻辑,但必要时能够与外界通信。

Take the 7-segment display bit, you could have another use for it later that does not count down. Say you want a speedometer in a car or something. You will already have the digits that you can wire up together. (Think hardware: stock 7-segment displays that do nothing but light up. Then you attach a controller to them and they get functionality.)

拿7段显示位,稍后可以再使用它,不会倒计时。假设你想要一辆汽车或其他什么的车速表。您已经拥有可以连接在一起的数字。 (想想硬件:库存7段显示器除了点亮之外什么都不做。然后你将一个控制器连接到他们身上并获得功能。)

In fact if you think hard enough, you might find you want CountUp() functionality too. And an event argument in HitZero to tell whether it was by counting up or down. But you can wait until later to add this functionality when you need it. This is where inheritance shines: inherit for your CountDownDigit and make a CountUpOrDownDigit.

事实上,如果你认真思考,你可能会发现你也想要CountUp()功能。在HitZero中有一个事件参数来判断它是通过向上还是向下计数。但是您可以等到以后在需要时添加此功能。这是继承发光的地方:继承您的CountDownDigit并创建一个CountUpOrDownDigit。

Thinking about how I might design it in hardware, you might want to design each digit so it knows about its neighbors and count them up or down when appropriate. Have them remember a max value (remember, 60 seconds to a minute, not 100) so when they roll over 0, they reset appropriately. There's a world of possibilites.

考虑如何在硬件中设计它,您可能想要设计每个数字,以便它知道它的邻居并在适当时向上或向下计数。让他们记住一个最大值(记住,60秒到一分钟,而不是100)所以当他们翻过0时,他们会适当地重置。有一个可能的世界。

#4


The central concern of a Graphic User Interface is handling events. The user does X and you need to response or not respond to it. The games have the added complexity in that it needs to change state in real time. In a lot of cases it does this by transforming the current state into a new state and telling the UI to display the results. It does this in a very short amount of time.

图形用户界面的核心问题是处理事件。用户执行X并且您需要响应或不响应它。游戏具有额外的复杂性,因为它需要实时改变状态。在很多情况下,它通过将当前状态转换为新状态并告诉UI显示结果来实现此目的。它在很短的时间内完成。

You start off with a model. A collection of classes that represents the data the user wants to manipulate. This could represent the accounts of a business or vast frontiers of an unknown world.

你从一个模型开始。表示用户想要操作的数据的类集合。这可能代表一个企业的帐户或未知世界的广阔前沿。

The UI starts with defining a series of forms or screens. The idea is that is for each form or screen you create a interface that defines how the UI Controller will interact with it. In general there is one UI Controller classes for each form or screen.

UI首先定义一系列表单或屏幕。我们的想法是,为每个表单或屏幕创建一个界面,定义UI控制器将如何与之交互。通常,每个表单或屏幕都有一个UI控制器类。

The form passes the event to the UI Controller. The UI Controller then decides which command to execute. This is best done through the Command design pattern where each command is it own class.

表单将事件传递给UI控制器。然后UI控制器决定执行哪个命令。这最好通过Command设计模式完成,其中每个命令都是它自己的类。

The Command then is executed and manipulate the model. The Command then tells the UI Controller that a screen or a portion of a screen needs to be redraw. The UI Control then looks at the data in the model and uses the Screen Interface to redraw the screen.

然后执行Command并操纵模型。然后,Command告诉UI控制器需要重绘屏幕或部分屏幕。然后,UI Control会查看模型中的数据,并使用屏幕界面重绘屏幕。

By putting all the forms and screen behind a interface you can rip out what you have and put something different in. This includes even not having any forms at all but rather mock objects. This is good for automated testing. As long as something implements the Screen Interface properly the rest of the software will be happy.

通过将所有表单和屏幕放在界面后面,您可以删除所拥有的内容并添加不同的内容。这包括甚至根本没有任何形式,而是模拟对象。这对自动化测试很有用。只要某些东西正确实现了屏幕界面,其余的软件就会很开心。

Finally a game that has to operate in real time will have a loop (or loops) running that will be continually transforming the state of the game. It will use the UI Controller to redraw what it updated. Commands will insert or change information in the model. The next time the loop comes around the new information will be used. For example altering a vector of a object traveling through the air.

最后,必须实时操作的游戏将有一个循环(或循环)运行,将不断改变游戏的状态。它将使用UI控制器重绘其更新的内容。命令将在模型中插入或更改信息。下一次循环出现时,将使用新信息。例如,改变穿过空中的物体的矢量。

I don't like the MVC architecture as I feel it doesn't handle the issues of GUIs well. I prefer the use of a Supervising Controller which you can read about here. The reason for this is that I believe automated tests are one of the most important tools you have. The more you can automate the better off you are. The supervising presenter pattern makes the forms a thin shell so there is very little that can't be tested automatically.

我不喜欢MVC架构,因为我觉得它不能很好地处理GUI的问题。我更喜欢使用监督控制器,你可以在这里阅读。这样做的原因是我相信自动化测试是您拥有的最重要的工具之一。您可以越多地自动化越好。监督演示者模式使表单成为一个薄壳,因此很少有自动测试。

#5


Sorry to say it, but it seems you have mess in your head trying to improve your coding too much in one step.

很抱歉这么说,但是你的脑子里似乎有点混乱,试图一步到位地改进你的编码。

There is no way to answer your question as such, but here we go.

没有办法回答你的问题,但我们走了。

First start with OOP, think about what objects are required for your game/GUI and start implementing them a little at a time, see if there are chances to break up these objects further, or perhaps reunite some objects that make no sense on their own, then try to figure out if you have repeated functionality among your objects, if you do, figure out if this repeated functionality is a (or many) base class or not.

首先从OOP开始,考虑游戏/ GUI需要什么对象,并开始一次实现它们,看看是否有可能进一步分解这些对象,或者重新组合一些自己没有意义的对象,然后尝试弄清楚你的对象中是否有重复的功能,如果你这样做,弄清楚这个重复的功能是否是一个(或许多)基类。

Now this will take you a few days, or weeks to really grok it well, then worry about dividing your logic and rendering.

现在这将花费您几天或几周的时间来真正理解它,然后担心划分您的逻辑和渲染。

#6


I have some tutorials that are written in C#. It discusses this very same topic. It is a starting point for a RogueLike game.

我有一些用C#编写的教程。它讨论了这个相同的主题。这是RogueLike游戏的起点。

Object Oriented Design in C# Converting Legacy Game

C#转换遗留游戏中的面向对象设计

Object Oriented Design: Domain Type Objects

面向对象设计:域类型对象

Object Oriented Design: Rethinking Design Issues

面向对象设计:重新思考设计问题

Object Oriented Design: Baby Steps in Acceptance Testing

面向对象设计:验收测试中的宝贝步骤

#1


Here is a simple (but effective) OO design to get you started:

这是一个简单(但有效)的OO设计,可以帮助您入门:

First create a Game object that is pure Java/C# code. With no UI or anything else platform specific. The Game object handles a Board object and a Player object. The Board object manages a number of Tile objects (where the mines are). The Player object keeps track of "Number of turns", "Score" etc. You will also need a Timer object to keep track of the game time.

首先创建一个纯Java / C#代码的Game对象。没有UI或任何其他平台特定的。 Game对象处理Board对象和Player对象。 Board对象管理许多Tile对象(地雷所在的地方)。 Player对象跟踪“Number of turn”,“Score”等。您还需要一个Timer对象来跟踪游戏时间。

Then create a separate UI object that doesn't know anything about the Game object. It is completely stand alone and completely platform dependent. It has its own UIBoard, UITile, UITimer etc. and can be told how to change its states. The UI object is responsible for the User Interface (output to the screen/sound and input from the user).

然后创建一个单独的UI对象,该对象对Game对象一无所知。它完全独立,完全依赖于平台。它有自己的UIBoard,UITile,UITimer等,可以告诉它如何改变它的状态。 UI对象负责用户界面(输出到屏幕/声音和用户输入)。

And finally, add the top level Application object that reads input from the UI object, tells the Game what to do based on the input, is notified by the Game about state changes and then turns around and tells the UI how to update itself.

最后,添加从UI对象读取输入的*Application对象,根据输入告知Game要做什么,由Game通知状态更改然后转向并告诉UI如何更新自身。

This is (by the way) an adaption of the MVP (Model, View, Presenter) pattern. And (oh by the way) the MVP pattern is really just a specialization of the Mediator pattern. And (another oh by the way) the MVP pattern is basically the MVC (Model, View, Control) pattern where the View does NOT have access to the model. Which is a big improvement IMHO.

这是(顺便说一下)MVP(模型,视图,演示者)模式的适应。而且(顺便说一句)MVP模式实际上只是Mediator模式的一个特化。而且(顺便说一句哦)MVP模式基本上是MVC(模型,视图,控制)模式,其中View无法访问模型。这是一个很大的改进恕我直言。

Have fun!

#2


use a MVC framework that handles all the hard organization work for you. there's a ton of MVC framework topics on SO.

使用MVC框架来处理所有硬组织工作。 SO上有大量的MVC框架主题。

using high quality stuff written by others will probably teach you faster - you will get further and see more patterns with less headache.

使用其他人写的高质量的东西可能会更快地教你 - 你会进一步看到更多的模式,减少头痛。

#3


I'm not suggesting this is the only way to do it, but what I would suggest is something like the following. Other people, please feel free to comment on this and make corrections.

我并不是说这是唯一的方法,但我建议的是以下内容。其他人,请随时对此发表评论并进行更正。

  • Each tile should inherit from something and handle drawing itself. A button seems like the best solution because it already has the button drawing functionality (pressed, unpressed, etc) built in.
  • 每个tile应该从某些东西继承并处理绘图本身。按钮似乎是最好的解决方案,因为它已经内置了按钮绘图功能(按下,未按下等)。

  • Each tile should also be aware of its neighbors. You would have eight pointers to each of its eight neighbors, setting them to null of course if there is no neighbor. When it goes to draw, it would query each neighbor's IsMine() function and display the count.
  • 每个瓦片也应该知道它的邻居。如果没有邻居,你可能会有八个指向其八个邻居的八个指针,当然将它们设置为null。当它进行绘制时,它将查询每个邻居的IsMine()函数并显示计数。

  • If none of its neighbors are a mine, it would then recurse into each neighbor's Reveal() method.
  • 如果它的邻居都不是我的,那么它会递归到每个邻居的Reveal()方法中。

  • For the 7-segment display, each digit is its own class that handles drawing. Then I would make a CountdownSegmentDigit class that inherits from this class, but has additional functionality, namely CountDown(), Set(), and Reset() methods, as well as a HitZero event. Then the display timer itself is a collection of these digits, wired up to propagate zeroes left. Then have a Timer within the timer class which ticks every second and counts down the rightmost digit.
  • 对于7段显示,每个数字都是它自己的处理绘图的类。然后我将创建一个继承自此类的CountdownSegmentDigit类,但具有其他功能,即CountDown(),Set()和Reset()方法,以及HitZero事件。然后显示计时器本身就是这些数字的集合,连接起来向左传播零。然后在计时器类中有一个Timer,它每秒都会滴答,并向下计数最右边的数字。

  • When the user clicks, see above. The tile itself will handle the mouse click (it is a button after all) and call its Reveal() method. If it is a mine, it will fire the MineExploded event, which your main form will be listening to.
  • 用户点击时,请参阅上文。磁贴本身将处理鼠标单击(毕竟它是一个按钮)并调用其Reveal()方法。如果它是我的,它将触发MineExploded事件,您的主要表单将听取。

For me, when I think of how to encapsulate objects, it helps to imagine it as a manufacturing process for physical parts. Ask yourself, "How can I design this system so it can be most efficiently built and reused?" Think about future reuse possibilities too. Remember the assembly process takes small pieces and builds them up into larger and larger pieces until the entire object is built. Each bit should be as independent as possible and handle its own logic, but be able to talk to the outside world when necessary.

对我来说,当我想到如何封装对象时,有必要将其想象为物理零件的制造过程。问问自己,“我如何设计这个系统,以便最有效地构建和重用它?”考虑未来的重用可能性。请记住,装配过程需要很小的部分,然后将它们构建成更大和更大的部分,直到构建整个对象。每个位应尽可能独立并处理自己的逻辑,但必要时能够与外界通信。

Take the 7-segment display bit, you could have another use for it later that does not count down. Say you want a speedometer in a car or something. You will already have the digits that you can wire up together. (Think hardware: stock 7-segment displays that do nothing but light up. Then you attach a controller to them and they get functionality.)

拿7段显示位,稍后可以再使用它,不会倒计时。假设你想要一辆汽车或其他什么的车速表。您已经拥有可以连接在一起的数字。 (想想硬件:库存7段显示器除了点亮之外什么都不做。然后你将一个控制器连接到他们身上并获得功能。)

In fact if you think hard enough, you might find you want CountUp() functionality too. And an event argument in HitZero to tell whether it was by counting up or down. But you can wait until later to add this functionality when you need it. This is where inheritance shines: inherit for your CountDownDigit and make a CountUpOrDownDigit.

事实上,如果你认真思考,你可能会发现你也想要CountUp()功能。在HitZero中有一个事件参数来判断它是通过向上还是向下计数。但是您可以等到以后在需要时添加此功能。这是继承发光的地方:继承您的CountDownDigit并创建一个CountUpOrDownDigit。

Thinking about how I might design it in hardware, you might want to design each digit so it knows about its neighbors and count them up or down when appropriate. Have them remember a max value (remember, 60 seconds to a minute, not 100) so when they roll over 0, they reset appropriately. There's a world of possibilites.

考虑如何在硬件中设计它,您可能想要设计每个数字,以便它知道它的邻居并在适当时向上或向下计数。让他们记住一个最大值(记住,60秒到一分钟,而不是100)所以当他们翻过0时,他们会适当地重置。有一个可能的世界。

#4


The central concern of a Graphic User Interface is handling events. The user does X and you need to response or not respond to it. The games have the added complexity in that it needs to change state in real time. In a lot of cases it does this by transforming the current state into a new state and telling the UI to display the results. It does this in a very short amount of time.

图形用户界面的核心问题是处理事件。用户执行X并且您需要响应或不响应它。游戏具有额外的复杂性,因为它需要实时改变状态。在很多情况下,它通过将当前状态转换为新状态并告诉UI显示结果来实现此目的。它在很短的时间内完成。

You start off with a model. A collection of classes that represents the data the user wants to manipulate. This could represent the accounts of a business or vast frontiers of an unknown world.

你从一个模型开始。表示用户想要操作的数据的类集合。这可能代表一个企业的帐户或未知世界的广阔前沿。

The UI starts with defining a series of forms or screens. The idea is that is for each form or screen you create a interface that defines how the UI Controller will interact with it. In general there is one UI Controller classes for each form or screen.

UI首先定义一系列表单或屏幕。我们的想法是,为每个表单或屏幕创建一个界面,定义UI控制器将如何与之交互。通常,每个表单或屏幕都有一个UI控制器类。

The form passes the event to the UI Controller. The UI Controller then decides which command to execute. This is best done through the Command design pattern where each command is it own class.

表单将事件传递给UI控制器。然后UI控制器决定执行哪个命令。这最好通过Command设计模式完成,其中每个命令都是它自己的类。

The Command then is executed and manipulate the model. The Command then tells the UI Controller that a screen or a portion of a screen needs to be redraw. The UI Control then looks at the data in the model and uses the Screen Interface to redraw the screen.

然后执行Command并操纵模型。然后,Command告诉UI控制器需要重绘屏幕或部分屏幕。然后,UI Control会查看模型中的数据,并使用屏幕界面重绘屏幕。

By putting all the forms and screen behind a interface you can rip out what you have and put something different in. This includes even not having any forms at all but rather mock objects. This is good for automated testing. As long as something implements the Screen Interface properly the rest of the software will be happy.

通过将所有表单和屏幕放在界面后面,您可以删除所拥有的内容并添加不同的内容。这包括甚至根本没有任何形式,而是模拟对象。这对自动化测试很有用。只要某些东西正确实现了屏幕界面,其余的软件就会很开心。

Finally a game that has to operate in real time will have a loop (or loops) running that will be continually transforming the state of the game. It will use the UI Controller to redraw what it updated. Commands will insert or change information in the model. The next time the loop comes around the new information will be used. For example altering a vector of a object traveling through the air.

最后,必须实时操作的游戏将有一个循环(或循环)运行,将不断改变游戏的状态。它将使用UI控制器重绘其更新的内容。命令将在模型中插入或更改信息。下一次循环出现时,将使用新信息。例如,改变穿过空中的物体的矢量。

I don't like the MVC architecture as I feel it doesn't handle the issues of GUIs well. I prefer the use of a Supervising Controller which you can read about here. The reason for this is that I believe automated tests are one of the most important tools you have. The more you can automate the better off you are. The supervising presenter pattern makes the forms a thin shell so there is very little that can't be tested automatically.

我不喜欢MVC架构,因为我觉得它不能很好地处理GUI的问题。我更喜欢使用监督控制器,你可以在这里阅读。这样做的原因是我相信自动化测试是您拥有的最重要的工具之一。您可以越多地自动化越好。监督演示者模式使表单成为一个薄壳,因此很少有自动测试。

#5


Sorry to say it, but it seems you have mess in your head trying to improve your coding too much in one step.

很抱歉这么说,但是你的脑子里似乎有点混乱,试图一步到位地改进你的编码。

There is no way to answer your question as such, but here we go.

没有办法回答你的问题,但我们走了。

First start with OOP, think about what objects are required for your game/GUI and start implementing them a little at a time, see if there are chances to break up these objects further, or perhaps reunite some objects that make no sense on their own, then try to figure out if you have repeated functionality among your objects, if you do, figure out if this repeated functionality is a (or many) base class or not.

首先从OOP开始,考虑游戏/ GUI需要什么对象,并开始一次实现它们,看看是否有可能进一步分解这些对象,或者重新组合一些自己没有意义的对象,然后尝试弄清楚你的对象中是否有重复的功能,如果你这样做,弄清楚这个重复的功能是否是一个(或许多)基类。

Now this will take you a few days, or weeks to really grok it well, then worry about dividing your logic and rendering.

现在这将花费您几天或几周的时间来真正理解它,然后担心划分您的逻辑和渲染。

#6


I have some tutorials that are written in C#. It discusses this very same topic. It is a starting point for a RogueLike game.

我有一些用C#编写的教程。它讨论了这个相同的主题。这是RogueLike游戏的起点。

Object Oriented Design in C# Converting Legacy Game

C#转换遗留游戏中的面向对象设计

Object Oriented Design: Domain Type Objects

面向对象设计:域类型对象

Object Oriented Design: Rethinking Design Issues

面向对象设计:重新思考设计问题

Object Oriented Design: Baby Steps in Acceptance Testing

面向对象设计:验收测试中的宝贝步骤