flutterflame

How to rebuild the game on screen resize?


I'm trying to create a grid with the flame framework where the cells size depends on the screen width. This is the current code that is achieving this:

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;

  @override
  FutureOr<void> onLoad() {
    super.onLoad();

    _paintGrid();
  }

  void _paintGrid() {
    // number of rows and cols
    const numRows = 7;
    const numCols = 5;

    // screen size
    final screenSize = gameRef.size;

    // cell spacing
    const cellSpacing = 5.0;

    // cell size
    final cellSize = (screenSize.x / numCols) - (cellSpacing * (numCols - 1));

    // calculating starting point of the grid
    final startingTopLeftOfGrid = Vector2(
      -(((cellSize * numCols) + (cellSpacing * (numCols - 1))) / 2),
      -(((cellSize * numRows) + (cellSpacing * (numRows - 1))) / 2),
    );

    for (int i = 0; i < numRows; i++) {
      for (int j = 0; j < numCols; j++) {
        final cell = Cell(
          position: Vector2(
            startingTopLeftOfGrid.x + (j * (cellSize + cellSpacing)),
            startingTopLeftOfGrid.y + (i * (cellSize + cellSpacing)),
          ),
          size: Vector2.all(cellSize),
        );

        add(cell);
      }
    }
  }
}

class Cell extends RectangleComponent {
  Cell({
    required super.position,
    required super.size,
    super.anchor,
    super.paint,
  });
}

Now what I want is to resize the grid if the screen resizes. e.g. on a desktop application, when the user resizes the game window, I want the grid to render according to the new screen width. How may I achieve that? Thank you


Solution

  • The easiest option is to use CameraComponent.withFixedResolution which uses the FixedResolutionViewport, so everything that you have in your game will be scaled up/down according to the window size. The downside with that is that you will get black bars on the side when you're not matching the aspect ratio.

    Just change the class extending FlameGame to this:

    class MyGame extend FlameGame {
      MyGame() : super(
        camera: CameraComponent.withFixedResolution(
          width: 800,
          height: 600,
        ),
      );
    }
    

    The other option is to override onGameResize and set the size of the cells in there, all components have onGameResize:

    
    @override
    class Cell extends RectangleComponent {
      ...
    
      void onGameResize(Vector2 size) {
        this.size = // new size dependent on the size argument
        this.position = // since all cells change size you also have to change the position
      }
    }