Skip to content

Instantly share code, notes, and snippets.

@hardy716
Last active January 25, 2024 23:02
Show Gist options
  • Save hardy716/9da3bb0b25a898b93fa1f80e4f1ef400 to your computer and use it in GitHub Desktop.
Save hardy716/9da3bb0b25a898b93fa1f80e4f1ef400 to your computer and use it in GitHub Desktop.
플러터챌린지 4일차 심화문제 - 신현호

플러터챌린지 4일차 심화문제 - 신현호

Created with <3 with dartpad.dev.

import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'CatchGreen',
debugShowCheckedModeBanner: false,
home: CatchGreenScreen(),
);
}
}
class CatchGreenScreen extends StatefulWidget {
@override
State<CatchGreenScreen> createState() => _CatchGreenScreenState();
}
class _CatchGreenScreenState extends State<CatchGreenScreen> {
bool _isGameStarted = false;
void _startGame() {
setState(() {
_isGameStarted = true;
});
}
void _stopGame() {
setState(() {
_isGameStarted = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_TimeBoard(
isGameStarted: _isGameStarted,
onStartGame: _startGame,
),
Expanded(
child: Container(
color: Colors.black,
child: _GameBoard(
isGameStarted: _isGameStarted,
onStopGame: _stopGame,
),
),
),
Container(
height: 100,
color: Colors.white,
),
],
),
),
),
);
}
}
class _TimeBoard extends StatefulWidget {
final bool isGameStarted;
final VoidCallback onStartGame;
const _TimeBoard({
required this.isGameStarted,
required this.onStartGame,
});
@override
State<_TimeBoard> createState() => _TimeBoardState();
}
class _TimeBoardState extends State<_TimeBoard> {
late Timer _timer;
late DateTime _startDateTime;
String _timerToString = '0:0.0';
@override
void didUpdateWidget(_TimeBoard oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.isGameStarted && !_timer.isActive) {
_startTimer();
} else if (!widget.isGameStarted && _timer.isActive) {
_stopTimer();
}
}
@override
void initState() {
super.initState();
_startDateTime = DateTime.now();
_timer = Timer.periodic(const Duration(milliseconds: 1), (timer) => _timer.cancel());
}
void _startTimer() {
_startDateTime = DateTime.now();
if (!_timer.isActive) {
_timer = Timer.periodic(const Duration(milliseconds: 1), (timer) => _updateTimer());
}
setState(() => _timerToString = '0:0.0');
}
void _stopTimer() {
_timer.cancel();
_updateTimer();
}
void _updateTimer() {
final diffTime = DateTime.now().difference(_startDateTime);
final m = diffTime.inMinutes.remainder(60);
final s = diffTime.inSeconds.remainder(60);
final ms = diffTime.inMilliseconds.remainder(1000).toString().padLeft(3, '0');
setState(() => _timerToString = '$m:$s.$ms');
}
void _buttonPressed() {
widget.onStartGame();
_startTimer();
}
@override
void dispose() {
if (_timer.isActive) {
_timer.cancel();
}
super.dispose();
}
@override
Widget build(BuildContext context) {
return SizedBox(
height: 140,
child: Column(
children: [
const SizedBox(height: 10),
Text(
'Catch green game',
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 36),
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Visibility(
visible: !widget.isGameStarted,
child: ElevatedButton(
onPressed: _buttonPressed,
child: const Text('Start!'),
),
),
const SizedBox(height: 10),
Text(
_timerToString,
style: Theme.of(context).textTheme.bodyMedium,
),
],
),
],
),
);
}
}
class _GameBoard extends StatefulWidget {
final bool isGameStarted;
final VoidCallback onStopGame;
const _GameBoard({
required this.isGameStarted,
required this.onStopGame
});
@override
State<_GameBoard> createState() => _GameBoardState();
}
class _GameBoardState extends State<_GameBoard> {
bool _show = false;
final double greenSize = 50;
double screenWidth = 0;
double screenHeight = 0;
void showGreen() {
setState(() => _show = true);
}
@override
void didUpdateWidget(_GameBoard oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.isGameStarted && !_show) {
showGreen();
} else if (!widget.isGameStarted && _show) {
setState(() => _show = false);
}
}
@override
Widget build(BuildContext context) {
return Container(
color: Colors.transparent,
child: LayoutBuilder(
builder: (context, constraint) {
screenWidth = constraint.maxWidth;
screenHeight = constraint.maxHeight;
return Stack(
children: [
if (_show)
Positioned(
left: Random().nextDouble() * (screenWidth - greenSize),
top: Random().nextDouble() * (screenHeight - greenSize),
child: GestureDetector(
onTap: () => setState(() {
_show = false;
widget.onStopGame();
}),
child: Container(
width: greenSize,
height: greenSize,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(greenSize / 2),
color: Colors.green,
),
),
),
),
],
);
},
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment