https://www.spritewidget.com

pubspec.yaml


1
2
3
4
dependencies:
  flutter:
    sdk: flutter
  spritewidget:

노드(Node) 아래에 노드가 들어가는 구조입니다. 편의상 최상위 노드를 rootNode라는 변수명으로 만듭니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import 'package:flutter/material.dart';
import 'package:spritewidget/spritewidget.dart';

void main() => runApp(MyWidget());

class MyWidget extends StatefulWidget {
  @override
  MyWidgetState createState() => new MyWidgetState();
}

class MyWidgetState extends State<MyWidget> {
  NodeWithSize rootNode;

  @override
  void initState() {
    super.initState();
    rootNode = new NodeWithSize(const Size(1024.0, 1024.0));
  }

  @override
  Widget build(BuildContext context) {
    return new SpriteWidget(rootNode);
  }
}

SpriteWidget은 레터 박스(letterbox)를 사용하여 내용을 표시합니다. 즉, 루트 노드에 지정하는 크기에 따라 SpriteWidget의 내용이 크기에 맞게 조정됩니다. 위젯 영역에 완벽하게 맞지 않으면 상단과 하단 또는 왼쪽과 오른쪽 중 하나가 잘립니다.

앱의 빌드 메소드에 SpriteWidget을 추가하면 애니메이션 실행과 사용자 입력 처리가 자동으로 시작됩니다. 다른 추가 설정이 필요 없습니다.

이미지 추가


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
ImageMap imgMap;

Future<Null> _loadAssets(AssetBundle bundle) async {
  imgMap = ImageMap(bundle);
  await imgMap.load(<String>[
    "assets/icon.png"
  ]);
}

@override
void initState() {
  super.initState();
  rootNode = NodeWithSize(Size(720.0, 600.0));

  AssetBundle bundle = rootBundle;

  _loadAssets(bundle).then((_) {
    Sprite icon = Sprite.fromImage(imgMap["assets/icon.png"]);
    icon.pivot = Offset(0, 0);
    icon.size = Size(398, 500);
    icon.position = Offset(100, 50);
    rootNode.addChild(icon);
  });
}

Flutter의 Canvas를 이용하며 렌더링 퍼포먼스 테스트 결과 코로나보다 조금 더 나은 수준이지만 캡쳐 퀄리티는 훨씬 떨어집니다. 게임쪽은 좀 더 개선된 다음 써야 할 듯.