首页 > 解决方案 > 如何设置画布元素的“z-index”?

问题描述

所以我让这个画家为我的游戏画了一张小地图:

class MiniMapPainter extends CustomPainter {
  final GameMap map;
  final double tileSize;
  final List<ui.Image> images;

  MiniMapPainter(
      {@required this.images, @required this.map, @required this.tileSize});

  @override
  void paint(Canvas canvas, Size size) {
    var row = 0;
    var column = 0;

    map.encodedMap.runes.forEach((charCode) {
      final character = String.fromCharCode(charCode);

      if (character == map.rowSeparator) {
        row++;
        column = 0;
      } else if (character == map.colSeparator) {
        column++;
      } else {
        final code = map.codeFromInt(int.parse(character));
        final paint = _paintFromMapCode(code);

        switch (code) {
          case MapCode.TreasureChestClosed:
          case MapCode.TreasureChestLocked:
            _paintImageFromAsset(canvas, column, row, images[0]);
            break;
          default:
            canvas.drawRect(
                Rect.fromLTWH(
                  _getLeft(column), // Determines position on x-axis
                  _getTop(row), // Determines position on y-axis
                  tileSize,
                  tileSize,
                ),
                paint);
            break;
        }
      }
    });
  }

  double _getTop(int index) {
    return index * tileSize;
  }

  double _getLeft(int index) {
    return (index % map.columns).floor().toDouble() * tileSize;
  }

  void _paintImageFromAsset(Canvas canvas, int x, int y, ui.Image asset) {
    final size = tileSize * 3;
    final offset = (size / 2);

    paintImage(
        canvas: canvas,
        rect: Rect.fromLTWH(
          _getLeft(x) - offset,
          _getTop(y) - offset,
          size,
          size,
        ),
        image: asset);
  }

  Paint _paintFromMapCode(MapCode code) {
    var paint = Paint();

    switch (code) {
      case MapCode.Obstacle:
        paint.color = Colors.black;
        break;
      case MapCode.DamageTrap:
        paint.color = Colors.red[300];
        break;
      case MapCode.StunTrap:
        paint.color = Colors.red[100];
        break;
      default:
        paint.color = Colors.grey[300];
        break;
    }

    return paint;
  }

  @override
  bool shouldRepaint(MiniMapPainter oldDelegate) => true;
  @override
  bool shouldRebuildSemantics(MiniMapPainter oldDelegate) => true;
}

有些东西需要图像而不是矩形,例如宝藏。所以我添加了_paintImageFromAsset一个效果很好的方法,但是在这个截图中可以看到一个问题:

小地图示例

正如您所看到的,在宝藏似乎获得更高的 z-index 之后绘制的任何矩形,因此它们会剪切图像。

我还没有找到像这样设置自定义画布元素的 z-index 的方法。如果可能的话,我想避免在所有矩形之后绘制图像。

我怎样才能做到这一点?

标签: flutterdartcanvas

解决方案


也许使用两个小部件?例如

Stack(children: [
  CustomPaint(paint: ThePaintToCreateThingsWithSmallZIndex()),
  CustomPaint(paint: ThePaintToCreateThingsWithBigZIndex()),
])

这样,你就不需要关心绘制的顺序了,即使在ThePaintToCreateThingsWithSmallZIndex后面绘制,它仍然在下面。

不要忘记透明地绘制而不是白色背景。

(代码仅用于演示目的,当然不能编译)


推荐阅读