GML Universal Nineslice Script

Discussion in 'Tutorials' started by Ephemeral, Apr 24, 2019.

  1. Ephemeral

    Ephemeral Member

    Joined:
    Mar 1, 2017
    Posts:
    185
    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;
     
    SilentxxBunny and NeZvers like this.
  2. mjadev

    mjadev Member

    Joined:
    Jan 28, 2017
    Posts:
    51
    thanks, works as expected
     
    Last edited: Apr 25, 2019
  3. Edwin

    Edwin Member

    Joined:
    Jul 15, 2018
    Posts:
    406
    Almost no difference from Heartbeast's nineslice script.
     
  4. gnysek

    gnysek Member

    Joined:
    Jun 20, 2016
    Posts:
    1,305

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice