미니게임 (색상 스트룹 테스트)
글자의 색에 흔들리지 않고 화면에 제시된 목표 색과 같은 색 이름을 고르는 집중력 게임을 만듭니다.
동작
미니게임 (색상 스트룹 테스트) 실행 화면
화면에는 목표 색상이 크게 표시됩니다. 선택지는 색 이름 텍스트로 나오지만, 글자색은 다른 색으로 섞입니다. 게임 시작을 누르면 15초 제한 시간이 흐릅니다. 사용자는 글자색이 아니라 목표 색상과 같은 색 이름을 골라 점수를 얻습니다.
예제 코드
색상 스트룹 테스트
import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
class StroopColorGame extends StatefulWidget {
const StroopColorGame({super.key});
@override
State<StroopColorGame> createState() => _StroopColorGameState();
}
class _StroopColorGameState extends State<StroopColorGame> {
final random = Random();
final colors = [
{'name': '파랑', 'color': Colors.blue},
{'name': '초록', 'color': Colors.green},
{'name': '보라', 'color': Colors.purple},
{'name': '빨강', 'color': Colors.red},
{'name': '노랑', 'color': Colors.amber},
{'name': '검정', 'color': Colors.black},
];
int targetIndex = 0;
int score = 0;
int seconds = 15;
bool playing = false;
Timer? timer;
void pickNextQuestion() {
var next = targetIndex;
while (next == targetIndex) {
next = random.nextInt(colors.length);
}
targetIndex = next;
}
void chooseName(int index) {
if (!playing) return;
setState(() {
if (index == targetIndex) {
score += 1;
pickNextQuestion();
}
});
}
void startGame() {
timer?.cancel();
setState(() {
score = 0;
seconds = 15;
playing = true;
pickNextQuestion();
});
timer = Timer.periodic(const Duration(seconds: 1), (timer) {
setState(() {
seconds -= 1;
if (seconds <= 0) {
seconds = 0;
playing = false;
timer.cancel();
}
});
});
}
@override
void dispose() {
timer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
final target = colors[targetIndex];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('점수: $score · 시간: $seconds초'),
ElevatedButton(onPressed: startGame, child: const Text('게임 시작')),
Container(
width: 120,
height: 80,
color: target['color'] as Color,
child: const Center(child: Text('목표 색')),
),
Wrap(
spacing: 8,
children: List.generate(colors.length, (index) {
final textColor = colors[random.nextInt(colors.length)]['color'] as Color;
return ElevatedButton(
onPressed: () => chooseName(index),
child: Text(
colors[index]['name'] as String,
style: TextStyle(color: textColor),
),
);
}),
),
],
);
}
}
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('목표 파랑'))],
),
const SizedBox(height: 14),
SizedBox(
width: 320,
height: 220,
child: Wrap(
spacing: 8,
children: colors.map((color) {
return FilledButton.tonal(
onPressed: () => chooseColor(colors.indexOf(color)),
child: Text(color),
);
}).toList(),
),
),
],
),
)
예제 코드 기능별 설명
코드를 나누어 읽기
import
dart:async은 15초 제한 시간을 세는 Timer에 필요하고, dart:math는 다음 목표 색과 선택지 색을 무작위로 고르는 Random에 필요합니다. material.dart는 버튼, 텍스트, 색상 위젯을 만들기 위해 가져옵니다.
import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
StatefulWidget 클래스
스트룹 테스트는 점수, 남은 시간, 현재 목표 색이 계속 바뀌므로 StatefulWidget으로 만듭니다. 화면이 바뀌는 값은 State 클래스 안에 둡니다.
class StroopColorGame extends StatefulWidget {
const StroopColorGame({super.key});
}
상태 변수
targetIndex는 현재 맞혀야 하는 목표 색, score는 점수, seconds는 남은 시간, playing은 게임 진행 여부입니다. Timer는 게임이 끝나거나 다시 시작될 때 cancel해야 합니다.
int targetIndex = 0;
int score = 0;
int seconds = 15;
bool playing = false;
Timer? timer;
랜덤 목표 색
색과 색 이름이 고정 순서로 반복되면 게임성이 약해지므로 Random으로 다음 targetIndex를 뽑습니다. 이전 문제와 같은 값은 다시 뽑아 변화가 느껴지게 합니다.
void pickNextColor() {
var next = targetIndex;
while (next == targetIndex) {
next = random.nextInt(colors.length);
}
targetIndex = next;
}
정답 검사
사용자가 누른 버튼의 index와 현재 목표 index를 비교합니다. 정답일 때 점수를 올리고 다음 색과 색 이름을 새로 뽑습니다.
if (index == targetIndex) {
score += 1;
targetIndex = (targetIndex + 1) % colors.length;
}
색 데이터 묶기
이름과 실제 색 값을 한 목록에 묶어 두면 화면에는 색상 박스를, 버튼에는 색 이름을 같은 데이터에서 꺼내 쓸 수 있습니다.
final colors = [
{'name': '파랑', 'color': Colors.blue},
{'name': '초록', 'color': Colors.green},
];