이제 컴포넌트에 상호작용을 추가해야한다. 튜토리얼에서는 마우스나 터치 제스쳐를 통해 플레이어 컴포넌트를 조종할 수 있도록 안내하고 있다.
기존에 만든 FirstFlameGame 클래스에 PanDetector를 추가한다.
class FirstFlameGame extends FlameGame with PanDetector {
// ...
// 기존의 다른 코드는 생략. 새로 추가된 코드만 추가
late Player player;
@override
void onPanUpdate(DragUpdateInfo info) {}
}
PanDetector를 추가한 시점에서, 게임은 Pan의 입력값 변경에 대한 모든 업데이트를 받는다고 한다.
그러면 이제 이 Player 컴포넌트 안에 Pan에 대한 입력 값을 받았을 때 어떻게 처리할 것인지 함수를 추가해야 한다.
class Player extends PositionComponent {
// ...
// 기존의 다른 코드는 생략. 새로 추가된 코드만 추가
void move(Vector2 delta) {
position.add(delta);
}
}
class FirstFlameGame extends FlameGame with PanDetector {
late Player player;
@override
Future<void> onLoad() async {
await super.onLoad();
player = Player()
..position = size / 2
..width = 50
..height = 100
..anchor = Anchor.center;
add(player);
}
@override
void onPanUpdate(DragUpdateInfo info) {
player.move(info.delta.global);
}
}
이렇게 하고 앱을 실행해서, 마우스로 드래그를 해서 끌어보면 하얀색 사각형이 움직이는 것을 확인할 수 있다.
이제 이 하얀색 컴포넌트를 이미지 파일로 변경할 것이다. 기존에 PositionComponent 였던 Player를 SpriteComponent로 변경해준다.
class Player extends SpriteComponent {
void move(Vector2 delta) {
position.add(delta);
}
}
class FirstFlameGame extends FlameGame with PanDetector {
late Player player;
@override
Future<void> onLoad() async {
await super.onLoad();
final playerSprite = await loadSprite('player-sprite.png');
player = Player()
..sprite = playerSprite
..x = size.x / 2
..y = size.y / 2
..width = 50
..height = 100
..anchor = Anchor.center;
add(player);
}
@override
void onPanUpdate(DragUpdateInfo info) {
player.move(info.delta.global);
}
}
player-sprite.png 파일은 튜토리얼에 있는 assets/images 파일의 png 파일을 다운 받아서 사용했다.
이러고 실행하면 하얀 사각형이 우주선 모양의 이미지로 변경되어야 하는데...
그냥 에러 화면이 떴다.
assets/images/ 경로에 player-sprite.png 파일이 제대로 들어가 있는데...
대체 왜 그런 것인가 계속 오류를 찾고 있었는데, 해답은 flame이 아닌 flutter 그 자체에 있었다. 플러터에서는 pubspec.yaml 파일에 이미지 경로를 넣어줘야 이미지를 찾을 수 있다. 그 처리를 하지 않아서 오류가 발생했던것.
pubspec.yaml 파일에서
flutter:
assets:
- assets/images/
이렇게 추가해주고 나니, 정상적으로 우주선 그림이 떴다.
튜토리얼에서는 마지막으로 코드를 리팩터링했다. 원래 FirstFlameGame 클래스 안에 있던 Player 컴포넌트를 설정하는 부분을 Player 클래스 안으로 옮겼다. 이렇게 함으로써 Player 객체를 생성하면 생성자를 통해서 미리 설정한 값으로 초기화 할 수 있다.
class FirstFlameGame extends FlameGame with PanDetector {
late Player player;
@override
Future<void> onLoad() async {
await super.onLoad();
player = Player();
add(player);
}
@override
void onPanUpdate(DragUpdateInfo info) {
player.move(info.delta.global);
}
}
class Player extends SpriteComponent with HasGameReference<FirstFlameGame> {
Player() : super(size: Vector2(100, 150), anchor: Anchor.center);
@override
Future<void> onLoad() async {
await super.onLoad();
sprite = await game.loadSprite('player-sprite.png');
position = game.size / 2;
}
void move(Vector2 delta) {
position.add(delta);
}
}