입문
미니게임 (별 잡기)
StatefulWidget, setState, Timer, Stack을 사용해 별을 잡는 간단한 게임을 만듭니다.
동작
미니게임 (별 잡기) 실행 화면
별 잡기 게임
점수 0
시간 15초
화면에 나타나는 별을 제한 시간 안에 눌러 점수를 얻습니다. 별을 누르면 점수가 올라가고 별 위치가 바뀝니다. 시간이 끝나면 게임이 멈추고 다시 시작 버튼으로 초기화합니다.
예제 코드
별 잡기 게임
import 'dart:async';
import 'package:flutter/material.dart';
class StarCatcherGame extends StatefulWidget {
const StarCatcherGame({super.key});
@override
State<StarCatcherGame> createState() => _StarCatcherGameState();
}
class _StarCatcherGameState extends State<StarCatcherGame> {
int score = 0;
int seconds = 15;
double starX = 120;
double starY = 90;
Timer? timer;
void startGame() {
timer?.cancel();
setState(() {
score = 0;
seconds = 15;
starX = 120;
starY = 90;
});
timer = Timer.periodic(const Duration(seconds: 1), (timer) {
if (seconds == 0) {
timer.cancel();
return;
}
setState(() => seconds -= 1);
});
}
void catchStar() {
if (seconds == 0) return;
setState(() {
score += 1;
starX = (score * 47 % 220).toDouble();
starY = (score * 73 % 150).toDouble();
});
}
@override
void dispose() {
timer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('점수: $score 시간: $seconds'),
const SizedBox(height: 12),
SizedBox(
width: 320,
height: 220,
child: Stack(
children: [
Positioned(
left: starX,
top: starY,
child: ElevatedButton(
onPressed: catchStar,
child: const Text('★'),
),
),
],
),
),
ElevatedButton(
onPressed: startGame,
child: const Text('게임 시작'),
),
],
);
}
}
Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: const Color(0xFFDCE6EF)),
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'별 잡기 게임',
style: TextStyle(fontSize: 22, fontWeight: FontWeight.w900),
),
const SizedBox(height: 14),
Wrap(
spacing: 8,
children: const [Chip(label: Text('점수 0')), Chip(label: Text('시간 15초'))],
),
const SizedBox(height: 14),
SizedBox(
width: 320,
height: 220,
child: Stack(
children: [
Positioned(
left: starX,
top: starY,
child: FilledButton(
onPressed: catchStar,
child: const Text('★'),
),
),
],
),
),
],
),
)
별 잡기 게임
점수 0
시간 15초
예제 코드 기능별 설명
코드를 나누어 읽기
import
dart:async은 제한 시간을 줄이는 Timer에 필요하고, material.dart는 버튼, 텍스트, Stack, Positioned 같은 화면 위젯을 제공합니다.
import 'dart:async';
import 'package:flutter/material.dart';
StatefulWidget 클래스
별 위치, 점수, 남은 시간이 계속 바뀌므로 StatefulWidget으로 만듭니다. 바뀌는 값은 _StarCatcherGameState 안에서 관리합니다.
class StarCatcherGame extends StatefulWidget {
const StarCatcherGame({super.key});
}
상태값
점수, 남은 시간, 별의 좌표를 State 안에 둡니다. 사용자가 별을 누르거나 시간이 흐를 때 이 값들이 바뀌고 화면이 다시 그려집니다.
int score = 0;
int seconds = 15;
double starX = 120;
double starY = 90;
게임 시작
기존 타이머를 멈춘 뒤 점수와 시간을 초기값으로 되돌립니다. Timer.periodic으로 1초마다 남은 시간을 줄입니다.
void startGame() {
timer?.cancel();
setState(() {
score = 0;
seconds = 15;
});
}
별 잡기
별을 누르면 점수를 올리고 다음 위치를 계산합니다. setState 안에서 좌표를 바꾸기 때문에 Stack 안의 버튼 위치가 바뀝니다.
void catchStar() {
if (seconds == 0) return;
setState(() {
score += 1;
starX = (score * 47 % 220).toDouble();
});
}