Flutter와 Firebase를 사용하여 수학 게임을 만든 방법
무언가를 배우는 가장 좋은 방법은 무언가를 만드는 것입니다.
오프라인 프로그래머 ・ 2020년 10월 19일 ・ 3분 읽기
#watercooler
#motivation
#beginners
#learning
BrainTrainer는 30초 동안 최대한 많은 문제를 풀어야 하는 수학 게임입니다. 가장 높은 점수는 앱 바에 표시되고 Firebase에 저장됩니다.
게임은 총 2개의 화면으로 구성되어 있습니다. main.dart에서 표시할 화면을 결정하기 위해 firebase 사용자를 관찰합니다.
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final firebaseUser = context.watch<User>();
return Scaffold(
appBar: AppBar(
title: Text('BrainTrainer'),
),
body: firebaseUser != null ? loadGameScreen(context) : LoginPage());
}
Future<Object> loadGameScreen(BuildContext context) {
Future.delayed(Duration.zero, () {
return Navigator.of(context).pushNamedAndRemoveUntil(
GameScreen.routeName, (Route<dynamic> route) => false);
});
}
}
우리는 Firebase를 사용하여 (Apple 로그인)을 활성화하기 위해 공급자를 사용하고 있습니다. 그것에 대한 내 이전 게시물을 확인하십시오.
Flutter Firebase 인증: Apple 로그인
오프라인 프로그래머 ・ 2월 17일 ・ 5분 읽기
#flutter
#ios
#tutorial
#firebase
우리는 게임에서 몇 가지 위젯을 사용하고 있습니다.
ActionButtons Widget: 게임을 시작하기 위한 재생 버튼을 표시하는 곳입니다. 또한 선택한 답변이 올바른지 또는 지금인지 플레이어에게 표시하는 데 사용합니다.
import 'package:brain_trainer_app/models/game.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ActionButtons extends StatefulWidget {
const ActionButtons({
Key key,
}) : super(key: key);
@override
_ActionButtonsState createState() => _ActionButtonsState();
}
class _ActionButtonsState extends State<ActionButtons> {
@override
Widget build(BuildContext context) {
final _game = Provider.of<Game>(context);
return SizedBox(
height: 100,
child: GestureDetector(
onTap: () {
_game.playTheGame();
},
child: Card(
margin: EdgeInsets.all(10),
elevation: 8,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(color: Colors.white, spreadRadius: 3),
],
),
padding: EdgeInsets.all(10),
child: Consumer<Game>(
builder: (context, game, child) {
return Image.asset(
_game.actionButtonImage,
fit: BoxFit.cover,
);
},
),
),
),
),
);
}
}
AnswerItem 위젯: 이것은 플레이어가 선택할 수 있는 숫자를 표시하는 그리드의 항목을 나타냅니다. 그 항목 중 하나가 정답이 될 것입니다.
import 'package:brain_trainer_app/models/game.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class AnswerItem extends StatelessWidget {
final Answer answer;
final int index;
static const _answercolot = [
Color.fromRGBO(224, 81, 98, 1),
Color.fromRGBO(84, 160, 86, 1),
Color.fromRGBO(68, 150, 224, 1),
Color.fromRGBO(111, 64, 222, 1),
];
const AnswerItem({Key key, this.answer, this.index}) : super(key: key);
@override
Widget build(BuildContext context) {
final _game = Provider.of<Game>(context);
return ClipRRect(
borderRadius: BorderRadius.circular(10),
child: GridTile(
child: GestureDetector(
onTap: () {
_game.answerSelected(this.answer);
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: _answercolot[this.index],
boxShadow: [
BoxShadow(color: Colors.white, spreadRadius: 3),
],
),
padding: EdgeInsets.all(10),
child: Center(
child: Text(
answer.value.toString(),
style: TextStyle(
fontSize: 24,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.bold),
)),
),
),
),
);
}
}
AnswersGrid 위젯: 4개의 AnswerItem 위젯으로 구성된 그리드입니다.
import 'package:brain_trainer_app/models/game.dart';
import 'package:brain_trainer_app/widgets/answer_item.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class AnswersGrid extends StatelessWidget {
@override
@override
Widget build(BuildContext context) {
final gameData = Provider.of<Game>(context);
final answers = gameData.answers;
return GridView.builder(
padding: const EdgeInsets.all(10.0),
itemCount: answers.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 3 / 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10),
itemBuilder: (BuildContext context, int index) {
return AnswerItem(
answer: answers[index],
index: index,
);
});
}
}
GameAds 위젯: Google AdMob 광고를 표시하는 곳입니다.
import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
class GameAds extends StatefulWidget {
@override
_GameAdsState createState() => _GameAdsState();
}
class _GameAdsState extends State<GameAds> {
BannerAd _bannerAd;
@override
void initState() {
super.initState();
MobileAds.instance.initialize();
_bannerAd = BannerAd(
size: AdSize.banner,
adUnitId: BannerAd.testAdUnitId,
listener: AdListener(),
request: AdRequest(),
);
_bannerAd..load();
}
@override
void dispose() {
super.dispose();
_bannerAd.dispose();
}
@override
Widget build(BuildContext context) {
return SizedBox(height: 50, child: AdWidget(ad: _bannerAd));
}
}
GameConfetti 위젯: 이 재미있는 위젯을 사용하여 플레이가 게임을 마칠 때 축하 애니메이션을 표시합니다.
import 'package:brain_trainer_app/models/game.dart';
import 'package:confetti/confetti.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:rflutter_alert/rflutter_alert.dart';
class GameConfetti extends StatefulWidget {
@override
_GameConfettiState createState() => _GameConfettiState();
}
class _GameConfettiState extends State<GameConfetti> {
ConfettiController _controllerCenter;
@override
void initState() {
_controllerCenter =
ConfettiController(duration: const Duration(seconds: 10));
_controllerCenter.play();
super.initState();
}
@override
void dispose() {
_controllerCenter.dispose();
super.dispose();
}
_showAlert(context) {
Future.delayed(Duration.zero, () async {
final String _gameMsg =
Provider.of<Game>(context, listen: false).completionMsg;
var alertStyle = AlertStyle(
animationType: AnimationType.fromTop,
isCloseButton: false,
isOverlayTapDismiss: false,
descStyle: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
descTextAlign: TextAlign.start,
animationDuration: Duration(milliseconds: 400),
overlayColor: Colors.transparent,
alertBorder: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0.0),
side: BorderSide(
color: Colors.grey,
),
),
titleStyle: TextStyle(
color: Colors.green,
),
alertAlignment: Alignment.center,
);
Alert(
style: alertStyle,
context: context,
type: AlertType.success,
title: "Well done",
desc: _gameMsg,
buttons: [
DialogButton(
child: Text(
"Brilliant!!!",
style: TextStyle(color: Colors.white, fontSize: 16),
),
onPressed: () => Navigator.pop(context),
width: 120,
)
],
).show();
});
}
@override
Widget build(BuildContext context) {
return Align(
alignment: Alignment.topCenter,
child: ConfettiWidget(
confettiController: _controllerCenter,
blastDirectionality: BlastDirectionality
.explosive, // don't specify a direction, blast randomly
shouldLoop: false,
gravity: 0.5,
emissionFrequency: 0.05,
numberOfParticles:
20, // start again as soon as the animation is finished
colors: const [
Colors.green,
Colors.blue,
Colors.pink,
Colors.orange,
Colors.purple
], // manually specify the colors to be used
child: _showAlert(context)
),
);
}
}
TimerQuestionScoreRow 위젯: 여기에서 30초 타이머, 수학 문제를 보여주고 플레이어 점수/
import 'package:brain_trainer_app/models/game.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class TimerQuestionScoreRow extends StatefulWidget {
const TimerQuestionScoreRow({
Key key,
}) : super(key: key);
@override
_TimerQuestionScoreRowState createState() => _TimerQuestionScoreRowState();
}
class _TimerQuestionScoreRowState extends State<TimerQuestionScoreRow> {
@override
Widget build(BuildContext context) {
final _game = Provider.of<Game>(context);
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
flex: 3,
child: SizedBox(
height: 100,
child: Card(
margin: EdgeInsets.all(10),
elevation: 8,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Color.fromRGBO(255, 152, 0, 1),
boxShadow: [
BoxShadow(color: Colors.white, spreadRadius: 3),
],
),
padding: EdgeInsets.all(10),
child: Consumer<Game>(
builder: (context, game, child) {
return Center(
child: Text(
'${game.timer}s',
style:
TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
));
},
),
),
),
),
),
Expanded(
flex: 4,
child: SizedBox(
height: 100,
child: Card(
margin: EdgeInsets.all(10),
elevation: 8,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(color: Colors.white, spreadRadius: 3),
],
),
padding: EdgeInsets.all(10),
child: Consumer<Game>(
builder: (context, game, child) {
return Center(
child: Text(
'${game.question}',
style:
TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
));
},
),
),
),
),
),
Expanded(
flex: 3,
child: SizedBox(
height: 100,
child: Card(
margin: EdgeInsets.all(10),
elevation: 8,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Color.fromRGBO(3, 169, 244, 1),
boxShadow: [
BoxShadow(color: Colors.white, spreadRadius: 3),
],
),
padding: EdgeInsets.all(10),
child: Consumer<Game>(
builder: (context, game, child) {
return Center(
child: Text(
'${game.score}',
style:
TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
));
},
),
),
),
),
),
],
);
}
}
게임은 세 가지 모델을 사용합니다.
게임: 게임을 설정하는 기본 모델입니다. 여기에서 선택한 답변을 확인하고 타이머를 추적합니다.
답변: 답변 값을 나타내는 간단한 모델입니다.
플레이어: Firebase에서 가져온 플레이어 정보가 있는 곳이며 최고 점수를 추적하는 데도 사용합니다.
DataRepository 클래스를 사용하여 데이터를 검색하고 저장합니다.
import 'package:brain_trainer_app/models/player.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class DataRepository {
final CollectionReference collection =
FirebaseFirestore.instance.collection('players');
Future<void> addPlayer(Player player) {
return collection.doc(player.uid).set(player.toJson());
}
updatePlayer(Player player) async {
await collection.doc(player.uid).update(player.toJson());
}
Future<Player> getPlayer(String uid) async {
var doc = await collection.doc(uid).get();
if (doc.data() == null) {
return null;
}
return Player.fromJson(doc.data());
}
}
이 게임은 Apple Storehere 및 Google Playhere에 있습니다.
여기에서 코드를 확인하세요
오프라인 프로그래머 / brain_trainer_flutter
brain_trainer_app
수학을 즐기십니까? 게임을 즐기십니까? 긴장을 풀고 두뇌를 훈련하고 싶습니까? 재미를 위해 이 놀라운 앱을 사용해 보세요 – Brain Trainer.
Brain Trainer는 기억력, 속도 및 주의력을 훈련하도록 설계된 간단한 수학 기반 게임으로 구성되어 있습니다. 바쁜 일정에서 휴식을 취하고 Brain Trainer를 사용하여 휴식을 취하고 수학을 연습하십시오.
View on GitHub
Follow me on for more tips about #coding, #learning, #technology...etc.
Check my Apps on Google Play
Cover image Amol Tyagi on Unsplash
Reference
이 문제에 관하여(Flutter와 Firebase를 사용하여 수학 게임을 만든 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/offlineprogrammer/how-i-built-a-math-game-using-flutter-firebase-i4o
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Follow me on for more tips about #coding, #learning, #technology...etc.
Check my Apps on Google Play
Cover image Amol Tyagi on Unsplash
Reference
이 문제에 관하여(Flutter와 Firebase를 사용하여 수학 게임을 만든 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/offlineprogrammer/how-i-built-a-math-game-using-flutter-firebase-i4o텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)