IndexOutOfRangeException,没有机会获得它

时间:2017-10-17 11:34:18

标签: c# xna visual-studio-2017 monogame

我在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之间)

有什么我无法看到的吗?

2 个答案:

答案 0 :(得分:1)

colorData的索引从0开始到width * height。您正在访问从rec.X + rec.Y * width(rec.X + width) + (height + rec.Y) * height的索引。如果rec.Xrec.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。总而言之,绝对有可能超越你的功能。我建议你重写它,因为它似乎是一个可怕的意大利面条代码案例。