Why is my sprite stretched wrong?


The edges of the sprite should be 1 pixel thick, but they also stretch

I used the code from here

I’m not really sure what I’m looking at, let alone the problem. Can you be more specific?

Only the middle should stretch. The edges too, but along the middle

What is the sprite you’re trying to stretch? Can you produce an example of what you want, to contrast with what you see?

Like this

This is what you’re trying to achieve? In which case, your sprite isn’t being stretched wrong; it is being scaled uniformly, as would be expected.

So, I think the question instead becomes, how do you achieve what you want. Let me get back to you on that.

I’m a little confused about curr_rectangle; it looks like it’s being used as both the source and destination location (albeit sliced differently in the latter). Is that correct?
Also, what are the dimensions of your source image/texture?

I have so far left it for later. Maybe someday I’ll do this feature. Thanks…

The DestinationRectangle should be the entire region you want to draw over. If you want to draw this sliced rectangle at a scale of 200x100 at position 500, 300, for instance, you will need to create a new rectangle at that position and scale (Ex. new Rectangle(500, 300, 200, 100)).

I also have an improved nine-sliced implementation that is easier to read and has a method to get each individual region by index, which does not generate garbage like with the Rectangle array. You won’t be able to drag and drop it into your project, but the amount you need to adjust it is minimal.

1 Like

The answer at first glance is because you are trying to scale using the actual scale function which would make a multi step problem into a complex one.

You can do it like that but beware down scaling. Note the example in the image below in red if i downscaled that any more it would be a mess.

Here is a method that i typed out that does what your trying to achieve.
It outputs the following from top left to bottom right
the original image, the upscaled image, the down scaled image.

        public void DrawInnerExpandedEdgeMaintained(Rectangle destination, Rectangle source, Color color, float edgeMarginPercentage)
        {
            int sideSizeW = (int)(source.Width * edgeMarginPercentage);
            int midSizeW = (int)(source.Width - sideSizeW *2);
            int sideSizeH = (int)(source.Height * edgeMarginPercentage);
            int midSizeH = (int)(source.Height - sideSizeH * 2);

            int sx0 = 0;
            int sy0 = 0;
            int sx1 = sideSizeW;
            int sy1 = sideSizeH;
            int sx2 = source.Width - sideSizeW;
            int sy2 = source.Height - sideSizeH;
            int sInnerWidth = source.Width - sideSizeW * 2;
            int sInnerHeight = source.Height - sideSizeH * 2;

            int dx0 = destination.X;
            int dy0 = destination.Y;
            int dx1 = destination.X + sideSizeW;
            int dy1 = destination.Y + sideSizeH;
            int dx2 = destination.X + destination.Width - sideSizeW;
            int dy2 = destination.Y + destination.Height - sideSizeH;
            int dInnerWidth = destination.Width - sideSizeW * 2;
            int dInnerHeight = destination.Height - sideSizeH * 2;

            // left top
            spriteBatch.Draw(texture, new Rectangle(dx0, dy0, sideSizeW, sideSizeH), new Rectangle(sx0, sy0, sideSizeW, sideSizeH), color);
            // mid top
            spriteBatch.Draw(texture, new Rectangle(dx1, dy0, dInnerWidth, sideSizeH), new Rectangle(sx1, sy0, sInnerWidth, sideSizeH), color);
            // right top
            spriteBatch.Draw(texture, new Rectangle(dx2, dy0, sideSizeW, sideSizeH), new Rectangle(sx2, sy0, sideSizeW, sideSizeH), color);
            // left mid
            spriteBatch.Draw(texture, new Rectangle(dx0, dy1, sideSizeW, dInnerHeight), new Rectangle(sx0, sy1, sideSizeH, sInnerHeight), color);
            // mid mid
            spriteBatch.Draw(texture, new Rectangle(dx1, dy1, dInnerWidth, dInnerHeight), new Rectangle(sx1, sy1, sInnerWidth, sInnerHeight), color);
            // right mid
            spriteBatch.Draw(texture, new Rectangle(dx2, dy1, sideSizeW, dInnerHeight), new Rectangle(sx2, sy1, sideSizeW, sInnerHeight), color);
            // left bottom
            spriteBatch.Draw(texture, new Rectangle(dx0, dy2, sideSizeW, sideSizeH), new Rectangle(sx0, sy2, sideSizeW, sideSizeH), color);
            // mid bottom
            spriteBatch.Draw(texture, new Rectangle(dx1, dy2, dInnerWidth, sideSizeH), new Rectangle(sx1, sy2, sInnerWidth, sideSizeH), color);
            // right bottom
            spriteBatch.Draw(texture, new Rectangle(dx2, dy2, sideSizeW, sideSizeH), new Rectangle(sx2, sy2, sideSizeW, sideSizeH), color);
        }

Its called in draw like so.

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here

            spriteBatch.Begin();

            Rectangle source = new Rectangle(0, 0, texture.Width, texture.Height);

            spriteBatch.Draw(texture, new Rectangle(0, 0, texture.Width, texture.Height), source, Color.ForestGreen);

            DrawInnerExpandedEdgeMaintained(new Rectangle(100,100, 500,500), source, Color.White , .23f);

            DrawInnerExpandedEdgeMaintained(new Rectangle(200, 200, 150, 150), source, Color.Firebrick, .23f);

            spriteBatch.End();

            base.Draw(gameTime);
        }
2 Likes