flutterdartflame

How can I achieve a 9-Patch in Flame?


Can Flame support 9-patch images? I've searched but couldn't find any documentation or examples.

I know it's possible to implement 9-patch in standalone Flutter: https://api.flutter.dev/flutter/widgets/Image/centerSlice.html

However, I'm unsure how to integrate Flutter's features seamlessly within a Flame game.

Since Godot supports 9-patch out of the box, I feel it should be possible in Flame as well: https://2dgames.jp/godot-nine-patch-rect/ (Japanese)

A specific use case would be the outer frame for elements like RPG command input menus or shop menus.

A standalone Flutter 9-patch may not be well-suited for games. Pixel art is drawn at small sizes. For example, if the line width is 4 pixels, it may appear too thin in Flutter.

In Flame, size adjustments allow even thin lines to be represented as larger pixels.


As already mentioned, I am asking whether there is something specific for Flame, not just for standalone Flutter.

I know it's possible to implement 9-patch in standalone Flutter: https://api.flutter.dev/flutter/widgets/Image/centerSlice.html


As mentioned in the comments, it seems possible to achieve this using something like NineTileBox, so I plan to give it a try (though I haven’t tested it yet).

btw, i just found that flame supports nine pathches naively: go to pub.dev/documentation/flame/latest/index.html and type nine in the top right search box - so use that and not CustomPainterComponent

i mean that you shoud use the classes that supports nine patches natievly in flame


Solution

  • Flame supports a "9-Patch" box via the NineTileBox class and the NineTileBoxComponent component; for example, from the examples app:

        final sprite = Sprite(await images.load('nine-box.png'));
        final boxSize = Vector2.all(300);
        final nineTileBox = NineTileBox(sprite, destTileSize: 148);
        add(
          nineTileBoxComponent = NineTileBoxComponent(
            nineTileBox: nineTileBox,
            position: size / 2,
            size: boxSize,
            anchor: Anchor.center,
          ),
        );
    

    This is what the input sprite looks like:

    flame nine box sprite source example

    And this is what it looks like in the examples app:

    nine tile box component on the examples app

    As expected, and in line with other implementations, it will split your image on a 3x3 grid, keep the corners, scale the sides only in one direction, and scale the center in both directions, keeping the "border" design intact.

    You can also read more about in our docs or check out the source code for even more details.