首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我的架构(实时策略游戏中的NPC)的多重继承的替代方案?

我的架构(实时策略游戏中的NPC)的多重继承的替代方案?
EN

Software Engineering用户
提问于 2014-08-22 18:47:58
回答 4查看 3.4K关注 0票数 11

编码其实没那么难。困难的部分是编写有意义、可读性和可理解性的代码。因此,我想要一个更好的开发人员,并创建一些坚实的架构。

所以我想在视频游戏中为鼻咽癌创建一个架构。这是一个实时战略游戏,如星际争霸,帝国时代,指挥和征服等。所以我会有不同种类的NPC。一个NPC可以有一个到多个能力(方法):Build()Farm()Attack()

示例:

工作者can Build()Farm()

战士可以Attack()

公民can Build()Farm()Attack()

渔夫可以Farm()Attack()

我希望到目前为止一切都很清楚。

所以现在我有我的NPC类型和他们的能力。但让我们谈谈技术/程序方面。

对于我的不同类型的NPC来说,什么才是好的编程架构?

好的,我可以有一个基类。实际上,我认为这是坚持干的原则的好方法。所以我可以在基类中使用像WalkTo(x,y)这样的方法,因为每个NPC都可以移动。但现在让我们来谈谈真正的问题。我该在哪里实现我的能力?(记住:Build()Farm()Attack())

由于这些能力将由相同的逻辑组成,因此为每个NPC (Worker,Warrior,.)实现它们将是恼人/断断续续的原则。

好的,我可以在基类中实现这些能力。这需要某种逻辑来验证NPC是否可以使用X. IsBuilderCanBuild、..。我想我想表达的很清楚。

但我对这个想法感觉不太好。这听起来像是一个功能过多的膨胀的基类。

我确实使用C#作为编程语言。所以多重继承在这里不是一种选择。意思是:拥有像Fisherman : Farmer, Attacker这样的额外基类是行不通的。

EN

回答 4

Software Engineering用户

回答已采纳

发布于 2014-08-22 18:57:11

组合继承和接口继承是传统多重继承的常用选择。

上面以" can“一词开头的所有内容都是可以用接口表示的功能,如ICanBuildICanFarm。您可以根据自己的需要继承这些接口中的任何一个。

代码语言:javascript
复制
public class Worker: ICanBuild, ICanFarm
{
    #region ICanBuild Implementation
    // Build
    #endregion

    #region ICanFarm Implementation
    // Farm
    #endregion
}

您可以通过类的构造函数传递“泛型”构建和农业对象。这就是构图的来源。

票数 14
EN

Software Engineering用户

发布于 2014-08-22 20:05:18

正如其他海报所提到的,组件体系结构可以解决这个问题。

代码语言:javascript
复制
class component // Some generic base component structure
{
  void update() {} // With an empty update function
} 

在这种情况下,扩展update函数来实现NPC应该具有的任何功能。

代码语言:javascript
复制
class build : component
{
  override void update()
  { 
    // Check if the right object is selected, resources, etc
  }
}

迭代组件容器并更新每个组件允许应用每个组件的特定功能。

代码语言:javascript
复制
class npc
{
  void update()
  {
    foreach(component c in components)
      c.update();
  }

  list<component> components;
}

由于需要每种类型的对象,所以可以使用某种类型的工厂模式来构造所需的各个类型。

代码语言:javascript
复制
npc worker;
worker.add_component<build>();
worker.add_component<walk>();
worker.add_component<attack>();

随着组件变得越来越复杂,我总是遇到一些问题。保持组件复杂度低(一项责任)可以帮助缓解这个问题。

票数 4
EN

Software Engineering用户

发布于 2014-08-22 19:23:15

如果您定义了像ICanBuild这样的接口,那么游戏系统必须按类型检查每个NPC,这在OOP中通常是不允许的。例如:if (npc is ICanBuild)

你最好是:

代码语言:javascript
复制
interface INPC
{
    bool CanBuild { get; }
    void Build(...);
    bool CanFarm { get; }
    void Farm(...);
    ... etc.
}

然后:

代码语言:javascript
复制
class Worker : INPC
{
    private readonly IBuildStrategy buildStrategy;
    public Worker(IBuildStrategy buildStrategy)
    {
        this.buildStrategy = buildStrategy;
    }

    public bool CanBuild { get { return true; } }
    public void Build(...)
    {
        this.buildStrategy.Build(...);
    }
}

当然,您可以使用许多不同的体系结构,比如某种特定于领域的语言,以fluent接口的形式定义不同类型的NPC等等,其中通过组合不同的行为构建NPC类型:

代码语言:javascript
复制
var workerType = NPC.Builder
    .Builds(new WorkerBuildBehavior())
    .Farms(new WorkerFarmBehavior())
    .Build();

var workerFactory = new NPCFactory(workerType);

var worker = workerFactory.Build();

NPC构建器可以实现一个DefaultWalkBehavior,在飞行但不能行走的情况下,它可以被覆盖。

票数 3
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/254164

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档