【问题标题】:How should I structure the logic of an object oriented Role-playing game?我应该如何构建面向对象的角色扮演游戏的逻辑?
【发布时间】:2026-01-13 20:30:02
【问题描述】:

请在我的游戏player 类中查看此方法:

public void eatSomethingt(Items eatable)
{
    foreach (Items i in items)
    {
        if (i is Ieatable && i.name == eatable.name) //Give items an ID in the future
        {
            Ieatable k = i as Ieatable;
            k.eat(this);
            items.Remove(i);
            break;
        }
    }
}

基本上这将遍历玩家拥有的物品列表并比较它们以检查传入的参数是否可食用,如果是,则检查玩家是否有。如果它进入 IF 语句,那么该项目将从玩家背包中移除(items)

问题出在这行:k.eat(this) 发送到这个方法:

public void eat(Player p)
{
    Console.WriteLine(p.Name + " Ate the " + name);
    p.life = p.life + amountHealed;
}

这感觉有点“乒乓”,因为它是 Fruit 类将物品提供给玩家。由于我的Fruitclass 实现了接口iEatable(这肯定是有意义的),我必须在实现它的类中放置一个eat 方法。

【问题讨论】:

  • 我认为玩家应该有eat方法而不是ieatable。
  • 嗯,对游戏一无所知,但eat 不应该更像:void eat(IIsFood)?如果需要,当然可以用另一种方法随机化...IIsFood 会喜欢:int hprestored 等...
  • 为什么不引入一个负责进食的 Mouth 类 :-) 这样您就可以移出将在玩家(上帝对象)内部编写的各种职责。
  • 如果你的代码有很多这样的限制,LINQ 将是一个有价值的朋友。

标签: c# oop interface


【解决方案1】:

我觉得应该是玩家的一种方法:

更正确的IEatable应该是IEdible甚至IConsumable

public class Player
{
    .
    .
    public string Name {get;set;}
    public int Life {get;set;}
    .
    .
    public void eat(IEdible food)
    {
        Console.WriteLine(Name + " Ate the " + food.name);
        life += food.amountHealed;
    }
}

【讨论】:

  • Imo eat 应该是玩家实现的ICanEat 接口中的一个void ......这不是更合理(即可以用于其他小怪等)吗?
  • @StefanDenchev 我认为你是对的,但我只是想给出一个大概的想法。
【解决方案2】:

争取看起来像自然语言的代码。例如,将Console 告诉Write(a)Line 确实有意义。告诉食物吃是没有意义的。食物本身应该被吃掉。此外,食物很少有动画——它不会与环境发生任何互动,因此问问自己它是否真的应该有任何方法?我现在唯一想出的可能是Rot 方法,但这也可以在导致食物腐烂的细菌类中实现。解决此任务的最 OOP 方式似乎是:

  1. 食物应该是一个没有方法的结构
  2. 将所有工作委托给播放器

其次,为什么要传递 Items 实例而不是 IEdible?而是这样定义方法:

public void eatSomething(IEnumerable<IEdible> eatable)

这样,任何试图传递不能被吃掉的东西的尝试都会在编译时被捕获。它还删除了if 语句的第一个条件。

第三,使用 LINQ 来缩短你的代码。

【讨论】:

    最近更新 更多