Flutter - Defense Game - 2

김진한·2023년 1월 28일
0

Flutter

목록 보기
11/11

이번 포스팅에서는 화면 사이즈가 변경될 때마다 mapComponent의 사이즈와 위치를 변경시키는 작업을 하겠습니다(반응형 작업).

GameSetting

사이즈 측정을 위해서 GameSetting 이라는 클래스를 만들었습니다. GameSetting 클래스를 사용해서 DefenseGame 위젯에서 GameSetting 클래스를 사용해서 MapComponent의 사이즈를 넘겨줄 것입니다.
MapComponent는 position값을 계산해서 가로 세로 center에 위치시켰습니다. mapTile의 size의 최소값도 추가했습니다.

import 'package:flame/extensions.dart';

class GameSetting {
  /// 현재 화면 사이즈
  late Vector2 screenSize;

  /// 타일 사이즈
  double mapTileSize = 0;

  /// 타일의 개수
  final double mapTileCount = 12;

  /// 타일 사이즈 최소값
  final double _minTileSize = 30;

  void init(Vector2 size) {
    setScreenSize(size);
    caleMapTile(size);
  }

  /// 화면 사이즈 세팅
  void setScreenSize(Vector2 size) => screenSize = size;

  /// 타일의 사이즈 계산
  void caleMapTile(Vector2 size) {
    /// x, y 중에 사이즈가 작은 값을 기준으로 계산 한다.
    double value = size.x > size.y ? size.y : size.x;

    /// value 값을 tile 개수로 나눈 후 -10 해준다.
    /// -10을 해주는 이유는 타일 크기를 줄여서, 전체 grid의 사이즈를 줄이기 위해서다
    /// 그래야 가로, 세로 패딩의 효과를 줄 수 있다.
    mapTileSize = (value / mapTileCount) - 10;

    /// 최소값 체크
    if (mapTileSize < _minTileSize) mapTileSize = _minTileSize;
  }

  Vector2 get mapTileSizeVector2 => Vector2(mapTileSize, mapTileSize);

  Vector2 get mapGridVector2 => Vector2(mapTileCount, mapTileCount);

  Vector2 get mapPositionVector2 => Vector2(
        (screenSize.x - mapTileCount * mapTileSize) / 2,
        (screenSize.y - mapTileCount * mapTileSize) / 2,
      );

  Vector2 mapComponentSize() {
    double x = screenSize.x;
    double y = screenSize.y;
    if (x < _minScreenSize || y < _minScreenSize) {
      return Vector2(_minScreenSize, _minScreenSize);
    }
    return screenSize;
  }

  double get _minScreenSize => mapTileCount * _minTileSize;
}

  • DefenseGame 위젯
    onGameResize 함수는 화면 사이즈가 변경될 때 마다 호출됩니다. 그래서 GameSetting의 init 함수로 값들을 필요한 값들을 계산해주고, setMapComponent 함수에서 계산한 값들을 넘겨주고 있습니다.
    값들을 입력해서 MapComponent를 다시 생성한 다음에 새로 화면을 갱신시켜야 하기 때문에 remove와 add를 앞 뒤에서 호출해주고 있습니다.
import 'dart:async';

import 'package:defense_tutorial/map/map_component.dart';
import 'package:defense_tutorial/util/game_log.dart';
import 'package:defense_tutorial/util/game_setting.dart';
import 'package:flame/game.dart';

class DefenseGame extends FlameGame {
  final GameSetting _setting = GameSetting();
  MapComponent? _mapComponent;

  
  void onGameResize(Vector2 canvasSize) {
    super.onGameResize(canvasSize);
    _setting.init(canvasSize);
    _setMapComponent();
  }

  
  FutureOr<void> onLoad() async {
    logging("DefenseGame.onLoad");
    return null;
  }

  void _setMapComponent() {
    if (_mapComponent != null) remove(_mapComponent!);
    _mapComponent = MapComponent(
      tileSize: _setting.mapTileSizeVector2,
      mapGrid: _setting.mapGridVector2,
      position: _setting.mapPositionVector2,
      size: _setting.mapComponentSize(),
    );
    add(_mapComponent!);
  }
}


이제 웹으로 빌드했을 때 화면 사이즈 변경에 따라서 타일들의 크기와 위치가 변경됩니다.


프로젝트 링크
https://github.com/jinhan38/defense_tutorial.git

0개의 댓글