You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在屏幕尺寸变化时重新构建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,
  });
}

代码说明

  1. _cells列表:用于存储所有单元格组件,每次窗口尺寸变化时,先移除所有旧单元格并清空列表,避免重复添加导致的组件堆积。
  2. onGameResize方法:Flame的生命周期方法,当窗口大小改变时自动触发,这里调用_updateGrid重新计算布局。
  3. 锚点设置:将GameGrid的anchor设为Anchor.center,使网格的中心与游戏窗口中心对齐,简化了位置计算逻辑,无需再使用负数偏移量。
  4. 单元格尺寸计算:使用clamp(0.0, double.infinity)确保单元格尺寸不会为负数,防止窗口过小时出现布局异常。
  5. _updateGrid方法:整合了网格的清理与重建逻辑,确保每次尺寸变化时都能生成适配新窗口的网格。

内容的提问来源于stack exchange,提问作者dipansh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 07:05:19