在游戏中制作大量咒语时遇到困难
Having trouble with making lots of spells in a game
所以我在想出一种在我的游戏中实施咒语的方法时遇到了麻烦。问题是我想添加许多不同的法术(如传送、心灵传动、火力控制等)。我尝试的第一件事是制作一个大的 class 层次结构,例如:
Spell -> Passive ->Speed
->Flying
-> Active ->Teleportation
Telekinesis
一开始看起来不错,但是当我开始实施很多法术时,它开始变得混乱。
我搜索了其他解决方案,并找到了基于实体组件的系统。但我认为这不是一个好的解决方案。
那么你们中有人知道解决这个问题的任何其他方法吗?
与其为每种类型的魔法创建多个 classes,不如开始将它们全部封装在一个魔法 class 中并根据触发器从那里处理它们?
switch(castID) {
default:
break;
case 1: //air strike
Spell AirStrike = new Spell('AirStrike');
break;
case 2:
...
}
然后有一个 class 用于 Spell 并根据发送的参数处理其中的每个法术
如果您使用 Strategy Design Pattern
之类的东西,并且您在哪里有一个定义方法的接口,例如 ApplySpell()
和 Name
属性 以及具体 拼写实现所述接口?
这样,对于每个角色,您可以遍历分配给他们的法术并使用 Name
属性 获取名称(也许您想通过 UI 列出它们或类似的东西),或者将它们存储在字典中,其中拼写的名称是键,实际的拼写实现是值。
然后你可以做的是,一旦用户选择了法术,你需要做的就是调用 ApplySpell()
,实际法术的作用委托给 class代表法术。
这样一来,你就不用担心需要调用哪个法术了,因为一切都在幕后完成。
继承是可以的,但是对于属性,您可以使用接口或基础 类 作为属性:
class SpellBase
{
public string Name { get; protected set; } // all spells have to have name
public virtual void Animate() { ... } // abstract?
...
}
然后进行传送
class TeleportationSpell: SpellBase, IEffect
{
... // set name, override Animate() and implement IAreaEffect (as OnSelfEffect() for teleport)
}
interface IEffect
{
public EffectBase Effect {get; set;}
...
}
class EffectBase { ... }
class OnSelfEffect: EffectBase { ... }
class OnTargetEffect: EffectBase { ... }
class OnSelfAndTargetEffect: EffectBase { ... }
接口将使您的层次结构更少分支,但需要更多代码来实现(这不是真正的问题,因为您可以将通用代码移动到方法中并调用它们)。
实体组件方法可以很好地解决您的问题。 :)
你应该花更多的时间去理解它。
你总是要在"is a"或"have a"关系之间做出决定。
其中 "is a" 表示继承,"have a" 表示组合。
EntityComponents 的作用是将每个游戏对象属性放入一个组件 class,然后将这些组件放在一起。您可以创建属性的每个组合而无需或更少的代码更改(取决于实现)。
通过使用该方法,创建多人游戏也很容易,因为您的代码中只有几个地方可以放置通信内容。
另一方面是你会有很多 classes 并且一切都高度解耦。总的来说,这是一个优点,也是我们作为 OO 开发人员想要的。
但是对于新开发人员或技能不那么高的开发人员来说,这可能读起来很糟糕。
所以我建议你选择实体组件的方式,因为你的游戏以后会更容易扩展。
所以我在想出一种在我的游戏中实施咒语的方法时遇到了麻烦。问题是我想添加许多不同的法术(如传送、心灵传动、火力控制等)。我尝试的第一件事是制作一个大的 class 层次结构,例如:
Spell -> Passive ->Speed
->Flying
-> Active ->Teleportation
Telekinesis
一开始看起来不错,但是当我开始实施很多法术时,它开始变得混乱。
我搜索了其他解决方案,并找到了基于实体组件的系统。但我认为这不是一个好的解决方案。 那么你们中有人知道解决这个问题的任何其他方法吗?
与其为每种类型的魔法创建多个 classes,不如开始将它们全部封装在一个魔法 class 中并根据触发器从那里处理它们?
switch(castID) {
default:
break;
case 1: //air strike
Spell AirStrike = new Spell('AirStrike');
break;
case 2:
...
}
然后有一个 class 用于 Spell 并根据发送的参数处理其中的每个法术
如果您使用 Strategy Design Pattern
之类的东西,并且您在哪里有一个定义方法的接口,例如 ApplySpell()
和 Name
属性 以及具体 拼写实现所述接口?
这样,对于每个角色,您可以遍历分配给他们的法术并使用 Name
属性 获取名称(也许您想通过 UI 列出它们或类似的东西),或者将它们存储在字典中,其中拼写的名称是键,实际的拼写实现是值。
然后你可以做的是,一旦用户选择了法术,你需要做的就是调用 ApplySpell()
,实际法术的作用委托给 class代表法术。
这样一来,你就不用担心需要调用哪个法术了,因为一切都在幕后完成。
继承是可以的,但是对于属性,您可以使用接口或基础 类 作为属性:
class SpellBase
{
public string Name { get; protected set; } // all spells have to have name
public virtual void Animate() { ... } // abstract?
...
}
然后进行传送
class TeleportationSpell: SpellBase, IEffect
{
... // set name, override Animate() and implement IAreaEffect (as OnSelfEffect() for teleport)
}
interface IEffect
{
public EffectBase Effect {get; set;}
...
}
class EffectBase { ... }
class OnSelfEffect: EffectBase { ... }
class OnTargetEffect: EffectBase { ... }
class OnSelfAndTargetEffect: EffectBase { ... }
接口将使您的层次结构更少分支,但需要更多代码来实现(这不是真正的问题,因为您可以将通用代码移动到方法中并调用它们)。
实体组件方法可以很好地解决您的问题。 :) 你应该花更多的时间去理解它。
你总是要在"is a"或"have a"关系之间做出决定。 其中 "is a" 表示继承,"have a" 表示组合。
EntityComponents 的作用是将每个游戏对象属性放入一个组件 class,然后将这些组件放在一起。您可以创建属性的每个组合而无需或更少的代码更改(取决于实现)。 通过使用该方法,创建多人游戏也很容易,因为您的代码中只有几个地方可以放置通信内容。
另一方面是你会有很多 classes 并且一切都高度解耦。总的来说,这是一个优点,也是我们作为 OO 开发人员想要的。 但是对于新开发人员或技能不那么高的开发人员来说,这可能读起来很糟糕。
所以我建议你选择实体组件的方式,因为你的游戏以后会更容易扩展。