【问题标题】:Modying Properties of a Class修改类的属性
【发布时间】:2009-08-20 18:57:55
【问题描述】:

为这个问题找到一个合适的问题标题和 -tags 让我很吃惊。

基本上,我已经构建了一个游戏,其中会出现多个单位/生物。现在我对构建一个系统很感兴趣,因此每个单元都可以应用效果/增益/减益,从而修改单元的属性。此类效果的示例可能是降低单位移动速度的霜冻效果、健康提升等。计划是通过脚本实现这些效果,以便可以创建自定义用户效果。

我正在寻找有关如何实现此功能的建议。现在我已经考虑过创建一个效果类。然后每个应用的效果都将是该类的一个实例,并且会引用它应用到的单元。 effect 至少有两个方法,apply 和 unapply 方法分别用于应用和取消应用。

问题在于,它不允许使用不同的累积百分比方式。比如,如果值 100 等于 120 或 121,则 10% 的两倍增加。

这并不重要,但它是用 C# 编码的

【问题讨论】:

    标签: c#


    【解决方案1】:

    你在 Effect 类的正确轨道上。但保留每个单位的效果列表,而不是让效果指单位。当你想获取一个属性值时,查询你需要的那个,而不是使用 apply() 和 unapply() 函数来修改基值(这可能导致底层值由于浮点错误等而漂移)。

    您的 Effect 类可以有一个 Modify() 方法,该方法将输入值作为浮点值,并返回修改后的值。查询一个属性最终看起来像这样的伪代码:

    def get_movement_speed():
        value = base_movement_speed() # this is intrinsic to the unit
        for effect in movement_speed_effects_list:
            value = effect.modify(value)
        return value
    

    万一您有太多效果而导致效率低下,请缓存这些值并在每次添加或删除效果时重新计算它们。

    【讨论】:

    • 这确实比我的回答更有意义。 +1
    【解决方案2】:

    您是否考虑过Decorator 模式?在tutorial 中可以找到一个实际示例。

    我写了一个小例子来说明你的具体情况。 UnitWithPowerUp 类接受一个 Unit 对象(它可能已经被装饰,也可能没有被装饰)。当你在这个类上调用 Health() 时,它会获取 Unit 的生命值,并在默认值 100 的基础上增加 10%。如果你已经对其进行了两次装饰,它将返回 121。调用 GetDescription( ) 在单个装饰的 Unit 上返回“Unit + Power Up”。同样,双重装饰的 Unit 返回“Unit + Power Up + Power Up”。

        public abstract class Unit
        {
    
          public virtual string GetDescription()
          {
             return "Unit";
          }
    
          public virtual double Cost()
          {
             return 100;
          }
       }
    
       public abstract class EffectDecorator : Unit
       {
          public EffectDecorator()
          {
          }
       }
    
    
    
       public class UnitWithPowerUp : EffectDecorator
       {
          Unit unit;
    
          public UnitWithPowerUp(Unit unit)
          {
             this.unit = unit;
          }
    
          public override string GetDescription()
          {
             return unit.GetDescription() + " + Power Up";
          }
    
          public override double Health()
          {
             return unit.Health() * 1.10;
          }
       }
    

    我没有测试代码或任何东西,只是为了展示这个概念。如果您认为这很有用,我建议您获取一份Head First Design Patterns 的副本。

    【讨论】:

    • 我不确定这对我有什么帮助。
    • 向类动态添加新的或附加的行为或属性是装饰器模式的定义,类似于将“效果”添加到“单元”。
    • 在运行时更改这些属性并不适合,但这是他需要的。
    【解决方案3】:

    如果您计划编写脚本来制作一些效果(这对于具有大量效果的游戏来说可能很好),您可以继续利用 C# 在运行时编译的能力Reference。本质上,您可以在 C# 中编写您想要的所有内容,将字节码保存在某处(可能作为关卡文件或扩展包或其他任何内容的一部分),然后让效果在每次关闭时执行适当的 C# 代码。

    【讨论】:

      【解决方案4】:

      在做需要动态改变对象状态的游戏时,看看组件系统/实体系统设计。

      到目前为止,我见过的关于这个主题的最好的文章是

      http://www.devmaster.net/articles/oo-game-design/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-01-05
        • 2011-03-10
        • 2011-06-16
        • 2019-09-12
        • 2021-11-25
        • 2016-11-10
        • 1970-01-01
        相关资源
        最近更新 更多