小编mik*_*dev的帖子

单一责任原则(SRP)和我的RPG的类结构看起来"怪异"

我正在制作角色扮演游戏,只是为了好玩,并了解有关SOLID原则的更多信息.我关注的第一件事就是SRP.我有一个"角色"类,代表游戏中的角色.它有Name,Health,Mana,AbilityScores等等.

现在,通常我也会在我的Character类中放置方法,所以它看起来像这样......

   public class Character
   {
      public string Name { get; set; }
      public int Health { get; set; }
      public int Mana { get; set; }
      public Dictionary<AbilityScoreEnum, int>AbilityScores { get; set; }

      // base attack bonus depends on character level, attribute bonuses, etc
      public static void GetBaseAttackBonus();  
      public static int RollDamage();
      public static TakeDamage(int amount);
   }
Run Code Online (Sandbox Code Playgroud)

但是由于SRP,我决定将所有方法都移到一个单独的类中.我将该类命名为"CharacterActions",现在方法签名看起来像这样......

public class CharacterActions
{
    public static void GetBaseAttackBonus(Character character);
    public static int RollDamage(Character character);
    public static TakeDamage(Character character, int amount);
} …
Run Code Online (Sandbox Code Playgroud)

c# design-patterns solid-principles

13
推荐指数
2
解决办法
2573
查看次数

帮助实现生物和物品在计算机角色扮演游戏中的交互方式

我正在编写一个简单的角色扮演游戏(学习和娱乐),而我正试图想出一种让游戏对象互相交流的方法.我试图避免两件事.

  1. 创建一个巨大的游戏对象,可以做任何事情并做任何事情
  2. 复杂性 - 所以我远离基于组件的设计,就像你在这里看到的那样

因此,考虑到这些参数,我需要一个关于游戏对象相互执行操作的好方法的建议.

例如

  • 生物(角色,怪物,NPC)可以对生物或物品(武器,药水,陷阱,门)执行操作
  • 项目也可以对Creatures或Items执行操作.一个例子是当角色试图打开胸部时陷阱

我想出的是一种PerformAction可以将生物或物品作为参数的方法.像这样

PerformAction(Creature sourceC, Item sourceI, Creature targetC, Item targetI)
// this will usually end up with 2 null params since
// only 1 source and 1 target will be valid
Run Code Online (Sandbox Code Playgroud)

或者我应该这样做吗?

PerformAction(Object source, Object target)
// cast to correct types and continue
Run Code Online (Sandbox Code Playgroud)

或者是否有一种完全不同的方式我应该考虑这个?

c# class-design

13
推荐指数
1
解决办法
418
查看次数

TDD是否意味着不考虑课堂设计?

我正在制作角色扮演游戏以获得乐趣并尝试在开发时使用TDD.我看到的许多TDD示例都侧重于首先创建测试,然后创建使测试通过所需的对象.

例如:

[Test]
public void Character_WhenHealthIsBelowZero_IsDead()
{
   // create default character with 10 health
   Character character = new Character();
   character.SubtractHealth(20);
   Assert.That(character.IsAlive, Is.EqualTo(false));
}
Run Code Online (Sandbox Code Playgroud)

所以基于此我将创建字符类和适当的属性/方法.这似乎很好,但是我的班级设计真的应该不断改进我的考试吗?这比制定我的游戏提前需要的可能对象更好吗?例如,我通常会想到一个基本的Character类,然后是子类,例如Wizard,Fighter,Theif.

或者是一种平衡的方法?我在哪里绘制出我需要的可能的类和层次结构,但首先编写测试来验证它们实际上是否需要?

c# tdd unit-testing

10
推荐指数
3
解决办法
1053
查看次数

为角色扮演游戏中的"角色"设计一个干净/灵活的方式来施放不同的法术

我正在创建一个角色扮演游戏,以获得乐趣和学习体验.我正处于我的角色(巫师)施放法术的地步.我正在使用战略模式来设置他们在施放法术之前施放的法术.我采用这种方法的原因是因为我希望以后能够添加不同的拼写类型,而不必弄乱角色/向导类.

我的问题 - 这是一个糟糕的设计吗?对此有更好/更清洁/更简单的方法吗?

我试图远离那个试图让一切都融入设计模式的"那个人".但在这种情况下,我觉得这是一个不错的选择.

这是我的代码到目前为止使用2个法术的样子

public class Wizard : Creature
{
   public List<Spell> Spells { get; set; }

   public void Cast(Spell spell, Creature targetCreature)
   {
      spell.Cast(this, targetCreature);
   }
}

public abstract class Spell
{
   public string Name { get; set; }
   public int ManaCost { get; set; }
   public Spell(string name, int manaCost)
   {
      Name = name;
      ManaCost = manaCost;
   }
   public void Cast(Creature caster, Creature targetCreature)
   {
      caster.SubtractMana(ManaCost);
      ApplySpell(caster, targetCreature);
   }
   public abstract void ApplySpell(Creature caster, Creature targetCreature); …
Run Code Online (Sandbox Code Playgroud)

c# design-patterns

9
推荐指数
2
解决办法
3395
查看次数

如何强制派生类包含具有默认值的某些属性

我有一个角色扮演游戏的类结构,看起来像这样......

public abstract class Item
{
   public abstract string Name { get; set; }
}

public abstract class Armor : Item
{
   public override string Name { get; set; }
}

public class Helmet : Armor
{
   public override string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

基本上,我试图强制每个派生类型包含"名称"属性.这是最好的方法吗?我知道我可以从Item.Name中删除"abstract",然后删除Armor和Helmet中的重写"Name"属性.如果我这样做,代码看起来有点干净,但我可能忘记在这些派生类中设置base.Name.

有人可以帮我告诉我最好的方法吗?

编辑:对不起,让我再澄清一下我的问题.我想确定两件事.1)Name属性存在于所有派生类中2)Name属性不为null或为空

我基本上想强制任何派生自Item(并且不是抽象)的类具有Name的值.

c# abstract-class derived-class

8
推荐指数
1
解决办法
7819
查看次数

在角色扮演游戏中暂时将玩家转变为动物的设计考虑因素

我正在开发一款角色扮演游戏,用于娱乐和练习设计模式.我希望玩家能够将自己变成不同的动物.例如,德鲁伊可能会变成猎豹.现在我正计划使用装饰模式来做这个,但我的问题是 - 我怎么做到这样当德鲁伊处于猎豹形态时,他们只能获得猎豹的技能?换句话说,他们不应该能够获得他们正常的德鲁伊技能.

使用装饰模式看来,即使在猎豹形态下,我的德鲁伊也能够获得他们正常的德鲁伊技能.

class Druid : Character
{
   // many cool druid skills and spells
   void LightHeal(Character target) { }
}

abstract class CharacterDecorator : Character
{
    Character DecoratedCharacter;
}

class CheetahForm : CharacterDecorator
{
    Character DecoratedCharacter;
    public CheetahForm(Character decoratedCharacter)
    {
       DecoratedCharacter= decoratedCharacter;
    }

    // many cool cheetah related skills
    void CheetahRun()
    {
       // let player move very fast
    }
}
Run Code Online (Sandbox Code Playgroud)

现在使用这些类

Druid myDruid = new Druid();
myDruid.LightHeal(myDruid); // casting light heal here is fine
myDruid = new CheetahForm(myDruid); …
Run Code Online (Sandbox Code Playgroud)

c# design-patterns decorator

7
推荐指数
1
解决办法
365
查看次数

循环单元测试不好?

我有一个单元测试,依赖于随机掷骰子.我滚动了一个20面的模具,如果它是20,它就算是一个重要的打击.

我现在正在做的是将20面模具滚动300次.如果这些卷中的任何一个是20,那么我知道我有一个致命的打击.

这是代码的样子:

public class DiceRoll
{
    public int Value { get; set; }
    public bool IsCritical { get; set; }

    // code here that sets IsCritical to true if "Value" gets set to 20
}

[Test]
public void DiceCanRollCriticalStrikes()
{
    bool IsSuccessful = false;
    DiceRoll diceRoll = new DiceRoll();

    for(int i=0; i<300; i++)
    {
        diceRoll.Value = Dice.Roll(1, 20); // roll 20 sided die once
        if(diceRoll.Value == 20 && diceRoll.IsCritical)
        {
            IsSuccessful = true;
            break;
        }
    }

    if(IsSuccessful)
        // test …
Run Code Online (Sandbox Code Playgroud)

c# unit-testing loops dice

3
推荐指数
1
解决办法
796
查看次数

如何在角色扮演游戏中设计类以允许多类化?

我正在编写一个游戏作为练习,我遇到了一个设计问题.我的角色扮演游戏将有典型的类,如战士,向导,Theif,牧师.如何设计课程以便玩家可以多班?例如,一个玩家可能从战斗机开始(并获得相关技能的战士),然后多级到一个巫师(此时他们获得向导法术),后来再多个级别又一个流氓(现在获得所有能力的流氓有).所以这个玩家现在是战斗机向导 - 盗贼.我不知道在C#中表示这个.

起初我尝试使用装饰器模式,但我不能多次多次使用它.关于如何设计这个的任何指针?

我唯一能想到的就是IList<CharacterBaseClass>为每个角色拥有一个属性,并将Fighter,Wizard,Rogue等添加到玩家多类中.所以像这样......

class CharacterBaseClass
{
   public IList<CharacterBaseClass> MultiClasses { get; set; }
   // constructors, etc
}
Run Code Online (Sandbox Code Playgroud)

每次我们将它们添加到IList中

// player starts off as Fighter
Warrior player1 = new Warrior();

// now multi-class to Wizard
player1.MultiClasses.Add(new Wizard()); 

// now multi-class to Theif
player1.MultiClasses.Add(new Theif());    
Run Code Online (Sandbox Code Playgroud)

我敢肯定必须有比这更好的方法吗?

c# design-patterns decorator

2
推荐指数
1
解决办法
4135
查看次数

设计角色扮演游戏中典型角色的类层次结构

我正在尝试设计一个简单的角色扮演游戏,它具有典型的角色类型,如战斗机,巫师,牧师,小偷等.我需要建议一个好的方法来设置类层次结构.

我最初的尝试是创建一个类型为"Character"的类,并使"Character"中的战士,向导,牧师,派生类型.

但后来我认为创建一个"Character"类然后使用装饰模式会更好.所以说战斗机装饰,精灵装饰等.

或者有更好的方式吗?

c#

1
推荐指数
1
解决办法
2580
查看次数