【问题标题】:Creating Specific Class Instances Through a Subclass in C#在 C# 中通过子类创建特定的类实例
【发布时间】:2016-10-06 00:44:51
【问题描述】:

我将使用我的特定用例来描述我的问题,但考虑到可能有其他应用程序需要基于某些默认值创建子类,它应该更广泛适用。这并不是一个“为我做作业”的问题。

我目前正在开发一个简单的俄罗斯方块游戏,我将我的比赛场地定义为一个充满布尔值的二维数组。我在 Grid 类中执行此操作以添加功能并拆分我的代码。我开发了一个功能,可以让我检查是否可以在某个位置在其顶部添加另一个 Grid,以检查是否可以将 tetromino 移动到某个位置。 (不是在一个位置上的两个布尔值都为真)

由于 tetromino(也是一个网格)具有预定义的形状和大小,因此只需创建每个形状一次,然后我可以将当​​前的下降块设置为该预定义的 tetromino 的副本,以便按照我的意愿进行操作。

现在我知道了两种初始化这些预定义形状的方法:在初始化程序的主要俄罗斯方块类中启动它们,我为每个 tetromino 调用一次 Grid(Columns, Rows) 并手动将正确的坐标设置为 true,或者创建Grid 类中的第二个构造函数,它接受一个字符(四元组名称 L、J、S、Z、T、X、I)并使用我已经构建的另一个构造函数初始化一个 3x3 或 4x4 网格,然后手动设置正确的坐标再次为真。

这两种方法都给这些类增加了混乱,感觉很丑。我希望可以改用子类,因为从技术上讲,tetriminos 是一种特定类型的网格

据我所知,现在子类中的构造函数只能传递给子类构造函数的默认参数或参数,如下所示:

class Grid
{
    bool[,] grid;

    public Grid(int x, int y)
    {
        // Creates grid, fills it with bools.
    }
}

class Block : Grid
{
    public Block(char blockShape, int x, int y) : base(x, y)
    {
        // Add additional logic here.
    }
}

现在这需要我传递 tetromino 的尺寸,考虑到这将是预设的,这感觉很奇怪。我更喜欢的是这些方面的东西:

class Block : Grid
{
    public Block(string blockShape)
    {
        if ("IX".Contains(blockShape))
        {
            this = new Grid(4, 4);
            // Add additional logic here.
        }
        if ("JLSZT".Contains(blockShape))
        {
            this = new Grid(3, 3);
            // Add additional logic here.
        }
    }
}

这方面的事情可能吗?如果是这样,怎么可能做到?如果没有,是否有一个干净的替代解决方案不会弄乱我的 Grid 或 Tetris 类?我应该做点别的吗?

【问题讨论】:

  • Tetrominos - 哇,这是一个词!

标签: c# class constructor subclass tetris


【解决方案1】:

我只是使用静态只读字段。 Tetrominos 是不可变的,您只需初始化它们一次,然后根据需要多次重复使用它们。

另外,我不太相信源自Grid 的 tetrominos。对我来说,它们在概念上是非常不同的东西。前者是预设的不可变块,后者是动态变化的游戏环境。我根本不会把这两个元素混为一谈。我会创建一个特定的Tetromino 类:

public class Tetromino
{
    public static readonly Tetromino J = new Tetromino(new[,] { { false, false, true }, .... });
    public static readonly Tetromino L = new Terromino(new[,] { { true, false, false } .... });
    //and so on...

    private readonly bool[,] grid;
    private Tetromino(bool[,] shape) //disallow any other Terronimos from being built.
    {
         this.shape = shape;
         Width = shape.GetLength(0);
         Height = shape.GetLength(1);
    }

    public int Height { get; }
    public int Width { get; }
    public bool this[int row, int col] => shape[row, col];
}

现在在您的 TetrisGrid 类中,您可以使用 Tetrominos 而不关心它们的实际形状。要生成一个特定的,您只需使用相应的字段; myPlayingGrid.Add(Tetromino.J)

【讨论】:

  • 谢谢,我想我会去做,并在 init 中实例化一次该类。它确实应该将代码转移到一个单独的文件中,这最终是我所追求的。我只是希望它可以更整洁。为四联体使用网格类的原因是我简化了;网格存储节点,而不是布尔值,它还包含块的颜色。这将允许我为网格对象创建一个函数,这将让我在实际放置之前在特定位置的网格顶部绘制 tetromino。以及允许旋转 tetromino 的克隆。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-22
  • 2017-04-10
  • 1970-01-01
  • 2021-03-14
  • 1970-01-01
相关资源
最近更新 更多