Oop 我将如何控制这个文本游戏,以及类如何获得更好的结构来实现这一点?

Oop 我将如何控制这个文本游戏,以及类如何获得更好的结构来实现这一点?,oop,class-design,Oop,Class Design,如果我有一个textgame,它有一个world对象,它有一个room类型的对象,它有物品和敌人的对象,然后是一个gamehelper对象,它有实际玩家的用户对象。(这个游戏没有游荡的敌人,因为这会让我的问题变得复杂:-) 我应该怎样去杀一个敌人或者捡起一个物体? 或者,当我完全构建我的课程时,我应该考虑其他方式吗?我得到的建议是,我需要一个管理者来控制世界,并在用户和对象之间进行调解,但我不知道这看起来/工作起来如何 我还将实现killable和pickable的接口,以便在必要时将对象彼此分

如果我有一个textgame,它有一个world对象,它有一个room类型的对象,它有物品和敌人的对象,然后是一个gamehelper对象,它有实际玩家的用户对象。(这个游戏没有游荡的敌人,因为这会让我的问题变得复杂:-)

我应该怎样去杀一个敌人或者捡起一个物体? 或者,当我完全构建我的课程时,我应该考虑其他方式吗?我得到的建议是,我需要一个管理者来控制世界,并在用户和对象之间进行调解,但我不知道这看起来/工作起来如何

我还将实现killable和pickable的接口,以便在必要时将对象彼此分离,如果这有任何关联的话。。。哦,我在学习Java,所以任何有助于理解的示例代码都可以用Java编写

即:


我看不出您的类结构有任何明显的错误,除非您的图表是它的图表。:)房间、物体和敌人当然不应该继承这个世界。不过,看起来您正在绘制包容图,这很好

你会如何杀死敌人或捡起一个物体?这不取决于这些动作在游戏中的意义吗?这听起来像是,为了拾取一个对象,一个对象有一个可以是房间或用户的环境;环境为用户的对象位于该用户的资源清册中。拾取对象会将其环境从房间更改为用户


物体也可能有敌人作为其环境,因此杀死敌人会摧毁敌人并将其库存中的物体移动到敌人占据的房间中。或者你想要一个“死敌”类型的物体?实际上,这完全取决于您的游戏模式。

可攻击和可拾取物品的界面,也许:

interface IAttackable {
    void Attack();
    event Killed;
}
interface ILiftable {
    void Get(Container putHere);
}
然后,您可以进行简单的类型检查,看看是否可以攻击或拾取内容

是的,中介对象听起来是个好主意。。。例如,它可能订阅所有IAttackable.Killed事件,并在与它们在同一房间中死亡时向用户类发送信号。它也可能是一个中间人,负责组织每个人遭受的损失


就我个人而言,我会有一个
生物
类,并让敌人和用户都从中得到子类,以简化一些事情(如果需要的话,可能会让敌人自己与敌人作战)。

应用程序中经常使用控制器或中介类,但这对我来说有点“味道”。当所有其他类都只是数据容器时,这样的类可以很快成为所谓的“上帝类”,它知道一切

这种设计是值得警惕的!OO设计有一个很好的例子,其中包括这个警告和其他非常好的原则

我还可以推荐“Bob叔叔”的文章来进行OO设计。你应该看看“设计原则”,这里特别是第一篇文章

这些都是非常宝贵的资源来理解类应该如何设计——我认为通过事件和其他事情进行解耦也是在那里处理的

有了这种武器,你将为设计做好更好的准备

您的设计也可以从思考开始,思考哪些对象应该执行哪些活动。收集所有活动的物品闻起来像上帝的职业——避开它们!没有任何活动的对象闻起来一点也不需要——盒子“世界”和“游戏”有点朝这个方向闻,除非它们真的携带了其他对象无法携带的功能

当你创造一些想法时,世界是如何运转的——设计可能很简单。像“环境”这样的联想可以在这里产生。但不同的建模也是可能的。这个怎么样(只是一个猜测!):为什么你们的房间必须是一个整体?您还可以拥有一个仅包含一个二维阵列的世界对象,其中包含房间中包含的对象(包括用户对象??)的插槽。当你有一个大的“世界”时,这可以使事情变得轻松。但当然,房间作为对象有一个优点,即可以轻松地容纳无限的对象(敌人、用户、物品)

因此,首先,您可能会开始考虑这个问题,然后如果您有一个Item类或“Takeable”类。。。等等


希望这能帮上一点忙——尽管问吧。

如评论中所述,了解游戏是单人游戏还是多人游戏、回合制还是实时游戏很重要。因为单人回合游戏的简单解决方案在多人实时游戏中无法不修改

对于基于单人回合的游戏,以下基本大纲应提供一种方法(类似Python的伪代码):

如果您是实时的,而不是基于回合,那么您的主循环可能会更改为轮询输入,并且您可能希望在某种计时器上运行update_world,而不是每次迭代运行一次。对于周期性任务,如轮番作战,也可以使用这种计时器完成。能够将将来的事件放入按时间排序的队列中,然后在每次迭代中检查队列前面是否有挂起的事件,这很有用


您的命令对象可以执行查找所有相关方并根据需要对其执行操作的任务。PC或NPC可以根据您的需要使用它们,如果您希望它们在将来运行,可以将它们推到未来事件队列中。显然,要使命令对象有用,它们需要能够在世界上查找东西,例如查找房间中的所有角色、角色资源清册中的所有对象、房间中的所有对象,等等。如果你很狡猾,你可以在一个容器接口周围用薄包装实现几乎所有这些。

哦,是的,这是一张它们不是c的地方的图表
interface IAttackable {
    void Attack();
    event Killed;
}
interface ILiftable {
    void Get(Container putHere);
}
def main_loop():
    while not finished:
        command_text = ask_user_for_input()
        execute_player_command(command_text)
        update_world()
        send_output_to_player()

def execute_player_command(command_text):
    # look up the command object and work out what parameters to pass it
    command, parameters = parse(command_text)
    # ask the command to do its stuff
    command.execute(player, parameters)

def update_world():
    # obviously you can munge these together with an Updateable interface
    # or something similar
    for each creature in all_creatures:
        creature.update()
    for each object in all_objects:
        object.update()