Development/Dart&Flutter

[Flame] Klondlike 1 - World 레이아웃 구현

사이바 미도리 2024. 9. 7. 10:45

 

  • onLoad -> Flutter widget tree에 game instance가 call될 때, 호출됨.
    • 현재는 그냥 sprite image만 띄우도록 하고 있음.
    • 반드시 load를 보장하기 위해, await을 붙였다.
    await Flame.images.load('klondike-sprites.png');

 

  • 로드 된 이후, fromCache를 통해 sprite의 빠른 호출이 가능함.
    Flame.images.fromCache('klondike-sprites.png'),

 

 

Game component tree

  • Component를 KlondlikeGame 클래스에 넣으면, Game component tree에 추가된다.
    • Game에 존재하는 모든 entity는 Component여야만 한다.

Position Component

  • position과 size를 가지는 component 객체
    • debugMode를 override해서 true로 하면, 아래와 같이 와꾸가 보인다.

 

World Component

  • world에 속한 모든 component들은 coordinate를 가진다.
    • world 또한 component다. 아래와 같은 구조이다.
KlondikeGame
 ├─ World
 │   ├─ Stock
 │   ├─ Waste
 │   ├─ Foundation (×4)
 │   └─ Pile (×7)
 └─ CameraComponent
  • 보통 2D 객체용 Vector 선언할 때는, 0번째 인자가 가로, 1번째 인자가 세로이니 아래와 같이 선언하자.
  static final Vector2 cardSize = Vector2(cardWidth, cardHeight);

 

  • Cascade Notation 을 활용한다. 예시는 아래와 같다.
Cascade Notation

    세미콜론 없애고 아래와 같이 쓸 수 있다.

  var blue2RedMan = Player.createBlue(name: 'bo', xp: 500)
    ..team = 'red'
    ..xp = 1000
    ..sayHello();
}

 

  • 우리는 이렇게 Cascade Notation 을 활용할 것이다.
    final stock = Stock()
      ..size = cardSize
      ..position = Vector2(cardGap, cardGap);
    final waste = Waste()
      ..size = cardSize
      ..position = Vector2(cardWidth + 2 * cardGap, cardGap);
    final foundations = List.generate(
      4,
      (i) => Foundation()
        ..size = cardSize
        ..position =
            Vector2((i + 3) * (cardWidth + cardGap) + cardGap, cardGap),
    );
    final piles = List.generate(
      7,
      (i) => Pile()
        ..size = cardSize
        ..position = Vector2(
          cardGap + i * (cardWidth + cardGap),
          cardHeight + 2 * cardGap,
        ),
    );
  • 최종적으로, world에 이 객체들을 add하자.
    • Flame 1.9.0 이후, FlameGame은 기본적으로 world 및 camera object를 가진다.
      • KlondlikeGame은 FlameGame을 extend 하므로, 선언없이 world 써도 됨.
    world.add(stock);
    world.add(waste);
    world.addAll(foundations);
    world.addAll(piles);

add할때, await을 언제 쓰고 언제 안써야 하냐?

  • component가 반드시 fully loaded되어야 하는 logic은 흔하지 않다.
    • add 함수의 반환시점은, component load된 시점이지, game에 실제로 mount된 시점은 아니라고 함.

 

 

Camera

  • Camera는 Viewport랑 Viewfinder 두 파트가 있다.
    • 기본 Viewport는 Maxviewport이다.
      • 최대 가용화면을 잡아먹는다.
    • 반면, ViewFinder는 underlying world의 dimension을 받아야 한다고 한다.
      • 대충, 화면 크기를 정적으로 잡는다는 뜻으로 이해함.