GML Universal Nineslice Script

Ephemeral

Member
GM Version: GMS2
Target Platform: All
Download: N/A
Links: N/A

Summary:
This is a basic universal script utility for drawing a nineslice, which is a textured box that keeps the proportions of its edges when you scale it.

Tutorial:
I've done my best to make this script entirely self-contained. It should be copy-paste-able right into your project with no tweaks.

The key to using it is in sprite design. To correctly create a sprite for use with this script, follow these steps.
  • Decide on the border width of the boxes you would like to draw.
  • Multiply that number by 3 and create a sprite with the resulting number as its dimensions.
  • Set up your grid size so that your canvas is divided into three rows and three columns.
  • Fill the center with a solid color, with or without alpha.
  • Draw the corners. These can be anything you want.
  • Connect the corners with something that only varies across itself, not lengthwise.
Code:
///@ function draw_ninebox(left, top, right, bottom, sprite, tint, opacity)
///@ param left
///@ param top
///@ param right
///@ param bottom
///@ param sprite
///@ param tint
///@ param opacity


var left = argument0;
var top = argument1;
var right = argument2;
var bottom = argument3;
var sprite = argument4;
var tint = argument5;
var opacity = argument6;

if (!sprite_exists(sprite)) return false;

// Vett Sprite

var sprite_size = sprite_get_height(sprite);

if (sprite_get_width(sprite) != sprite_size)
{
    show_debug_message(sprite_get_name(sprite) + " cannot be NINEBOXed because it is not a perfect square.");
    return false;
}
if not (sprite_size mod 3 == 0)
{
    show_debug_message(sprite_get_name(sprite) + " cannot be NINEBOXed because its pixel size is not divisible by three.");
    return false;
}
var slice_size = sprite_size / 3;

// Draw Fill

var scale_x = ((right - slice_size) - (left + slice_size)) / slice_size;
var scale_y = ((bottom - slice_size) - (top + slice_size)) / slice_size;
draw_sprite_part_ext(sprite, 0, slice_size, slice_size, slice_size, slice_size, left + slice_size, top + slice_size, scale_x, scale_y, tint, opacity);

// Draw Vertical Edges

draw_sprite_part_ext(sprite, 0, 0, slice_size, slice_size, slice_size, left, top + slice_size, 1, scale_y, tint, opacity);
draw_sprite_part_ext(sprite, 0, slice_size * 2, slice_size, slice_size, slice_size, right - slice_size, top + slice_size, 1, scale_y, tint, opacity);

// Draw Horizontal Edges

draw_sprite_part_ext(sprite, 0, slice_size, 0, slice_size, slice_size, left + slice_size, top, scale_x, 1, tint, opacity);
draw_sprite_part_ext(sprite, 0, slice_size, slice_size * 2, slice_size, slice_size, left + slice_size, bottom - slice_size, scale_x, 1, tint, opacity);

// Draw the Corners

draw_sprite_part_ext(sprite, 0, 0, 0, slice_size, slice_size, left, top, 1, 1, tint, opacity);
draw_sprite_part_ext(sprite, 0, slice_size * 2, 0, slice_size, slice_size, right - slice_size, top, 1, 1, tint, opacity);
draw_sprite_part_ext(sprite, 0, 0, slice_size * 2, slice_size, slice_size, left, bottom - slice_size, 1, 1, tint, opacity);
draw_sprite_part_ext(sprite, 0, slice_size * 2, slice_size * 2, slice_size, slice_size, right - slice_size, bottom - slice_size, 1, 1, tint, opacity);

return slice_size;
 
Top