如何重构我的代码以避免从类外部引发事件?
Posted
技术标签:
【中文标题】如何重构我的代码以避免从类外部引发事件?【英文标题】:How to refactor my code to avoid raising events from outside the classes? 【发布时间】:2018-11-09 04:40:28 【问题描述】:我正在开发一个游戏,其中包含一些用于不同任务的管理器,例如碰撞检测等。一旦检测到碰撞,受此碰撞影响的每个游戏对象都应该引发 OnCollided
事件,这样我就可以轻松播放声音,制作对象消失,打开一扇门或其他任何东西,但如果不从CollisionSystem
引发事件,而不是让每个GameObject
引发自己的事件,我就无法获得这种行为。
这是一个简化的例子,希望它有意义:
Class CollisionSystem
// It is called when a collision has been detected between two objects (code not included)
public void HandleCollision(GameObject gameObject1, GameObject gameObject2)
//Do whatever
//How can trigger each corresponding game object event from here?
Class GameObject
protected event GameEventHandler Collided;
protected void OnCollided(GameEventArgs e)
if (Collided != null)
Collided(this, e);
我已经测试了诸如公开 OnCollided
方法之类的东西,但是应该从类内部引发事件......而且,另一方面,游戏对象本身无法确定它何时发生碰撞,原因,好吧,这就是CollisionSystem
所做的。
提前致谢。
【问题讨论】:
请修复代码格式,它让我的强迫症感到不安,一个智能捆绑游戏开发绝地应该没有问题 就我在这里看到的情况而言,您的做法是错误的。OnCollided
不应该引发事件,而是监听 CollisionSystem 引发的 OnCollided
事件。但是,您希望能够将其提升为仅处于冲突中的对象,而不是所有订阅该事件的对象。
从CollisionSistem
调用GameObject
中的公共方法(应该是带有y 的“系统”,除非它不是英语)然后引发事件?
抱歉,我是盲人,我很难在这里格式化代码,TheGeneral。
【参考方案1】:
好吧,这就是我能想出的应该体现你想要做的事情:
public class CollisionSystem
Public void HandleCollision(IGameObject[] objects)
foreach (IGameObject obj in objects)
//call the function that tells the object it collided
obj.CollisionDetected()
你会希望你的游戏对象实现一个接口
public interface IGameObject
public void CollisionDetected()
这意味着你的游戏对象类看起来像这样;
public class GameObject : IGameObject
//constructors, params, whatever
public void CollisionDetected()
//play some sound, remove object, whatever
问题是;我不知道是什么引发了您的碰撞事件。
编辑:所以我重读了你的问题,看到你提到它是从物理引擎开始调用的。无论在哪里/无论如何,如果您在物理引擎类中声明了您的CollisionSystem
,您可以从那里调用HandleCollision()
-方法,然后您就完成了。
【讨论】:
实际上,物理系统是指碰撞系统。当检测到碰撞时会调用 HandleCollision() 方法,因此参数只是发生碰撞的对象。我正在测试,但我认为你的答案效果更好! @D646 如果CollisionSystem
-class 正在检测冲突,您可以简单地调用HandleCollision()
-方法并给它一个数组(在我的示例中)IGameObjects
(或其他任何东西您可能正在使用可能会发生碰撞的事件),而不必从外部引发事件,这使事情变得更加容易。
所以,我只是从 gameobject 类中删除事件,并实现一个公共方法,如 gameObject.hasCollided()¿
@D646 是的。请注意,您描述的HasCollided()
-方法应该在GameObject
-class 中。但是,我假设门可能不是GameObject
,而是例如TerrainObject
。这就是我提出接口的原因。这样,当您将碰撞的所有对象交给HandleCollision()
-方法时,您可以将它们放在同一个数组中,正如我在回答中所展示的那样。以上是关于如何重构我的代码以避免从类外部引发事件?的主要内容,如果未能解决你的问题,请参考以下文章