Skip to content

Instantly share code, notes, and snippets.

@IBwWG
Forked from MSGhero/PlayState.hx
Last active March 5, 2020 20:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IBwWG/9ffe25a059983e7e4eeb7640d6645a37 to your computer and use it in GitHub Desktop.
Save IBwWG/9ffe25a059983e7e4eeb7640d6645a37 to your computer and use it in GitHub Desktop.
9-Slice Algo Test
package;
import flash.display.BitmapData;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flixel.FlxSprite;
import flixel.FlxState;
/**
* ...
* @author MSGHero
*/
class PlayState extends FlxState{
var sprite:FlxSprite;
override public function create():Void {
sprite = new FlxSprite(50, 0);
loadSpriteSheet();
add(sprite);
}
function loadSpriteSheet():Void {
//var bmd = new BitmapData(9, 9, false, 0xffffffff);
//var slices = [3, 3, 6, 6];
var bmd = new BitmapData(19, 23, false, 0xffffffff);
var slices = [3, 5, 17, 16]; // bottom: 2, right: 7
//var bmd = new BitmapData(19, 23, false, 0xffffffff);
//var slices = [3, 5, 16, 20]; // bottom: 3, right: 3
//var bmd = new BitmapData(9, 9, false, 0xffffffff);
//var slices = [2, 2, 6, 6]; // bottom: 3, right: 3
// generate an image from slice and size data:
var rect = new Rectangle(0, 0, slices[0], slices[1]);
bmd.fillRect(rect, 0xffff0000);
rect.setTo(slices[0], 0, slices[2] - slices[0], slices[1]);
bmd.fillRect(rect, 0xffff8800);
rect.setTo(slices[2], 0, bmd.width - slices[2], slices[1]);
bmd.fillRect(rect, 0xffffff00);
rect.setTo(0, slices[1], slices[0], slices[3] - slices[1]);
bmd.fillRect(rect, 0xff00ff00);
rect.setTo(slices[0], slices[1], slices[2] - slices[0], slices[3] - slices[1]);
bmd.fillRect(rect, 0xff0000ff);
rect.setTo(slices[2], slices[1], bmd.width - slices[2], slices[3] - slices[1]);
bmd.fillRect(rect, 0xffff00ff);
rect.setTo(0, slices[3], slices[0], bmd.height - slices[3]);
bmd.fillRect(rect, 0xffffffff);
rect.setTo(slices[0], slices[3], slices[2] - slices[0], bmd.height - slices[3]);
bmd.fillRect(rect, 0xff888888);
rect.setTo(slices[2], slices[3], bmd.width - slices[2], bmd.height - slices[3]);
bmd.fillRect(rect, 0xff444444); // not black against black background
var original = new FlxSprite();
original.pixels = bmd;
add(original);
// ----------------------------------------------- 9 slice starts here
var leftW = slices[0];
var topH = slices[1];
var rightW = bmd.width - slices[2];
var botH = bmd.height - slices[3];
var centerW = slices[2] - slices[0];
var centerH = slices[3] - slices[1];
var finalW = 259; // <------------------------------------------------ CHANGE THESE
var finalH = 83; // <--------------------
var finalCenterW = finalW - leftW - rightW;
var finalCenterH = finalH - topH - botH;
var scaleHoriz = finalCenterW / centerW;
var scaleVert = finalCenterH / centerH;
var mat = new Matrix();
var pt = new Point();
var finalImg = new BitmapData(finalW, finalH, true, 0x0);
// TL
rect.setTo(0, 0, leftW, topH);
pt.setTo(0, 0);
finalImg.copyPixels(bmd, rect, pt, null, null, true);
// T
rect.setTo(leftW, 0, finalCenterW, topH);
mat.setTo(scaleHoriz, 0, 0, 1, leftW * (1 - scaleHoriz), 0);
finalImg.draw(bmd, mat, null, null, rect);
// TR
rect.setTo(leftW + centerW, 0, rightW, topH);
pt.setTo(finalW - rightW, 0);
finalImg.copyPixels(bmd, rect, pt, null, null, true);
// L
rect.setTo(0, topH, leftW, finalCenterH);
mat.setTo(1, 0, 0, scaleVert, 0, topH * (1 - scaleVert));
finalImg.draw(bmd, mat, null, null, rect);
// C
rect.setTo(leftW, topH, finalCenterW, finalCenterH);
mat.setTo(scaleHoriz, 0, 0, scaleVert, leftW * (1 - scaleHoriz), topH * (1 - scaleVert));
finalImg.draw(bmd, mat, null, null, rect);
// R
rect.setTo(leftW + finalCenterW, topH, rightW, finalCenterH);
mat.setTo(1, 0, 0, scaleVert, finalCenterW - centerW, topH * (1 - scaleVert));
finalImg.draw(bmd, mat, null, null, rect);
// BL
rect.setTo(0, topH + centerH, leftW, botH);
pt.setTo(0, topH + finalCenterH);
finalImg.copyPixels(bmd, rect, pt, null, null, true);
// B
rect.setTo(leftW, topH + finalCenterH, finalCenterW, botH);
mat.setTo(scaleHoriz, 0, 0, 1, leftW * (1 - scaleHoriz), finalCenterH - centerH);
finalImg.draw(bmd, mat, null, null, rect);
// BR
rect.setTo(leftW + centerW, topH + centerH, rightW, botH);
pt.setTo(leftW + finalCenterW, topH + finalCenterH);
finalImg.copyPixels(bmd, rect, pt, null, null, true);
// render
sprite.pixels = finalImg;
sprite.dirty = true;
}
}
@IBwWG
Copy link
Author

IBwWG commented Aug 25, 2016

As you can see with a non-equal bevel all the way around, the bottom and right pieces do not come out right.

@IBwWG
Copy link
Author

IBwWG commented Aug 25, 2016

Interestingly, the bottom and right are broken also if you leave them at 3px and change the top and left pieces to be 2px wide:

        var bmd = new BitmapData(9, 9, false, 0xffffffff);
        var slices = [2, 2, 6, 6]; // bottom: 3, right: 3

This is also true even if you don't scale it: set finalW/H to 9.

@IBwWG
Copy link
Author

IBwWG commented Aug 25, 2016

OK, I got it. It's maybe a bit unintuitive--the original looked correct at first glance--but since you're translating the entire thing, not just the clipped part, you need to translate also by the amount you don't want to see.

E.g. for the right slice, finalCenterW - leftW is off by leftW - centerW, so adding those back in, the leftWs cancel and you get finalCenterW - centerW. You'll notice this is equal to finalW - bmd.width, which is visually a bit easier to understand--you translate by finalW, then you end up just off the right edge, and backtrack bmd.width to then have the right edges aligned, which is what you want.

Anyway, it's working now.

@MSGhero
Copy link

MSGhero commented Sep 3, 2016

Niceeeeeeeeee

@MSGhero
Copy link

MSGhero commented Apr 29, 2017

Yo, I'm using this gist for some 9-slice stuff but I have a few changes to make. Yours is correct as far as I can tell, but it can be expanded a bit.

Also, are you sure that the leftW * (1 - scaleHoriz) parts are correct? Should it just be -leftW * scaleHoriz? Yes, it is needed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment