Flutter๋ฅผ ์ฒ์ ๋ณด๋ ์ฌ๋๋ ์์ ๊ฒ์ ํ๋ก์ ํธ๋ฅผ ๋ฐ๋ผ ์ฝ์ผ๋ฉฐ ํต์ฌ ๊ฐ๋ ์ ์ตํ ์ ์๋๋ก ๋ง๋ ์ค์ต ํ๋ก์ ํธ์ ๋๋ค.
์์ฑ๋ ์ฑ์ ํฌ๋กฌ ๊ณต๋ฃก ๊ฒ์์ฒ๋ผ ์๋์ผ๋ก ๋ฌ๋ฆฌ๋ ๋ฌ๋ ๊ฒ์์ ๋๋ค. ์ฌ์ฉ์๋ ๊ณ ์์ด ๋๋ ๊ณต๋ฃก์ ๊ณ ๋ฅด๊ณ , ์ ํํ๊ฑฐ๋ ์์ฌ์ ์ฅ์ ๋ฌผ์ ํผํฉ๋๋ค. ๋ณ๋ ์ด๋ฏธ์ง ์์ ์ด๋ ๊ฒ์ ์์ง์ ์ฌ์ฉํ์ง ์์๊ณ , Flutter ๊ธฐ๋ณธ ๊ธฐ๋ฅ๋ง์ผ๋ก ํ๋ฉด๊ณผ ์์ง์์ ๋ง๋ค์์ต๋๋ค.
์ฑ ์ฝ๋๋ dino ํด๋์ ์์ต๋๋ค.
| ํ์ผ | ์ญํ | ์ฒ์ ๋ณผ ๋ ์ง์คํ ๋ด์ฉ |
|---|---|---|
dino/lib/main.dart |
์ฑ ์คํ, ๊ฒ์ ์ํ, ์ ๋ ฅ ์ฒ๋ฆฌ, ํ๋ฉด ๊ทธ๋ฆฌ๊ธฐ | Flutter ์ฑ์ด ์์๋๊ณ ํ๋ฉด์ด ๋ฐ๋๋ ํ๋ฆ |
dino/pubspec.yaml |
ํ๋ก์ ํธ ์ด๋ฆ, SDK ๋ฒ์ , ์์กด์ฑ ์ค์ | Flutter ํ๋ก์ ํธ๊ฐ ์ด๋ค ํจํค์ง๋ฅผ ์ฐ๋์ง |
dino/test/widget_test.dart |
ํ๋ฉด ๋์ ํ ์คํธ | ๋ฒํผ ์ ํ, ๊ฒ์ ์์, ์ฌ์์์ ์ฝ๋๋ก ํ์ธํ๋ ๋ฐฉ๋ฒ |
dino/README.md |
์ฑ ํด๋์ฉ ๊ฐ๋จ ์คํ ์๋ด | ์คํ ๋ช ๋ น๋ง ๋น ๋ฅด๊ฒ ํ์ธํ ๋ |
์ด ํ๋ก์ ํธ๋ Flutter์ ๊ธฐ์ด ์์ ฏ ์ฑ์์ ํ ๋จ๊ณ ๋ ๋์๊ฐ โ์ง์ ๊ทธ๋ฆฌ๋ ํ๋ฉดโ๊ณผ โ์๊ฐ์ ๋ฐ๋ผ ์์ง์ด๋ ์ํโ๋ฅผ ๋ค๋ฃน๋๋ค.
MaterialApp,Scaffold: Flutter ์ฑ์ ๊ธฐ๋ณธ ๊ป๋ฐ๊ธฐ ๋ง๋ค๊ธฐStatefulWidget,setState: ์ ์, ์์น, ๊ฒ์ ์ํ์ฒ๋ผ ๋ฐ๋๋ ๊ฐ ๊ด๋ฆฌํ๊ธฐGestureDetector,Focus: ํฐ์น์ ํค๋ณด๋ ์ ๋ ฅ ๋ฐ๊ธฐAnimationController: ๋งค ํ๋ ์ ๊ฒ์ ์ํ ๊ฐฑ์ ํ๊ธฐCustomPainter: ์ด๋ฏธ์ง ์์ด ์บ๋ฒ์ค์ ์บ๋ฆญํฐ์ ์ฅ์ ๋ฌผ ๊ทธ๋ฆฌ๊ธฐRect.overlaps: ์บ๋ฆญํฐ์ ์ฅ์ ๋ฌผ์ ์ถฉ๋ ํ์ ํ๊ธฐflutter_test: ํ๋ฉด์ ์ํ๋ ๋ฌธ๊ตฌ์ ๋ฒํผ์ด ๋์ค๋์ง ํ ์คํธํ๊ธฐ
GDGOC-SeoulTech-5th_Flutter_Session_13/
README.md
dino/
lib/
main.dart
test/
widget_test.dart
pubspec.yaml
macos/
web/
android/
ios/
windows/
linux/
Flutter๋ ํ๋์ ์ฝ๋๋ก ์ฌ๋ฌ ํ๋ซํผ์ ์คํํ ์ ์์ต๋๋ค. ์ด ํ๋ก์ ํธ๋ web, macos, windows, linux, android, ios ํด๋๊ฐ ํจ๊ป ์์ฑ๋์ด ์์ต๋๋ค. ์ค์ ๊ฒ์ ๋ก์ง์ ๋๋ถ๋ถ dino/lib/main.dart์ ๋ค์ด ์์ต๋๋ค.
Flutter ์ฑ์ main() ํจ์์์ ์์ํฉ๋๋ค.
void main() {
runApp(const MyApp());
}runApp์ Flutter์๊ฒ โ์ด ์์ ฏ์ ํ๋ฉด์ ์ฌ๋ ค๋ผโ๋ผ๊ณ ์๋ ค์ฃผ๋ ํจ์์
๋๋ค. ์ฌ๊ธฐ์๋ MyApp์ด ์ฑ์ ๊ฐ์ฅ ๋ฐ๊นฅ ์์ ฏ์
๋๋ค.
MyApp์ MaterialApp์ ๋ง๋ค๊ณ , ์ค์ ๊ฒ์ ํ๋ฉด์ธ DinoGamePage๋ฅผ ์ฒซ ํ๋ฉด์ผ๋ก ๋ณด์ฌ์ค๋๋ค.
๊ฒ์์ ๊ณ์ ์ํ๊ฐ ๋ฐ๋๋๋ค. ์์ ์ ์ธ์ง, ํ๋ ์ด ์ค์ธ์ง, ๊ฒ์ ์ค๋ฒ์ธ์ง์ ๋ฐ๋ผ ํ๋ฉด๊ณผ ์ ๋ ฅ ๋์์ด ๋ฌ๋ผ์ง๋๋ค.
์ด ์ํ๋ DinoGameStatus enum์ผ๋ก ํํํฉ๋๋ค.
enum DinoGameStatus { idle, playing, gameOver }idle: ์์ง ์์ํ์ง ์์ ์ํplaying: ๊ฒ์์ด ์งํ ์ค์ธ ์ํgameOver: ์ถฉ๋ํด์ ๋ค์ ์์์ ๊ธฐ๋ค๋ฆฌ๋ ์ํ
์บ๋ฆญํฐ ์ ํ์ RunnerCharacter enum์ผ๋ก ๊ด๋ฆฌํฉ๋๋ค.
enum RunnerCharacter { cat, dino }์ฌ์ฉ์๊ฐ ๊ณ ์์ด ๋๋ ๊ณต๋ฃก์ ์ ํํ๋ฉด ์ ๋ชฉ, ์บ๋ฆญํฐ ๊ทธ๋ฆผ, ์ฅ์ ๋ฌผ ๋ชจ์์ด ํจ๊ป ๋ฐ๋๋๋ค.
Flutter์์ ํ๋ฉด์ ๋ณด์ด๋ ๊ฐ์ด ๋ฐ๋์ด์ผ ํ๋ฉด ๋ณดํต StatefulWidget์ ์ฌ์ฉํฉ๋๋ค. ์ด ํ๋ก์ ํธ์ ํต์ฌ ํ๋ฉด์ธ DinoGamePage๊ฐ ๊ทธ ์ญํ ์ ํฉ๋๋ค.
๊ฒ์ ์ํ๋ _DinoGamePageState ์์ ๋ณ์๋ค๋ก ๊ด๋ฆฌ๋ฉ๋๋ค.
DinoGameStatus _status = DinoGameStatus.idle;
RunnerCharacter _character = RunnerCharacter.cat;
double _dinoLift = 0;
double _velocityY = 0;
double _obstacleX = 980;
double _speed = _baseSpeed;
double _distance = 0;
int _highScore = 0;
bool _isDucking = false;๊ฐ ๋ณ์๋ ๋ค์ ์๋ฏธ๋ฅผ ๊ฐ์ง๋๋ค.
_status: ํ์ฌ ๊ฒ์ ์ํ_character: ์ ํํ ์บ๋ฆญํฐ_dinoLift: ์บ๋ฆญํฐ๊ฐ ๋ฐ๋ฅ์์ ๋ ์๋ ๋์ด_velocityY: ์ ํ ์ค ์์๋ ์๋_obstacleX: ์ฅ์ ๋ฌผ์ ๊ฐ๋ก ์์น_speed: ๊ฒ์ ์๋_distance: ์ ์๋ฅผ ๊ณ์ฐํ๊ธฐ ์ํ ๋์ ๊ฑฐ๋ฆฌ_highScore: ์ต๊ณ ์ ์_isDucking: ์์ด๊ณ ์๋์ง ์ฌ๋ถ
๊ฐ์ด ๋ฐ๋ ๋ค ํ๋ฉด๋ ๋ค์ ๊ทธ๋ ค์ผ ํ ๋๋ setState๋ฅผ ํธ์ถํฉ๋๋ค. Flutter๋ setState๊ฐ ํธ์ถ๋๋ฉด ํ์ํ ๋ถ๋ถ์ ๋ค์ ๊ทธ๋ฆฝ๋๋ค.
์ผ๋ฐ ์ฑ์ ์ฌ์ฉ์๊ฐ ๋ฒํผ์ ๋๋ฅผ ๋๋ง ํ๋ฉด์ด ๋ฐ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ํ์ง๋ง ๊ฒ์์ ์ฌ์ฉ์๊ฐ ์๋ฌด๊ฒ๋ ํ์ง ์์๋ ๋งค ์๊ฐ ์บ๋ฆญํฐ์ ์ฅ์ ๋ฌผ์ด ์์ง์ฌ์ผ ํฉ๋๋ค.
์ด ํ๋ก์ ํธ๋ AnimationController๋ฅผ ๊ฒ์ ๋ฃจํ์ฒ๋ผ ์ฌ์ฉํฉ๋๋ค.
_gameLoop = AnimationController(
vsync: this,
duration: const Duration(days: 1),
)..addListener(_tick);addListener(_tick) ๋๋ฌธ์ ์ ๋๋ฉ์ด์
์ด ์งํ๋๋ ๋์ _tick์ด ๋ฐ๋ณตํด์ ํธ์ถ๋ฉ๋๋ค.
_tick์์๋ ๋ค์ ์ผ์ ์ฒ๋ฆฌํฉ๋๋ค.
- ์ด์ ํ๋ ์๊ณผ ํ์ฌ ํ๋ ์์ ์๊ฐ ์ฐจ์ด ๊ณ์ฐ
- ์ค๋ ฅ ์ ์ฉ
- ์ ํ ์์น ๊ฐฑ์
- ์ฅ์ ๋ฌผ ์ด๋
- ํ๋ ์ด ๊ฐ๋ฅํ ์ต์ ์ฅ์ ๋ฌผ ๊ฐ๊ฒฉ ๋ณด์ฅ
- ์ ์ ์ฆ๊ฐ
- ์๋ ์ฆ๊ฐ
- ์ถฉ๋ ๊ฒ์ฌ
- ๊ฒ์ ์ค๋ฒ ์ฒ๋ฆฌ
์ฌ๊ธฐ์ ์ค์ํ ์ ์ โํ๋ ์ ์โ๊ฐ ์๋๋ผ โ์ง๋ ์๊ฐโ์ ๊ธฐ์ค์ผ๋ก ์์ง์์ ๊ณ์ฐํ๋ค๋ ๊ฒ์ ๋๋ค. ๊ทธ๋์ ๊ธฐ๊ธฐ ์ฑ๋ฅ์ด ๋ฌ๋ผ๋ ๊ฒ์ ์๋๊ฐ ๋น๊ต์ ์ผ์ ํ๊ฒ ์ ์ง๋ฉ๋๋ค.
์ฅ์ ๋ฌผ์ ํ ๋ฒ์ ํ๋์ฉ ๋ฑ์ฅํฉ๋๋ค. ์ฅ์ ๋ฌผ์ด ํ๋ฉด ์ผ์ชฝ ๋ฐ์ผ๋ก ๋๊ฐ๋ฉด _resetObstacle์ด ๋ค์ ์ฅ์ ๋ฌผ์ ํ๋ฉด ์ค๋ฅธ์ชฝ ๋ฐ๊นฅ์ ๋ค์ ๋ฐฐ์นํฉ๋๋ค.
์ ์๊ฐ ๋์์ง์๋ก ๊ธฐ๋ณธ ๊ฐ๊ฒฉ์ ์ค์ด๋ค์ง๋ง, ๋๋ฌด ์ด์ดํด์ ธ์ ํผํ ์ ์๋ ์ํฉ์ด ์๊ธฐ์ง ์๋๋ก ์ต์ ํ๋ณต ์๊ฐ์ ๋ก๋๋ค.
final playableGap = _speed * _minimumObstacleRecoverySeconds;
_obstacleX = _viewportWidth + max(difficultyGap, playableGap);_minimumObstacleRecoverySeconds๋ ๋ค์ ์ฅ์ ๋ฌผ๊น์ง ์ต์ํ ํ๋ณดํ ์๊ฐ์ ๋ปํฉ๋๋ค. ํ์ฌ ๊ฐ์ 0.9์ด์
๋๋ค. ์๋๊ฐ ๋นจ๋ผ์ง์๋ก ํ์ํ ๊ฑฐ๋ฆฌ๋ ๊ฐ์ด ๋์ด๋๊ธฐ ๋๋ฌธ์, ๋์ด๋๋ ์ฌ๋ผ๊ฐ๋๋ผ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฐ์ํ ์ ์๋ ๊ฐ๊ฒฉ์ ์ ์ง๋ฉ๋๋ค.
ํฐ์น ์
๋ ฅ์ GestureDetector๊ฐ ์ฒ๋ฆฌํฉ๋๋ค.
GestureDetector(
onTap: _handleAction,
onLongPressStart: (_) => _setDucking(true),
onLongPressEnd: (_) => _setDucking(false),
)- ํญ: ์์, ์ ํ, ์ฌ์์
- ๊ธธ๊ฒ ๋๋ฅด๊ธฐ: ์์ด๊ธฐ
ํค๋ณด๋ ์
๋ ฅ์ _onKeyEvent์์ ์ฒ๋ฆฌํฉ๋๋ค.
Space,Enter,ArrowUp: ์์, ์ ํ, ์ฌ์์ArrowDown,S: ์์ด๊ธฐ
์ ํ ๋ก์ง์ _jump์ ์๊ณ , ์์ด๊ธฐ ๋ก์ง์ _setDucking์ ์์ต๋๋ค.
๊ฒ์ ์ค๋ฒ๋ ์บ๋ฆญํฐ์ ์ฅ์ ๋ฌผ์ด ๊ฒน์น ๋ ๋ฐ์ํฉ๋๋ค. ์ด ํ๋ก์ ํธ๋ ๋ณต์กํ ๋ฌผ๋ฆฌ ์์ง ๋์ Flutter์ Rect๋ฅผ ์ฌ์ฉํฉ๋๋ค.
์ถฉ๋ ๊ฒ์ฌ๋ _hasCollision์์ ํฉ๋๋ค.
final dinoRect = Rect.fromLTWH(
_dinoX,
_groundY - _dinoHeight - _dinoLift,
_dinoWidth,
_dinoHeight,
).deflate(7);์บ๋ฆญํฐ์ ์ฅ์ ๋ฌผ์ ๊ฐ๊ฐ ์ฌ๊ฐํ์ผ๋ก ๋ณด๊ณ , ๋ ์ฌ๊ฐํ์ด ๊ฒน์น๋ฉด ์ถฉ๋์
๋๋ค. deflate๋ ์ถฉ๋ ์์ญ์ ์กฐ๊ธ ์ค์ด๋ ์ญํ ์ ํฉ๋๋ค. ์ค์ ๊ทธ๋ฆผ๋ณด๋ค ์ถฉ๋ ๋ฐ์ค๊ฐ ์ด์ง ์์์ ธ์ ํ๋ ์ด ๊ฐ๊ฐ์ด ๋ ์์ฐ์ค๋ฌ์์ง๋๋ค.
๋ณดํต Flutter ํ๋ฉด์ Text, Container, Column, Row ๊ฐ์ ์์ ฏ์ ์กฐํฉํด์ ๋ง๋ญ๋๋ค. ํ์ง๋ง ๊ฒ์์ฒ๋ผ ์์ ๋ฌผ์ฒด๊ฐ ๋งค ํ๋ ์ ์์ง์ด๋ ํ๋ฉด์ ์บ๋ฒ์ค์ ์ง์ ๊ทธ๋ฆฌ๋ ๋ฐฉ์์ด ๋ ๋จ์ํ ์ ์์ต๋๋ค.
์ด ํ๋ก์ ํธ๋ DinoGamePainter๊ฐ ํ๋ฉด ๋๋ถ๋ถ์ ์ง์ ๊ทธ๋ฆฝ๋๋ค.
paint ๋ฉ์๋ ์์์ ๋ค์ ์์๊ฐ ๊ทธ๋ ค์ง๋๋ค.
- ๋ฎ/๋ฐค ๋ฐฐ๊ฒฝ
- ๊ตฌ๋ฆ
- ์ง๋ฉด
- ๊ณ ์์ด ๋๋ ๊ณต๋ฃก
- ํธ์ค๊ณต ๋๋ ์ ์ธ์ฅ
- ๋ ์์ค๋ ์ฅ๋๊ฐ ๋๋ ์ต๋ฃก
์บ๋ฆญํฐ ๊ทธ๋ฆผ์ ์ด๋ฏธ์ง ํ์ผ์ด ์๋๋๋ค. _drawCat๊ณผ _drawDino์์ ์ฌ๊ฐํ๊ณผ ์์ ์กฐํฉํด ํฝ์
์คํ์ผ๋ก ์ง์ ๊ทธ๋ฆฝ๋๋ค.
๋ฌ๋ฆฌ๊ธฐ ๋ค๋ฆฌ ๋ชจ์๊ณผ ๊ณต์ค ์ฅ์ ๋ฌผ์ ๋ ๊ฐ ๋ชจ์์ _animationTime์ ๊ธฐ์ค์ผ๋ก ์ฒ์ฒํ ๋ฐ๋๋๋ค. ์ ์๋ก ์ ๋๋ฉ์ด์
ํ๋ ์์ ๋ฐ๊พธ๋ฉด ์ ์๊ฐ ๋นจ๋ฆฌ ์ค๋ฅผ์๋ก ์์ง์๋ ๊ณผํ๊ฒ ๋นจ๋ผ์ง ์ ์์ด์, ์ค์ ์ด๋ ์๋์ ๊ทธ๋ฆผ ํ๋ ์ ์ ํ ์๋๋ฅผ ๋ถ๋ฆฌํ์ต๋๋ค.
ํ
์คํธ ์ฝ๋๋ dino/test/widget_test.dart์ ์์ต๋๋ค.
์ด ํ์ผ์ ์ฑ์ ์ค์ ๋ก ์คํํ์ง ์๊ณ ๋ ํ๋ฉด์ ์ฃผ์ ํ๋ฆ์ ๊ฒ์ฌํฉ๋๋ค.
- ์์ ํ๋ฉด์ ์ ์์ ์๋ด ๋ฌธ๊ตฌ๊ฐ ๋ณด์ด๋์ง
- ๊ณ ์์ด/๊ณต๋ฃก ์ ํ ๋ฒํผ์ด ์๋์ง
- ๊ณต๋ฃก ๋ฒํผ์ ๋๋ฅด๋ฉด ์ ๋ชฉ์ด
DINO RUNNER๋ก ๋ฐ๋๋์ง - ๊ฒ์ ํ๋ฉด์ ํญํ๋ฉด ๊ฒ์์ด ์์๋๋์ง
- ๊ฒ์ ์ค๋ฒ ์ํ์์ ๋ค์ ์์ํ ์ ์๋์ง
์๋ฅผ ๋ค์ด tester.tap์ ํ
์คํธ ์ค ๋ฒํผ์ ๋๋ฅด๋ ๋์์ ๋์ ํฉ๋๋ค.
๋จผ์ Flutter SDK๊ฐ ์ค์น๋์ด ์๊ณ flutter doctor์์ ์ฌ์ฉํ ๋์ ๊ธฐ๊ธฐ ๋๋ ๋ธ๋ผ์ฐ์ ๊ฐ ์กํ๋์ง ํ์ธํฉ๋๋ค.
flutter doctorํ๋ก์ ํธ ๋ฃจํธ์์ ์ฑ ํด๋๋ก ์ด๋ํฉ๋๋ค.
cd dino์น ๋ธ๋ผ์ฐ์ ์์ ๊ฐ๋ฐ ๋ชจ๋๋ก ์คํํฉ๋๋ค.
flutter run -d chromemacOS ๋ฐ์คํฌํฑ ์ฑ์ผ๋ก ์คํํ๋ ค๋ฉด macOS ํ๊ฒฝ์์ ์๋ ๋ช ๋ น์ ์ฌ์ฉํฉ๋๋ค.
flutter run -d macos์ฐ๊ฒฐ๋ ์คํ ๋์์ ํ์ธํ๋ ค๋ฉด ์๋ ๋ช ๋ น์ ์ฌ์ฉํฉ๋๋ค.
flutter devices์น ๋๋ฒ๊ทธ ์คํ์์ ๋น ํ๋ฉด์ด ๋ณด์ด๋ฉด ์ ์ ์น ๋น๋๋ก ์คํํฉ๋๋ค.
flutter build web
cd build/web
python -m http.server 5178 --bind 127.0.0.1Windows์์ python ๋ช
๋ น์ด ๋์ํ์ง ์์ผ๋ฉด py -m http.server 5178 --bind 127.0.0.1์ ์ฌ์ฉํฉ๋๋ค.
๋ธ๋ผ์ฐ์ ์์ ์๋ ์ฃผ์๋ฅผ ์ฝ๋๋ค.
http://127.0.0.1:5178
์ฑ ํด๋์ธ dino ์์์ ์คํํฉ๋๋ค.
dart format lib/main.dart test/widget_test.dart
flutter analyze
flutter test
flutter build web๊ฐ ๋ช ๋ น์ ์๋ฏธ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
dart format: Dart ์ฝ๋ ์คํ์ผ ์ ๋ฆฌflutter analyze: ๋ฌธ๋ฒ, ํ์ , ๊ถ์ฅ ๊ท์น ๊ฒ์ฌflutter test: ํ ์คํธ ์คํflutter build web: ์น ๋ฐฐํฌ์ฉ ๋น๋ ์์ฑ
์ฒ์ Flutter๋ฅผ ๋ณธ๋ค๋ฉด ์๋ ์์๋ก ์ฝ๋ ๊ฒ์ด ์ข์ต๋๋ค.
dino/pubspec.yaml์์ ํ๋ก์ ํธ ์ค์ ํ์ธmain()๊ณผMyApp์ผ๋ก ์ฑ ์์ ํ๋ฆ ํ์ธDinoGamePage์์ ์ํ ๋ณ์๊ฐ ์ด๋ป๊ฒ ์ ์ธ๋๋์ง ํ์ธ_onKeyEvent์GestureDetector์์ ์ ๋ ฅ ์ฒ๋ฆฌ ํ์ธ_tick์์ ๊ฒ์์ด ๋งค ํ๋ ์ ๊ฐฑ์ ๋๋ ๋ฐฉ์ ํ์ธ_resetObstacle์์ ์ฅ์ ๋ฌผ ๊ฐ๊ฒฉ์ ์กฐ์ ํ๋ ๋ฐฉ์ ํ์ธDinoGamePainter์์ ํ๋ฉด์ ์ง์ ๊ทธ๋ฆฌ๋ ๋ฐฉ์ ํ์ธwidget_test.dart์์ UI ๋์์ ํ ์คํธํ๋ ๋ฐฉ์ ํ์ธ
- Flutter ์ฑ์
main()์์ ์์ํด ์์ ฏ์ ํ๋ฉด์ ์ฌ๋ฆฝ๋๋ค. - ํ๋ฉด์ ๋ฐ๋๋ ๊ฐ์ด ์์ผ๋ฉด
StatefulWidget๊ณผsetState๋ก ๊ด๋ฆฌํ ์ ์์ต๋๋ค. - ๊ฒ์์ฒ๋ผ ๊ณ์ ์์ง์ด๋ ํ๋ฉด์
AnimationController๋ก ๋ฐ๋ณต ๊ฐฑ์ ํ ์ ์์ต๋๋ค. CustomPainter๋ฅผ ์ฌ์ฉํ๋ฉด ์ด๋ฏธ์ง ์์ด๋ ์บ๋ฒ์ค์ ์ง์ ์บ๋ฆญํฐ์ ๋ฐฐ๊ฒฝ์ ๊ทธ๋ฆด ์ ์์ต๋๋ค.- ์ฅ์ ๋ฌผ ๊ฐ๊ฒฉ์ ํ์ฌ ์๋๋ฅผ ๊ณ ๋ คํด โํผํ ์ ์๋ ์ต์ ์๊ฐโ์ ๋ณด์ฅํด์ผ ํฉ๋๋ค.
- ์์ง์ ์ ๋๋ฉ์ด์ ์ ์ ์๋ณด๋ค ๋ณ๋ ์๊ฐ ๊ฐ์ ๊ธฐ์ค์ผ๋ก ๋๋ ํธ์ด ์์ ์ ์ ๋๋ค.
- ํค๋ณด๋์ ํฐ์น ์
๋ ฅ์ ๊ฐ๊ฐ
Focus,GestureDetector๋ก ๋ฐ์ ์ ์์ต๋๋ค. - ์์ ๊ฒ์์ด๋ผ๋ฉด ๋ณ๋ ๊ฒ์ ์์ง ์์ด Flutter ๊ธฐ๋ณธ ๊ธฐ๋ฅ๋ง์ผ๋ก๋ ์ถฉ๋ถํ ๋ง๋ค ์ ์์ต๋๋ค.