Flutter Flame中选中组件时添加名称标签的实现方法
在Flutter Flame中实现选中组件顶部显示名称文本
1. 定义可选中的自定义组件
创建继承PositionComponent并混入TapCallbacks的组件类,用来处理点击选中逻辑,同时维护选中状态和名称属性:
class SelectableComponent extends PositionComponent with TapCallbacks, HasGameRef { final String name; bool isSelected = false; late TextPaint textPaint; SelectableComponent({required this.name, required Vector2 size}) : super(size: size) { // 初始化文本画笔,设置样式 textPaint = TextPaint( style: const TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold, ), ); } // 点击切换选中状态 @override void onTapDown(TapDownEvent event) { isSelected = !isSelected; // 如需单选,取消其他组件选中状态 // gameRef.children.whereType<SelectableComponent>().forEach((comp) { // if (comp != this) comp.isSelected = false; // }); super.onTapDown(event); } // 绘制组件本体与选中时的名称文本 @override void render(Canvas canvas) { super.render(canvas); // 绘制组件基础样式(示例为矩形) Paint paint = Paint()..color = isSelected ? Colors.blue : Colors.grey; canvas.drawRect(size.toRect(), paint); // 选中时在顶部绘制名称 if (isSelected) { final textSize = textPaint.measureText(name); // 计算文本位置:组件顶部居中,向上偏移4px final textX = (size.x - textSize.width) / 2; final textY = -textSize.height - 4; textPaint.render(canvas, name, Vector2(textX, textY)); } } }
2. 在游戏类中添加组件
在你的Flame游戏类里初始化并挂载自定义组件:
class MyGame extends FlameGame { @override Future<void> onLoad() async { super.onLoad(); // 添加两个示例组件到不同位置 add(SelectableComponent( name: "组件A", size: Vector2(100, 100), )..position = Vector2(100, 100)); add(SelectableComponent( name: "组件B", size: Vector2(100, 100), )..position = Vector2(300, 100)); } }
3. 可选:用TextComponent子组件实现
如果偏好组件化的方式,可以给SelectableComponent添加TextComponent子组件,通过控制visible属性显示/隐藏名称:
class SelectableComponent extends PositionComponent with TapCallbacks, HasGameRef { final String name; bool isSelected = false; late TextComponent nameText; SelectableComponent({required this.name, required Vector2 size}) : super(size: size) { nameText = TextComponent( text: name, textRenderer: TextPaint( style: const TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold, ), ), position: Vector2(size.x / 2, -20), // 顶部居中位置 anchor: Anchor.center, )..visible = false; add(nameText); } @override void onTapDown(TapDownEvent event) { isSelected = !isSelected; nameText.visible = isSelected; // 单选逻辑同上 super.onTapDown(event); } @override void render(Canvas canvas) { super.render(canvas); Paint paint = Paint()..color = isSelected ? Colors.blue : Colors.grey; canvas.drawRect(size.toRect(), paint); } }
核心注意点
- 借助
TapCallbacks监听组件点击,切换选中状态 - 两种文本显示方式按需选择:直接绘制更轻量,子组件方式更符合Flame组件化思想
- 文本位置需根据组件尺寸计算,确保在顶部居中显示
- 单选场景下,记得在选中当前组件时取消其他同类型组件的选中状态
内容的提问来源于stack exchange,提问作者Zzz
相关产品推荐
相关产品推荐

