• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

SOLVED Draw Nine Slice Sprite on Scaled up GUI

Hello, everyone! I'll go straight to the point:
I want to draw a textbox sprite that uses nine slice on the GUI layer, but it appears tiny because my GUI is scaled up.

Got any suggestion?
Thank you!
 
If they are objects, you can use image_xscale and image_yscale, or for sprites, you can use something like draw_sprite_stretched. I tend to use objects for things that I need to be referenced or move dynamically. Anything static or non-referenced works fine as a sprite.

Alternatively, depending on your setup, you can pre-place your UI and deactivate/use “visible = false;” until you need them. For example, my turn-based battle sequence happens in a battle room where I have all of my UI elements laid out ahead of time. I like this method because it is much more visual than using solely code to draw/create the elements. In this scenario, I imagine you would have to update the UI elements’ coords depending on your camera though, if your room is larger than your camera view.

There may be other ways, but this is what I have done.
 

Alice

Darts addict
Forum Staff
Moderator
I guess the simplest approach would be not to draw it to the GUI layer but in a regular Draw event instead, so it would be drawn to the application surface and upscaled along with that. Drawing it at a really low depth should do the job, as long as there aren't other objects with Draw GUI events that should be drawn below it. You don't need to add the layer in the room explicitly, either, just setup the layer in code instead.

If the above is not viable, not-so-simple approach would be drawing the textbox sprite to a surface, and then draw the upscaled surface.

Otherwise, I can't think of a nice and intuitive way to draw a sprite with part of upscaling being done 9-slice way, and other part being upscaled the regular way.

@stardust9000 Are you sure that draw_sprite_stretched works for 9-slice sprites? The thing about 9-slice sprites is that they are scaled by drawing the corners at a fixed scale, and stretching/tiling/whatever the sides and the middle instead.
 

Alice

Darts addict
Forum Staff
Moderator
I did a quick test, and this is what I got for drawing a 9-slice with draw_sprite_stretched:

Which is pretty much 9-slice acting as a 9-slice, and that matches my expectations.

Now, the impression I got from the opening post - correct me @David Lorenz if I'm wrong - is that the goal is to draw the 9-slice sprite with part-regular part-9-slice upscaling.
So suppose that there is a 9-slice textbox sprite with 64x64 dimensions, and it's drawn on regular scale GUI with 80x234 size or so.

Then, the user turns on the fullscreen mode and the whole game is upscaled to, say, 1.5 factor. The result we want is everything - ingame elements, GUI, etc. to be simply drawn 1.5 larger.
However, with draw_sprite_stretched it will be drawn using regular 9-slice logic, so instead of getting the 80x234 part drawn wholly with scale 1.5 (corners, sides, middle), we get corners drawn at regular size, while sides and middle are stretched. And then such textbox sticks out among the other sprites.
 
@Alice My problem was that all the sprites on my GUI layer are drawn scaled up because my GUI layer is bigger than the view_camera, and drawing nine-slice sprites consequently resulted out of scale.
Practically, a pixel of a nine-slice sprite resulted 4 times smaller than a pixel of a normal sprite drawn scaled up in the Draw GUI event. 4 times because my GUI is 4 times the size of the view_camera. :)

I guess the simplest approach would be not to draw it to the GUI layer but in a regular Draw event instead, so it would be drawn to the application surface and upscaled along with that.
I did what you suggested and it did the trick! Thank you! Unfortunately, I now need to rework some of my code. Nothing terrible, but still... It's strange that there's no way of scaling the nine-slice through the Draw GUI event.

Thanks, again! :D
 

gnysek

Member
It's strange that there's no way of scaling the nine-slice through the Draw GUI event.
There is, you just need to scale whole drawing using matrices, I'm not good at it, but I've tested and this seems to work:

GML:
    var _gui_scale = 3; // image will be 3x bigger
    var _m = matrix_get(matrix_world); // get current matrix
  
    var _new_m = matrix_build(0,0,0, 0,0,0, _gui_scale, _gui_scale, 0);
    matrix_set(matrix_world, _new_m);
  
    draw_sprite_stretched(Sprite1, 0, 20, 20, 200, 200);
  
    matrix_set(matrix_world, _m); // revert matrix
I also think, that playing with x/y in matrix_build would help to not scale x/y starting position, but as I said - I'm not good at it :p

1639054056233.png
 
Top