如何最好地解耦“蛇”等对象中的对象?游戏

发布于 2024-12-11 14:44:45 字数 616 浏览 0 评论 0原文

我正在用 C#/XNA 创建一个蛇游戏,只是为了好玩,但这是练习一些良好的对象设计的好机会。

Snake 对象

有一个 Snake 对象,它本质上是一个链表,每个节点都是一个带有 X & 的向量。与地图相关的 Y 坐标。

还有一些属性,例如蛇是否刚刚吃过东西(在这种情况下,本次更新不会删除最后一个身体节点)、蛇移动的方向等。

地图对象

地图(游戏区域)将其内容保存在二维整数数组中 - 使用基元数组来存储地图应该可以降低内存消耗,并且比向量数组更快(更容易)迭代。

内容在枚举 {Empty, Wall, Snake, Food} 内定义,然后存储在数组内的相关坐标处。

地图中还保留了对蛇对象的引用,以便每次调用渲染时都会循环遍历构成蛇的节点并将其渲染到地图上的正确位置。

问题!!

我的问题是...这种耦合是否太紧了,在这种情况下有什么建议(即观察者模式)还是适合这种情况...

我试图思考一种将蛇与需要知道地图使用的坐标系分离的方法,但无法想出一种方法使其工作并保持每个节点相对于彼此的位置。

任何答案表示赞赏,干杯!

I am creating a snake game in C#/XNA for fun but it's a good opportunity to practice some good object design.

Snake Object

There's a snake object which is essentially a linked list, each node being a vector with X & Y co-ordinates which relate to the map.

Also a few properties such as whether the snake has just eaten (in which case, the last body node is not removed for this update), direction that the snake is moving in etc.

Map Object

The map (game area) holds its contents inside 2D array of integers - using an array of primitives to store the map should keep down memory consumption and be quicker (and easier) to iterate over than an array of vectors.

Contents are defined inside an enum {Empty, Wall, Snake, Food} which are then stored inside the array at the relevant co-ordinates.

A reference is also kept to the snake object within the map so that every call to render, loops through the nodes that make up the snake and render it into the correct position on the map.

Question!!

My question is... is this coupling too tight, in which case are there any suggestions (i.e. observer pattern) or is it okay for this situation...

I've tried to think of a way to decouple the snake from needing to know the co-ordinate system being used by the map, but can't think of a way to make it work and keep the positions each nodes relative to each-other.

Any answers appreciated, cheers!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

优雅的叶子 2024-12-18 14:44:45

“这配合是不是太紧了?” 不,不是。

在这种情况下,解耦所需的代码比简单地通过耦合实现它所需的代码更大、更复杂且更难维护。

此外,总是需要某种程度的耦合。与“坐标系”的耦合通常是游戏开发中的其中之一。事实上,您可以严格解耦地图和蛇对象(同样,不值得付出努力),但它们仍然需要共享一个公共坐标系才能进行通信。

"is this coupling too tight?" No, it isn't.

In this case, the code required to decouple it is bigger, more complicated, and harder to maintain than the code required to simply implement it with the coupling.

Furthermore, there is always going to be some level of coupling required. Coupling to "a coordinate system" is usually one of them in game development. You could, in fact, rigorously decouple your map and snake objects (again, not worth the effort), but they still need to share a common coordinate system in order to communicate.

〆一缕阳光ご 2024-12-18 14:44:45

我想你自己已经暗示了答案。当前制作地图中引用的 Snake 的设计是两者之间的紧密耦合。

您可能需要考虑创建另一个接口,例如 Snake 将实现的 MapListenerSnake 将侦听地图将发布的事件并对其做出反应,从而有效地使 Snake 成为 Map 事件的订阅者发布(例如按照您所说的正确位置渲染)。您甚至可以拥有侦听器的 ArrayList,这样您就可以灵活地在地图中添加新对象,当您的游戏变得更加复杂时,这些新对象将对地图中的事件做出反应。

有关创建侦听器的参考,请参阅此问题 如何编写自定义侦听器。虽然此示例正在侦听完成下载,但您应该能够在接受的答案中看到为您的游戏创建自定义侦听器的模式。如果您需要任何说明,请告诉我,我将调整代码以适合您的情况。

I think you are already hinted the answer yourself. The current design of making the Snake referenced in the map is tight coupling between the two.

You might want to consider creating another Interface such as MapListener that the Snake will implement. The Snake will listen to the event that maps will publish and react to it, effectively making the Snake the subscriber for the event that the Map is publishing (such as rendering in the correct position as you say). You could even have ArrayList of Listeners so you have the flexibility of adding new Object in the map that would react to the event in the maps as your game becoming more complex.

For reference on creating the Listener, see this SO question How can I code a custom listener. While this example is listening for finishing download, you should be able to see the pattern in the accepted answer for creating custom listener for your game. Let me know if you need any clarification and I will adapt the code to fit your case.

忆依然 2024-12-18 14:44:45

这是简单的第一个想法结构:

 create an interface called MapContainable
 //marker interface
 interface MapContainable {
 }

 interface MapMovable extends MapContainable {
   ///map movement specific contract methods here
 }

class Snake implements MapMovable {
.....
}

这样,你的地图不需要知道是否有称为蛇、食物等的具体对象。你的蛇对象不需要知道地图的存在。蛇只会动!

Here is simple first thought structure:

 create an interface called MapContainable
 //marker interface
 interface MapContainable {
 }

 interface MapMovable extends MapContainable {
   ///map movement specific contract methods here
 }

class Snake implements MapMovable {
.....
}

This way, your map need not know if there are concrete objects called snake, food etc. You snake object need not know the existence of a Map. A snake just moves!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文