我将如何控制这个文本游戏以及类如何获得更好的结构呢?

时间:2009-06-30 23:08:22

标签: oop class-design

如果我的文本游戏中有一个世界对象,其中包含类型为room的对象,其中包含项目和敌人的对象,然后是一个具有实际玩家用户对象的gamehelper对象。 (这个游戏没有游荡的敌人,因为这会让我的问题变得更加困难: - ))。

我应该如何杀死敌人或拾取物体? 或者在完全构建我的类时我应该考虑其他方式吗?我得到的建议是,我需要一个控制世界并在用户和对象之间进行调解的经理,但我无法弄清楚看起来/工作的方式

我还会实现killable和pickable的接口,以便在必要时将对象与其他对象分开,如果有任何相关性......并且我即时学习Java,因此任何可能有用的示例代码都可以写入其中。

即:

        World
         |
    ____Rooms____ (could be like a 4x4 array or something with X and Y cords)
    |           |
  Objects     Enemies (Either killable / pickupable)

        Game
         |
        User (can walk around in rooms, kill monsters and take treasure)

4 个答案:

答案 0 :(得分:1)

除非您的图表是图表,否则我没有看到您的类结构有任何明显错误。 :)房间,物体和敌人当然不应该继承世界。看起来你的图表是遏制,这很好。

你会如何杀死敌人或拾取物体?这取决于这些行为在游戏中的意义吗?听起来,对于拾取对象,对象具有可以是房间或用户的环境;环境为用户的对象位于该用户的清单中。拾取对象会将其环境从房间更改为用户。

可能物体也可以将敌人作为他们的环境,因此杀死敌人会摧毁敌人并将其库存中的物体移动到敌人占据的房间。或许你想要一个“死敌”类型的物体?真的,这一切都取决于你的游戏模式。

答案 1 :(得分:1)

可攻击和可拾取物品的接口,可能是:

interface IAttackable {
    void Attack();
    event Killed;
}
interface ILiftable {
    void Get(Container putHere);
}

然后你可以进行简单的类型检查,看看你是否可以攻击或拾取东西。

是的,一个中介对象听起来是个好主意......例如,它可能订阅所有IAttackable.Killed事件,并在与它们在同一房间内死亡时向User类发送信号。它也可能是组织每次伤害的中间人。

就个人而言,我有一个Creature类,并且同时拥有敌人和用户的子类,以简化一些事情(并且如果需要的话,可能使敌人能够自己战斗)。

答案 2 :(得分:0)

控制器或中介类通常用于应用程序中,但这对我来说有点“嗅觉”。当所有其他类只是数据容器时,这些类可以快速成为所谓的“上帝类”,它们知道一切。

警告这种设计!关于OO-Design有一个很好的book,包括这个警告和其他非常好的原则。

我也可以推荐OO-Design,一般是“Uncle Bob”Robert C. Martin的文章。你应该看看“设计原则”,特别是第一篇文章。

那些是非常宝贵的资源来理解,应该如何设计类 - 我认为也可以通过事件和其他东西进行解耦。

通过这种武器,您将为设计做好更充分的准备。

您的设计也可以通过思考,应该由哪些对象完成哪些活动来开始。帐篷收集所有活动的物品闻起来像神级 - 避免它们!根本没有任何活动的物品根本不需要闻起来 - “世界”和“游戏”这两个方框在这个方向上有点嗅觉,除非它们真的带有其他任何物体都无法携带的功能。

当你创造一些想法,世界如何运作时 - 设计可能非常容易。像“环境”这样的思想可以在这里作出。但也可以进行不同的建模。怎么样(只是一个猜测!):为什么你的房间必须完全是对象?您还可以拥有一个World-Object,它只包含一个2D-Array,其中包含房间中包含的对象的插槽(包括用户对象??)。当你有一个大的“世界”时,这可以缓解一切。但是当然,房间作为物体具有优势,可以轻松地将无限物体(敌人,用户,物品)包含在其中。

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

希望这有点帮助 - 不要犹豫。

答案 3 :(得分:0)

正如评论中所述,了解游戏是单人游戏还是多人游戏,回合制游戏还是实时游戏非常重要。因为单人游戏回合制游戏的简单解决方案不适用于多人实时游戏。

对于单人回合制游戏,以下基本概要应该为您提供一种方法(类似Python的伪代码):

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()

如果你是实时而不是回合制,你的主循环可能会改为轮询输入,你可能想要在某种计时器上运行update_world,而不是每次迭代运行一次。对于诸如逐轮战斗的周期性任务,他们也可以使用这样的计时器来完成。能够将未来事件放入按时间排序的队列中,然后每次迭代检查队列的前面是否有待处理的事件,这很有用。

您的命令对象可以执行查找所有相关方并根据需要对其执行操作的任务。它们可以根据需要由PC或NPC使用,如果您希望将来运行,可以将它们推送到未来的事件队列中。显然,对于命令对象有用,他们需要能够在世界中查找事物,例如。查找房间中的所有字符,角色库存中的所有对象,房间中的所有对象等。如果你很狡猾,你可以在一个收容界面周围使用薄包裹器实现几乎所有这些。