我正在构建一个由手机组成的简单游戏--游戏中的角色(暴徒)。每个暴徒都可以执行某些功能。为了给暴徒提供这种功能,我创建了一个行为。
例如,假设一个暴徒需要在游戏字段中移动,我会给它一个MoveBehavior -这是添加到暴徒类的内部行为列表中的:
// Defined in the Mob class
List<Behavior> behaviors;
// Later on, add behavior...
movingMob.addBehavior(new MovingBehavior());我的问题是。大多数行为都会操纵一些关于暴徒的东西。在MoveBehavior示例中,它将更改暴徒在世界上的X,Y位置。然而,每个行为都需要特定的信息,比如" movementRate“-- movementRate应该存储在哪里?
是否应该将其存储在Mob类中?其他暴徒可能会试图通过减速/加速暴徒来与之互动,并且更容易在暴徒级别访问它。但并不是所有的暴徒都有movementRate,所以它会造成混乱。
或者应该将其存储在MoveBehavior类中?这就隐藏了它,使得其他暴徒更难与之互动-但它不会用额外和未使用的属性来扰乱静止的暴徒(例如,不移动的塔永远不需要使用movementRate)。
发布于 2009-06-25 17:10:43
这就是经典的“行为组合”问题。权衡的是,行为越独立,它们彼此交互的难度就越大。
从游戏编程的角度来看,最简单的解决方案是决定一组“核心”或“引擎”数据,并将其放在主对象中,然后让行为能够访问和修改该数据-可能是通过函数接口。
如果您想要特定于行为的数据,这很好,但是为了避免变量名称中的冲突,您可能想要使访问它的接口包含行为名称。像这样:
obj.getBehaviorValue("movement", "speed")
obj.setBehaviorValue("movement", "speed", 4)这样,两种行为都可以定义自己的变量,称为速度和不冲突。这种类型的跨行为getter和setter将允许在需要时进行通信。
我建议使用Lua或Python这样的脚本语言来实现这一点。
发布于 2009-06-25 16:58:28
如果它与行为相关,并且只在该行为的上下文中有意义,那么它应该被存储为它的一部分。
移动率只对可以移动的东西有意义。这意味着它应该存储为表示其移动能力的对象的一部分,这似乎就是您的MoveBehavior。
如果这让它很难访问,那听起来更像是你的设计出了问题。那么问题不是“我是否应该作弊,并将一些变量放在Mob类中,而不是它所属的行为”,而是“我如何更容易地与这些单独的行为进行交互”。
我可以想到几种方法来实现这一点。显而易见的是,在Mob类上有一个简单的成员函数,它允许您选择单独的行为,如下所示:
class Mob {
private List<Behavior> behaviors;
public T Get<T>(); // try to find the requested behavior type, and return it if it exists
}然后其他人可以做这样的事情:
Mob m;
MovementBehavior b = m.Get<MovementBehavior();
if (b != null) {
b.SetMovementRate(1.20f);
}您还可以将其中的一些放在Mob类之外,创建一个辅助函数,该函数修改移动速率(如果存在),否则不执行任何操作:
static class MovementHelper {
public static SetMovementRate(Mob m, float movementrate){
MovementBehavior b = m.Get<MovementBehavior();
if (b != null) {
b.SetMovementRate(1.20f);
}
}
}然后其他人可以像这样使用它:
MovementHelper.SetMovementRate(m, 1.20f);这将提供修改行为的简单访问,但不会弄乱Mob类。(当然,将其转换为扩展方法是很有诱惑力的,但这可能会导致在Mob类的公共接口中出现太多杂乱。更可取的做法是明确指出这是驻留在Mob类之外的帮助器功能)
发布于 2009-08-20 11:01:59
看看组件系统/实体系统设计:
http://www.devmaster.net/articles/oo-game-design/
到目前为止我见过的最好的。
聪明人说,这是处理大型游戏的唯一方法,但这需要改变你对OOP的看法。
https://stackoverflow.com/questions/1044998
复制相似问题