我在XNA中编写游戏,创建了从纹理中获取子图像的简单方法,但每次使用它时,都会引发异常。我检查了变量,没有机会超出范围。以下两种方法的代码:
public Color[] GetSubImage(Color[] colorData, int width, Rectangle rec)
{
Color[] color = new Color[rec.Width * rec.Height];
for (int x = 0; x < rec.Width; x++)
{
for (int y = 0; y < rec.Height; y++)
{
color[x + y * rec.Width] = colorData[x + rec.X + (y + rec.Y) * width]; // Exception is thrown there
}
}
return color;
}
public void LoadSubImages(Texture2D sourceSpritesheet, List<Texture2D[]> destinationSprites)
{
int count = 0;
Color[] imageData = new Color[sourceSpritesheet.Width * sourceSpritesheet.Height];
Texture2D subImage;
Rectangle sourceRec;
destinationSprites = new List<Texture2D[]>();
for (int i = 0; i < this.NUMFRAMES.Length; i++)
{
Texture2D[] bi = new Texture2D[this.NUMFRAMES[i]];
for (int j = 0; j < this.NUMFRAMES[i]; j++)
{
sourceRec = new Rectangle(j * this.FRAMEWIDTHS[i], count, this.FRAMEWIDTHS[i], this.FRAMEHEIGHTS[i]);
Color[] imagePiece = this.GetSubImage(imageData, sourceSpritesheet.Width, sourceRec);
subImage = new Texture2D(Game1.Instance.GraphicsDevice, sourceRec.Width, sourceRec.Height);
subImage.SetData<Color>(imagePiece);
bi[j] = subImage;
}
destinationSprites.Add(bi);
count += this.FRAMEHEIGHTS[i];
}
}
sourceSpritesheet为368 * 550 big,FRAMEWIDTHS = 46,FRAMEHEIGTHS = 50,NUMFRAMES.Length = 11(值介于1-8之间)
有什么我无法看到的吗?
答案 0 :(得分:1)
colorData
的索引从0
开始到width * height
。您正在访问从rec.X + rec.Y * width
到(rec.X + width) + (height + rec.Y) * height
的索引。如果rec.X
或rec.Y
大于0
(考虑到如何构建矩形,将发生这种情况),这将超出范围。 .NET Framework数组运行正常,Universe是安全的......
答案 1 :(得分:1)
colorData
的大小为202,400
在最糟糕的情况下:
colorData[x + rec.X + (y + rec.Y) * width];
x = 45
rec.x = 7*46 = 322
y = 50
rec.y = 11*50 = 550
width = 368
由于操作顺序,您的公式将如下执行:
x + rec.X + ((y + rec.Y) * width)
45 + 322 + ((50 + 550) * 368)
367 + (600 * 368)
221,167
和221,167大于colorData
大小202,400。总而言之,绝对有可能超越你的功能。我建议你重写它,因为它似乎是一个可怕的意大利面条代码案例。