在我的程序中,绘图的源矩形可以是常规矩形,空矩形或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
答案 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)
{
...
}
}
我希望您现在对扩展方法有一个了解,以及如何使用它们来轻松解决您的问题;)