Java游戏的面向对象设计:如何处理NPC?

Java游戏的面向对象设计:如何处理NPC?,java,oop,Java,Oop,我正在用Java制作一个非常简单的2D RPG。我的目标是用尽可能简单的代码来实现这一点。简而言之,我目前的班级结构如下: 物理对象有x和y 维 漫游对象是物理对象 它可以移动()。 类人对象是漫游对象 有游戏物品清单的。 该玩家是一个单身人形 可以雇佣最多4个NPC类人的对象 加入他或她的团队,并做其他动作,例如与非人形物体战斗 NPC类人形机器人可以被 玩家反对加入他或她 党,一旦雇用可以为球员战斗 到目前为止,我已经给出了NPC类人形游戏玩家a级的“派对”数组列表,以及NP

我正在用Java制作一个非常简单的2D RPG。我的目标是用尽可能简单的代码来实现这一点。简而言之,我目前的班级结构如下:

  • 物理对象有x和y 维
    • 漫游对象是物理对象 它可以移动()。
      • 类人对象是漫游对象 有游戏物品清单的。
        • 该玩家是一个单身人形 可以雇佣最多4个NPC类人的对象 加入他或她的团队,并做其他动作,例如与非人形物体战斗
        • NPC类人形机器人可以被 玩家反对加入他或她 党,一旦雇用可以为球员战斗
到目前为止,我已经给出了NPC类人形游戏玩家a级的“派对”数组列表,以及NPC类人形游戏玩家a级的“雇佣”布尔值

然而,我的战斗方法很笨拙,在实施战斗之前使用if检查队伍规模,例如

public class Player extends Humanoids {
   private ArrayList<Humanoids> party;
   // GETTERS AND SETTERS for party here
   //...

   public void fightEnemy(Enemy eneObj) {
      if (this.getParty().size() == 0)
        // Do combat without party issues
      else if (this.getParty().size() == 1)
        // Do combat with party of 1
      else if (this.getParty().size() == 2)
        // Do combat with party of 2
      // etc. 
公共类玩家扩展人形类{
私人政党;
//这里聚会的接受者和接受者
//...
公敌{
if(this.getParty().size()==0)
//做没有党派问题的战斗
else if(this.getParty().size()==1)
//与一方作战
else if(this.getParty().size()==2)
//与2人一组作战
//等等。

我的问题是,在面向对象设计中思考,我在尽可能简单的代码中做这件事是否正确?有更好的方法吗?

好吧,从基本编程的角度来看,忘记总体设计,而不是拥有
如果
结构,你应该有一个以参与者大小为参数的方法。那就是这样,您就可以传入
this.getParty().size()
并去掉
if
s

i、 e

其中,
combatManager
是一个对象(或类,如果您想要一个静态版本),它知道如何使事物
战斗

正如我所说的,这不是设计的解决方案,只是避免
if
s的更好方法


Player
类不应该负责让事情发生冲突,所以也许你可以将你的
fightnemy
方法更改为
Engage敌军
或其他方法,然后简单地将其交给战斗管理器,并提供正确的参数。

也许这将是一个很好的使用方法的机会。通过这种方式,你可以更改“我的问题是,在面向对象的设计中思考,我是否走上了用尽可能简单的代码实现这一点的正确道路?”

不,您的描述使用了基本动词来描述您的设计是如何建立在太多的继承之上的

物理对象具有x和y维度(位置)。
[漫游对象是具有可更改位置的物理对象]
类人对象是具有库存的漫游对象。
玩家是一个单体类人对象,可以拥有一个聚会 [一方拥有一名玩家,拥有最多4名NPC人形机器人

虽然在面向对象设计中很少强调组合,但它在代码中起着作用。这就是为什么在分析中经常使用has-a/is-a的区别

通过将一个播放器声明为singleton,您增加了类型复杂性,并且可能限制了您的设计。如果您希望在将来某个时候拥有两个播放器,那么会怎么样?更多呢?这不是一个不合理的扩展,但需要您打破使用的singleton反模式。如果您只需要一个播放器,则只需实例化一个;对si进行编码对类的单一性假设是不必要的限制。记住,编码者必须肯定地调用构造函数,不必担心玩家自发出现

一个对象有一个位置,很好:通过合成给它一个位置。位置可以改变,所以定义位置::move()。玩家可能有一个与NPC不同的人类控制器,但根据定义,非玩家角色确实是一个角色,一个具有控制权的角色,而不是来自玩家。您是否希望赋予NPC玩家控制权?许多游戏都有,但如果您已经对玩家角色dep进行了编码在班级里,NPC永远是NPC

另外,你有多确定4(或5)对一个聚会来说是一个好数字?原则上说,如果你允许多个,就允许任意数字。如果你不在设计中硬编码“五度”,你就限制了灵活性


<>我通常建议设计师考虑继承是一种最后的手段,因为有一个过度使用的历史。一个设计可以是没有继承性的OOP。多态性是很酷的,但是封装和抽象也是如此。

< P>玩家是党的一部分。NPC也是党的一部分。为什么会这样?玩家处理NPC战斗?我认为你应该把这个逻辑添加到NPC类中(扩展人形)让我们添加一些人工智能,这样NPC将在玩家和其他NPC组合在一起时与他们一起行动。

我建议你这样写,但在你有一个工作版本后,重新查看代码,重构或重写它。@Chris,谢谢,我弹出了“==”总之。@Ron,谢谢你的建议,我将采纳。我应该指出,我更愿意一开始就把它做好,而不是以后再搞得一团糟。如果它只是一个例子,那么使用switch…case语句如何ints@Chuk李:好主意。换一个,或者说,关键是它笨重而且不是好的面向对象设计。克里斯·库普从OO设计的角度来看,r的回答很好。我认为玩家不应该这样做
  combatManager.fight(this.getParty().size(), eneObj);