我将使用特定的用例来描述我的问题,但是考虑到可能还有其他应用程序希望基于某些默认值创建子类,因此它应该更广泛地适用。这并不是要“为我做功课”的问题。
我目前正在开发一个简单的俄罗斯方块游戏,在其中我将游戏场定义为填充有布尔值的二维数组。我在类Grid中做到了这一点,以添加功能并拆分代码。我已经开发了一个函数,该函数可以让我检查是否可以在特定位置的顶部添加另一个网格,以检查是否可以将tetromino移动到特定位置。(并非两个布尔值都在同一位置)
由于tetrominos(也是网格)具有预定义的形状和大小,因此只需创建一次每个形状,然后我就可以将当前的下降块设置为该预定义的tetromino的副本,以按需要进行操作。
现在,我知道两种初始化这些预定义形状的方法:在初始化程序的主Tetris类中启动它们,在此我为每个tetromino调用一次Grid(Columns,Rows)并手动将正确的坐标设置为true,或者创建第二个构造函数在Grid类中,该类采用一个char(四口号名称L,J,S,Z,T,X,I),并使用我已经构建的其他构造函数初始化3x3或4x4网格,然后手动将正确的坐标设置为true再次。
这两种方法都给这些类增加了混乱感。我希望有可能改为使用子类,因为从技术上讲,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是不可变的,您只需要初始化一次并根据需要重复使用它们多次。
另外,我对源自的四联蛋白并不是很确信Grid
。在我看来,它们在概念上是非常不同的。前者是预设的不可变块,后者是动态变化的竞争环境。我根本不会将这两个元素混为一谈。我将创建一个特定的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];
}
现在,在您Tetris
或您的Grid
班级内部,您将可以与Tetromino
s一起工作,而不必关心它们的真正形状。要生成一个特定的字段,您只需使用相应的字段即可;myPlayingGrid.Add(Tetromino.J)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句