我正在制作一个包含不同类型怪物的游戏。还有一个接口列表,每个接口代表一个暴徒可以拥有的能力。假设我有100个对象来扩展mob类,每个对象包含一个不同的暴徒适用能力列表(swing,explode,jump等)。所有实现这些接口的方法都是向类中添加空白方法。如果能力的使用在所有怪物之间是恒定的,那么我将如何才能使能力如此 预先编写好以便我不需要为每个实现它的暴徒再写一次吗?
我确实知道默认方法,但是它们是静态的,除非我将“this”作为参数传递给我不想做的事情,否则无法访问任何mob的变量。
我也知道使用接口可以解决问题,这些接口只能由暴徒实现。
感谢。
答案 0 :(得分:2)
如果我理解正确,可能的解决方案是组合能力而不是继承它们。
interface Ability {
void doAbility();
}
class Firebending implements Ability {
private Mob mob;
public Firebending(Mob mob) {
this.mob = mob;
}
void doAbility() {
// mutate mob's state to spit fire, and attack the world
}
} // repeat this for each ability you have, flying, x-ray vision, doing taxes etc
class Mob {
private Ability[] abilities;
public Mob(Ability[] abilities) {
this.abilities = abilities;
}
}
使用这样的东西,你可以在飞行中建立不同的怪物,每个怪物具有不同的能力,适合于当暴徒品种数量超过能力数量时。是的,这将涉及设计你的Mob类,以便灵活地以这种方式进行变异。
答案 1 :(得分:0)
很酷的问题和一个我来回打架的问题。事实证明,您可能最终会陷入代码陷阱,这主要是由于严格的面向对象设计方法。编写了许多游戏引擎后,我可能会提出另一种思考过程。
图像如果你的骨架需要盾牌和剑,但是在任何时候都没有盾牌,也许你放弃它,或者相反地掉剑(或两者兼而有之)。要仅使用面向对象的设计对此进行编码,我们将尝试从骨架继承并扩展类以使用剑实例的骨架,但是使用盾牌,剑与盾,或两者,或两者都没有。为了实现这一目标,你可以强迫它并强制进行OOP设计,但是就像所有事情一样,游戏设计师最终会要求你以某种方式改变骨架,这将导致重大的代码更改,你可以忘记松散耦合的对象共享(比如说骷髅掉剑,骑士捡起它。
在处理了这个并且低估了你现在的位置之后,我建议研究Entity Component System。
这里的游戏资产分为实体,组件和系统。
实体:是一个简单的整数列表,其中每个整数都是一个组件ID。这允许诸如SwordComponent之类的组件跨任何其他组件共享。将实体视为系统可用于执行某些游戏操作的组件集合。
组件:组件是一个简单的类,它只包含数据字段,从不实现。每个组件都获得一个唯一的ID以及定义组件所需的特定字段。在这里,我发现可以使用OOP继承Component类,所以我真的使用了两个世界的混合。
系统:系统是事物变得有趣的地方。虽然实体只是组合组件的列表,而组件只是数据和状态信息,但系统会对组件数据起作用以使实体工作。在这里,您可以传入一个实体并对数据进行一些游戏逻辑操作。您可以在系统中放置使每个实体都打勾的代码。
以下是我们骨架示例的概述:
Component[0]: Skeleton Mesh
Component[1]: Idle Animation
Component[2]: Walk Animation
Component[3]: Run Animation
Component[4]: Collision
Component[5]: Sound
Component[6]: Sword
Component[7]: Shield
Component[8]: Clown Suit
骷髅实体:
Entity[0] = new int {0,1,2,3,4,5,6,7,8} // Defines all the components above into one character
可能的系统:
System[0] = Collision system handles polygon collisions, using all entities collision components.
System[1] = Animation system uses idle, walk, and run animation components and can be shared across entities.
System[2] = Render system is used to render the mesh using your render engine.
System[3] = Sound system is used to handle sound start, end, tween...
System[4] = ...
现在如果设计师希望骨架能够发芽并飞行,我不担心更改任何以前的代码,我只需创建一个新的WingsComponent,将其添加到我的实体组件列表中,然后对新系统进行编码让骨架飞起来。现在我可以自由扩展我的组件和系统池而不用担心破坏更改。