Goombert
|
|
Posted on: May 01, 2016, 07:09:11 pm |
|
|
Location: Cappuccino, CA Joined: Jan 2013
Posts: 2993
|
This was requested of me to write a script that can do this. Drawing sprites this way makes it easier to scale parts of them without messing up and blurring the corners. This is especially useful for rendering UI controls. NOTE: These scripts should work in older GM versions, but if you are using Studio or ENIGMA you may want to replace control variable increments (such as += 1 in a for loop) with ++i as an optimization because preincrement is faster. If you are using ENIGMA then it is even faster to just use an int with preincrement. // this works in old GM versions but is slower for (i = 0; i < 3; i += 1) { // this is faster and only works in GMS, ENIGMA, or C++ for (i = 0; i < 3; ++i) { // this is the fastest in both ENIGMA or C++ for (int i = 0; i < 3; ++i) {
This is what a 9-patch sprite looks like: My first attempt makes use of a single sprite and its subimages. /// draw_sprite_patch(sprite, x, y); /// by Robert B. Colton /// /// draws a 9 patch sprite with x, y as the top-left corner /// subimages are in the order: top-left, top-center, top-right, /// middle-left, middle-center, middle-right, bottom-left, bottom-center, bottom-right
var spr = argument0; var xx = argument1, yy = argument2; var ww = sprite_get_width(argument0), hh = sprite_get_height(argument0);
for (i = 0; i < 3; i += 1) { for (j = 0; j < 3; j += 1) { draw_sprite( spr, j + (i * 3), xx + j * ww, yy + i * hh); } }
My second attempt actually adds the arguments for scaling. If you wanted to center it around the x, y parameter you can just subtract the sprite origin from xx and yy. /// draw_sprite_patch(sprite, x, y, stretchedWidth, stretchedHeight); /// by Robert B. Colton /// /// draws a 9 patch sprite with x, y as the top-left corner where the middle and /// center row and column is stretched to the given width and height /// subimages in the order: top-left, top-center, top-right, /// middle-left, middle-center, middle-right, bottom-left, bottom-center, bottom-right
var spr = argument0; var xx = argument1, yy = argument2; var sw = argument3, sh = argument4; var ww = sprite_get_width(spr), hh = sprite_get_height(spr);
// top-left and top-right corners do not need scaled draw_sprite(spr, 0, xx, yy); draw_sprite(spr, 2, xx + ww + sw, yy);
// bottom-left and bottom-right corners do not need scaled draw_sprite(spr, 6, xx, yy + hh + sh); draw_sprite(spr, 8, xx + ww + sw, yy + hh + sh);
// top-center and bottom-center need stretched horizontally draw_sprite_stretched(spr, 1, xx + ww, yy, sw, hh); draw_sprite_stretched(spr, 7, xx + ww, yy + hh + sh, sw, hh);
// middle-left and middle-right needs stretched vertically draw_sprite_stretched(spr, 3, xx, yy + hh, ww, sh); draw_sprite_stretched(spr, 5, xx + ww + sw, yy + hh, ww, sh);
// middle-center needs stretched horizontally and vertically draw_sprite_stretched(spr, 4, xx + ww, yy + hh, sw, sh);
And my last attempt uses a single subimage of a single sprite. /// draw_sprite_patch(sprite, subimg, x, y, stretchedWidth, stretchedHeight, sourceWidth, sourceHeight); /// by Robert B. Colton /// /// draws a 9 patch sprite with x, y as the top-left corner where the middle and center row and column /// is stretched to the given width and height /// subimages in the order: top-left, top-center, top-right, middle-left, middle-center, middle-right, /// bottom-left, bottom-center, bottom-right
var spr = argument0, subimg = argument1; var xx = argument2, yy = argument3; var sw = argument4, sh = argument5; var ow = argument6, oh = argument7; var cw = (sprite_get_width(spr) - ow) / 2, ch = (sprite_get_height(spr) - oh) / 2; var color = c_white, alpha = draw_get_alpha();
/// do this if you want to center the sprite around its origin /// var xx = (sprite_get_xoffset(spr) / sprite_get_width(spr)) * (sprite_get_width(spr) - ow + sw), /// yy = (sprite_get_yoffset(spr) / sprite_get_height(spr)) * (sprite_get_height(spr) - oh + sh);
// top-left and top-right corners do not need scaled draw_sprite_part(spr, subimg, 0, 0, cw, ch, xx, yy); draw_sprite_part(spr, subimg, cw + ow, 0, cw, ch, xx + cw + sw, yy);
// bottom-left and bottom-right corners do not need scaled draw_sprite_part(spr, subimg, 0, ch + oh, cw, ch, xx, yy + ch + sh); draw_sprite_part(spr, subimg, cw + ow, ch + oh, cw, ch, xx + cw + sw, yy + ch + sh);
// top-center and bottom-center need stretched horizontally draw_sprite_part_ext(spr, subimg, cw, 0, ow, ch, xx + cw, yy, sw/ow, 1, color, alpha); draw_sprite_part_ext(spr, subimg, cw, ch + oh, ow, ch, xx + cw, yy + ch + sh, sw/ow, 1, color, alpha);
// middle-left and middle-right needs stretched vertically draw_sprite_part_ext(spr, subimg, 0, ch, cw, oh, xx, yy + ch, 1, sh/oh, color, alpha); draw_sprite_part_ext(spr, subimg, cw + ow, ch, cw, oh, xx + cw + sw, yy + ch, 1, sh/oh, color, alpha);
// middle-center needs stretched horizontally and vertically draw_sprite_part_ext(spr, subimg, cw, ch, ow, oh, xx + cw, yy + ch, sw/ow, sh/oh, color, alpha);
I can think of about 50 more ways that this can be done, including using the tile drawing functions, which may be faster because they are batched and have little overhead. I haven't wrote those yet but if anybody needs it done a different way, feel free to ask me and I'll write the script.
|
|
« Last Edit: May 01, 2016, 09:51:50 pm by Robert B Colton »
|
Logged
|
I think it was Leonardo da Vinci who once said something along the lines of "If you build the robots, they will make games." or something to that effect.
|
|
|