我正在为2D平台游戏制作地图编辑器,其中包括使用自定义控件显示可能的图块类型列表,以及另一个自定义控件来渲染图块网格。我已经制作了两个控件并且正在工作,但我真的不喜欢它们的交互方式。
网格控件需要知道当前选择了哪种图块类型,以便在用户单击图块时可以创建该类型的新图块。它还需要将实际图像与图块类型相关联,以便它可以绘制图块网格。
tileset控件存储两个同步列表,一个具有图块类型,另一个具有显示每个图块类型图像的图片框。我没有这方面的字典,因为有时我只需要瓷砖类型,有时只需要图片框。
我现在设置的方式是事件。每次更改选择时,磁贴集控件都会触发一个事件,而当磁贴集更改时(当用户添加另一个磁贴类型时)则触发另一个事件。主窗体注册这些事件并更新当前选择的每个现有级别或新的tileset。
我解决这个问题的方法是使用事件。因此,对于需要更新的类之间的每个变量,我都有一个事件,当它在tileset控件中发生更改时会触发。这很乏味。
我还计划添加一个工具菜单,其中包含滑块/按钮/复选框等,需要更新关卡网格控件的参数。我真的不打算为此使用事件,特别是当我有几个控件时,可能会在以后添加更多参数。
那么,有没有更简单的方法来解决这个问题?
答案 0 :(得分:1)
我可能会使用中介模式来做这种事情。各种控件将使用mediator类注册消息处理程序,每个类型对于他们感兴趣的每种消息类型。每个控件都可以在有趣事件发生时向调解器发送消息。当介体收到消息时,它会将其广播给所有已注册的侦听器以获取该类型的消息。因此,对于您的情况,网格控件的每个实例都将向中介注册以接收“TileSelectionChanged”和“TileSetChanged”消息,并且磁贴集控件将使用中介在这些事件发生时广播消息,并传递相关数据随着消息。将来,当您实现工具菜单时,您需要做的就是为每个菜单操作向介体发送一条消息,并为需要响应它们的任何控件中的每个消息类型注册一个处理程序。
这种模式在某种程度上类似于您已经在做的事情:主要表单充当一种中介,在一个控件中侦听事件并将其广播到需要更新的其他控件。但这不一样。关键的区别在于,与真正的调解员不同,您的主要形式负责主动注册所有事件,这是引入维护繁琐的地方。真正的中介更加被动,让想要发布消息的类这样做,并将消息路由到任何感兴趣的听众。它既不知道也不关心消息的来源或含义,它只是传递它。在您当前的实现中,在构思新事件类型时,您需要更改三个位置:原始控件,主窗体和最终响应事件的控件。使用中介模式,更改将减少到两个位置:始发控件和响应控件。