扩展方法是解决这个问题的方法吗?

时间:2011-08-14 14:54:45

标签: c# winforms

在我的程序中,绘图的源矩形可以是常规矩形,空矩形或X或Y为-1的矩形。如果矩形是正常的(例如(0,0,64,64)),那么它只是从纹理中绘制出来。如果它是Rectangle.Empty,它什么都不绘制,只是继续循环。如果源矩形的X或Y为-1,则确定它是碰撞图块。

这个问题是-1不直观。这是一个令人困惑和糟糕的解决方案。此外,如果有更多的瓷砖类型,它将开始变得荒谬,如-2表示缓慢的瓷砖或-3表示水瓦片。

另一个问题是,由于我不知道早期会有碰撞瓦片和普通的XNA矩形很好,整个系统(幸好目前只有大约1000行代码)使用XNA矩形。我想我将不得不在这一点上单独上课并更新所有内容,但我不确定。

对此有什么好的解决方案?我根本没有涉足扩展方法。它们是否可以应用于Rectangle类并获得类似IsCollisionTile()或IsBlankTile()的方法?最初我希望我可以从Rectangle类派生出一个Tile类,但不幸的是这个类是密封的。我想另一个简单的解决方案可能就是创建一个全局常量类,其中-1为CollisionTile,0为BlankTile,等等。这至少会使它更容易理解,但这对我来说仍然看起来很难看:

if (tiles[y, x].X == Constants.BlankTile)
    continue;

if (tiles[y, x].X == Constants.CollisionTile)
{
    Utility.DrawRectangle(spriteBatch, new Rectangle(x * TileSize, y * TileSize, TileSize, TileSize), collisionTileColor);
    continue;
}

spriteBatch.Draw(tileset, new Rectangle(x * TileSize, y * TileSize, TileSize, TileSize), tiles[y, x], Color.White);

如果只有一个属性,我可以使用Tag作为控件。我真的不想放弃使用Rectangle类,因为它嵌入到系统中,程序纯粹是功能性的,在这方面并不美观。理想情况下,我更喜欢一种解决方案,只允许将Rectangle类扩展到某种程度上能够与客户端通信它应该是什么样的磁贴。

那么,这比我原先希望的打字要多得多。很抱歉长时间阅读x_x

3 个答案:

答案 0 :(得分:2)

我建议设置全局常量。在这种情况下出现扩展方法的问题是因为Rectangle是一个结构,一个值类型。这意味着您的扩展方法正在使用矩形的副本,而不是原始副本。

答案 1 :(得分:1)

如果这个类不能继承(这通常是适当的解决方案。对你微软感到羞耻!)那么扩展方法可能会像你描述的那样正常工作。 问题是 - IMO通常使用C#和OOP来减少使用类似getter的方法的风格。这就是吸气剂的用途。 因此,我认为全局常量选项更符合一般风格,但这只是我的观点。

从一个完全程序化的POV - 两个方法都有效,其中全局常量类可能稍微快一点(虽然我不确定)

答案 2 :(得分:0)

一开始,您应该考虑,何时使用您的方法

IsCollisionTile() and IsBlankTile()

您有两种选择:
*)你想在全球范围内使用它,那么你最好写一个实用程序类,让你的方法就在你需要的地方:

public static class CollisionHelper
{
  public static Boolean IsCollisionTile(ITile tileToCheck) 
  {
    ...
  }
}

*)其次,如果你只想在你的瓷砖上使用它,你应该明确地写一个扩展方法,例如接受每个ITile-Object。扩展方法是广泛扩展类功能的好方法。样本可以是:

public class RectangleTile : ITile
{
  public static Boolean IsCollisionTile(this ITile tileToCheck)
  {
    ...
  }
}

我希望您现在对扩展方法有一个了解,以及如何使用它们来轻松解决您的问题;)