我在为游戏设计GUI时遇到问题。到目前为止,我已经得出结论,复合模式将允许我将所有 UIComponents 视为相同,无论一个是 UIButton ,另一个是 UIMenu 。这是UIComponent接口:
class UIComponent {
virtual void Init() = 0;
virtual void Draw() = 0;
}
我的每个实现类( UIFrame,UIButton,UITextBox,UIMenu,... )现在可以相互协作。此设计中的复合类是UIMenu类,因为它 IS A UIComponent和 HAS A UIComponent。
class UIMenu : public UIComponent {
private:
vector<UIComponent*> children_;
public:
virtual void Init() {
// Initialize any data
};
virtual void Draw() {
// Delegate drawing to each child
for each(UIComponent* component in children_) {
component->Draw();
}
};
void AddComponent(UIComponent* child) {...};
void RemoveComponent(UIComponent* child) {...};
}
因为我想支持所有 UIComponents 中的拖放功能,所以每个组件都需要位置,尺寸,比例,父级和图层( ComponentData )。为此,我需要将它们分别添加到每个实现类中,对我来说,这似乎是错误的方法。
class UIFrame : public UIComponent {
private:
string imgID_;
int layer_;
double relX_, relY_;
double width_, height_;
double scaleX_, scaleY_;
UIComponent* parent_;
public:
virtual void Init() {...}
virtual void Draw() {...}
...
};
这是否已经破坏了复合模式,因为我现在通过聚合使每个组件实现成为复合?如果我希望我的UIButton具有相同的定位,转换和缩放功能,我需要从UIFrame继承或将数据成员复制到UIButton。
有没有更好的方法来创建 UIComponent 接口的实现?例如,我们可以让UIFrame成为所有需要移动能力的组件的基类,而不是UIButton,UITextBox,UILabel等。现在,像UIButton这样的组件将成为UIFrame的子组件,以便重用ComponentData。
在UIComponent接口中放置涉及定位,转换和缩放的方法会更好吗?这将强制每个组件都知道如何在屏幕上操作自己。但是,我仍然留下了问题,&#34;我在哪里放置ComponentData(位置,尺寸,比例)?&#34;
我非常喜欢复合模式的概念以及以原子方式处理Tree结构的Leaf和Branch节点的能力。它还允许我使用装饰器模式来创建UIMenu对象的多次迭代,这样我就可以通过更改每个菜单所具有的UIComponent来获得InventoryMenu,CharacterInfoMenu,OptionsMenu等。
答案 0 :(得分:0)
您可以使用支持拖放所需的数据项和方法创建超类UIDraggable
,每个可拖动元素都可以继承它。 UIDraggable
可以继承UIComponent
。