如何在屏幕尺寸变化时重新构建Flame框架中的游戏网格?
解决方案
要实现屏幕尺寸变化时自动调整网格,你需要利用Flame框架的窗口尺寸监听机制,在窗口大小改变时重新计算并更新网格布局。以下是具体实现步骤和修改后的代码:
关键修改点
- 监听窗口尺寸变化事件:重写
Component的onGameResize方法,该方法会在窗口大小改变时被Flame自动调用。 - 维护单元格列表:保存所有单元格组件,方便在尺寸变化时快速清理旧组件,避免重复渲染。
- 优化网格居中逻辑:将网格组件的锚点设为
Anchor.center,简化位置计算,让网格始终居中显示。 - 边界值处理:确保单元格尺寸不会为负数,避免异常情况。
修改后的完整代码
import 'dart:async'; import 'dart:ui'; import 'package:flame/components.dart'; import 'package:flutter/material.dart'; import './my_game.dart'; class GameGrid extends Component with HasGameRef<MyGame> { final paint = Paint()..color = Colors.white; // 保存所有单元格组件,方便后续清理 final List<Cell> _cells = []; // 网格配置常量 const numRows = 7; const numCols = 5; const cellSpacing = 5.0; @override FutureOr<void> onLoad() { super.onLoad(); // 设置网格锚点为中心,让网格基于窗口中心定位 anchor = Anchor.center; // 初始化网格 _updateGrid(); } @override void onGameResize(Vector2 size) { super.onGameResize(size); // 窗口尺寸变化时更新网格 _updateGrid(); } void _updateGrid() { // 先移除所有旧单元格 for (final cell in _cells) { cell.removeFromParent(); } _cells.clear(); final screenSize = gameRef.size; // 计算单元格尺寸,确保不小于0 final cellSize = ((screenSize.x / numCols) - (cellSpacing * (numCols - 1))).clamp(0.0, double.infinity); // 计算网格总尺寸 final gridWidth = cellSize * numCols + cellSpacing * (numCols - 1); final gridHeight = cellSize * numRows + cellSpacing * (numRows - 1); // 网格左上角相对于自身中心的偏移(因为锚点是center) final startX = -gridWidth / 2; final startY = -gridHeight / 2; // 创建新的单元格 for (int i = 0; i < numRows; i++) { for (int j = 0; j < numCols; j++) { final cell = Cell( position: Vector2( startX + j * (cellSize + cellSpacing), startY + i * (cellSize + cellSpacing), ), size: Vector2.all(cellSize), paint: Paint()..color = Colors.white, ); add(cell); _cells.add(cell); } } } } class Cell extends RectangleComponent { Cell({ required super.position, required super.size, super.anchor, super.paint, }); }
代码说明
_cells列表:用于存储所有单元格组件,每次窗口尺寸变化时,先移除所有旧单元格并清空列表,避免重复添加导致的组件堆积。onGameResize方法:Flame的生命周期方法,当窗口大小改变时自动触发,这里调用_updateGrid重新计算布局。- 锚点设置:将
GameGrid的anchor设为Anchor.center,使网格的中心与游戏窗口中心对齐,简化了位置计算逻辑,无需再使用负数偏移量。 - 单元格尺寸计算:使用
clamp(0.0, double.infinity)确保单元格尺寸不会为负数,防止窗口过小时出现布局异常。 _updateGrid方法:整合了网格的清理与重建逻辑,确保每次尺寸变化时都能生成适配新窗口的网格。
内容的提问来源于stack exchange,提问作者dipansh
相关产品推荐
相关产品推荐

