简体   繁体   English

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

[英]Object oriented design of game in Java: How to handle a party of NPCs?

I'm making a very simple 2D RPG in Java. 我正在用Java制作一个非常简单的2D RPG。 My goal is to do this in as simple code as possible. 我的目标是尽可能简单地执行此操作。 Stripped down to basics, my class structure at the moment is like this: 根据基础知识,我的班级结构目前是这样的:

  • Physical objects have an x and y dimension. 物理对象具有x和y维度。
    • Roaming objects are physical objects that can move(). 漫游对象是可以移动()的物理对象。
      • Humanoid objects are roaming objects that have inventories of GameItems. Humanoid对象是具有GameItems库存的漫游对象。
        • The Player is a singleton humanoid object that can hire up to 4 NPC Humanoids to join his or her party, and do other actions, such as fight non-humanoid objects. 玩家是一个单人类人体对象,可以雇用最多4名NPC Humanoids加入他或她的队伍,并做其他行动,例如打击非人形物体。
        • NPC Humanoids can be hired by the Player object to join his or her party, and once hired can fight for the Player. 玩家对象可以雇佣NPC Humanoids加入他或她的派对,一旦被雇用就可以为玩家而战。

So far I have given the Player class a "party" ArrayList of NPC Humanoids, and the NPC Humanoids class a "hired" Boolean. 到目前为止,我已经给了Player类一个NPC Humanoids的“派对”ArrayList,而NPC Humanoids类是一个“雇佣”的布尔值。

However, my fight method is clunky, using an if to check the party size before implementing combat, eg 但是,我的战斗方法很笨重,在执行战斗之前使用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. 

My question is, thinking in object oriented design, am I on the right track to do this in as simple code as possible? 我的问题是,在面向对象设计中思考,我是否能够在尽可能简单的代码中做到这一点? Is there a better way? 有没有更好的办法?

" My question is, thinking in object oriented design, am I on the right track to do this in as simple code as possible? " 我的问题是,在面向对象设计中思考,我是否能够以尽可能简单的代码执行此操作?

No, and your description uses the essential verbs that describe how your design is built on too much inheritance. 不,您的描述使用必要的动词来描述您的设计是如何构建在过多的继承上的。

Physical Objects have an x and y dimension (position). 物理对象具有 x和y维度(位置)。
[A Roaming Object is a Physical object that has a changeable position] [漫游对象是具有可变位置的物理对象]
Humanoid objects are roaming objects that have inventories. 人形对象是具有库存的漫游对象。
The Player is a singleton humanoid object that can have a party 玩家是一个单独的人形物体,可以一个聚会
[A party has a player and] has up to 4 NPC Humanoids [派对一名球员] 并且最多有4名 NPC Humanoids

Composition, although too rarely stressed in object-oriented design has a role to play in code. 虽然组合虽然在面向对象设计中很少受到压力,但它在代码中起着重要作用。 This is why the has-a / is-a distinction is so often used in analysis. 这就是为什么a-a / is-a区别经常用于分析。

By declaring a player as a singleton, you've added type complexity and possibly limited your design. 通过将玩家声明为单身人士,您增加了类型复杂性并可能限制您的设计。 What if you'd like to have two players at some future point? 如果你想在未来的某个时间点拥有两名球员怎么办? How about more? 怎么样? This is not an unreasonable extension but would require that you break the singleton anti-pattern used. 这不是一个不合理的扩展,但需要你打破使用的单一反模式。 If you only want one player, only instantiate one; 如果你只想要一个玩家,只需要实例化一个; coding the singleness assumption into the class is unnecessarily limiting. 将单一性假设编码到类中是不必要的限制。 Remember that the coder has to affirmatively call a constructor and need not worry about Players spontaneously appearing. 请记住,编码员必须肯定地称呼构造函数,而不必担心玩家会自发出现。

An object has a position, great: give it one through composition. 一个物体有一个位置,很棒:通过构图给它一个。 A position can be changed, so define position::move(). 可以更改位置,因此定义position :: move()。 A Player may have a human controller which distinguishes it from an NPC, but - by definition - a non-player character indeed is a character, one which has control that doesn't come from a player. 玩家可以有一个人的控制器,它从一个NPC的区别,但-顾名思义-一个非玩家角色确实是一个字符,一个具有控制并不来自球员。 Might you want to give an NPC player control? 你想给NPC玩家控制吗? Many games do, but if you have already encoded the player-character dependency inside a class, an NPC will always be an NPC. 很多游戏都有,但如果你已经在一个类中编写了玩家角色依赖,那么NPC将永远是一个NPC。

Also, how certain are you that 4 (or 5) is a good number for a party? 另外,你有多确定4(或5)对于派对来说是个好人数? The Zero, One, Infinity principle says that if you will allow more than one, allow an arbitrary number. Zero,One,Infinity原则说如果允许多个,允许任意数字。 If you don't hard code "five-ness" into your design, you limit flexibility. 如果您没有在设计中硬编码“五个”,则会限制灵活性。

I generally recommend that designers consider inheritance a method of last resort because of a history of overzealous use. 我通常建议设计师认为继承是一种最后的方法,因为它有过度使用的历史。 A design can be OOP with no inheritance at all. 设计可以是OOP而根本没有继承。 Polymorphism is cool, but so are encapsulation and abstraction, perhaps even more so. 多态性很酷,但封装和抽象也是如此,甚至更多。

Well, forgetting the overall design, from a basic programming point of view, instead of having that if structure, you should have a method that takes the party size as an argument. 好吧,从基本的编程角度来看,忘记整体设计,而不是拥有if结构,你应该有一个方法,将派对大小作为参数。 That way, you can just pass in this.getParty().size() and get rid of the if s. 这样,你可以传入this.getParty().size()并删除if s。

ie

  combatManager.fight(this.getParty().size(), eneObj);

Where combatManager is an object (or class, if you want a static version) that knows how to make things fight . combatManager是一个对象(或类,如果你想有一个静态的版本),它知道如何把事情fight

As I said though, this is not a solution for your design, simply a nicer way to avoid the if s. 正如我所说,这不是你的设计的解决方案,只是一个更好的方法来避免if

The Player class should not be responsible for making things fight, so perhaps you could change your fightEnemy method to engageEnemy or something, and simply have it go to the combatManager with the correct parameters. Player类不应该对战斗进行战斗负责,所以也许你可以改变你的fightEnemy方法来engageEnemy或其他东西,然后让它用正确的参数进入战斗管理器。

Perhaps this would be a nice opportunity to use the Strategy Design Pattern . 也许这是使用战略设计模式的好机会。 This way you can change the fighting strategy which will be used when party members are added or removed, rather than every fight. 通过这种方式,您可以更改在添加或删除党员时使用的战斗策略,而不是每次战斗。

The player is part of the party. 玩家是派对的一部分。 The NPCs are part of the party too. NPC也是党的一部分。 Why would the player handle NPC combat? 为什么玩家会处理NPC战斗? I think you should add that logic into the NPC class (extends Humanoid) and let add some AI so that NPCs will act with the player and other NPCs when they are grouped together. 我认为你应该将这个逻辑添加到NPC类中(扩展Humanoid)并添加一些AI,以便NPC在它们组合在一起时将与播放器和其他NPC一起动作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM