flutter-wordle/lib/game_page.dart
2022-03-11 14:59:31 +08:00

175 lines
6.0 KiB
Dart

/*
* @Author : Linloir
* @Date : 2022-03-05 20:41:41
* @LastEditTime : 2022-03-11 14:54:15
* @Description : Offline page
*/
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:wordle/event_bus.dart';
import 'package:wordle/validation_provider.dart';
import 'package:wordle/display_pannel.dart';
import 'package:wordle/instruction_pannel.dart';
import 'package:wordle/popper_generator.dart';
class GamePage extends StatefulWidget {
const GamePage({Key? key, required this.database, required this.wordLen, required this.maxChances, required this.gameMode}) : super(key: key);
final Map<String, List<String>> database;
final int wordLen;
final int maxChances;
final int gameMode;
@override
State<GamePage> createState() => _GamePageState();
}
class _GamePageState extends State<GamePage> with TickerProviderStateMixin{
late AnimationController _controller;
void _onGameEnd(dynamic args) {
var result = args as bool;
if(result == true) {
_controller.forward().then((v) {
_controller.reset();
mainBus.emit(event: "Result", args: result);
}
);
}
else {
mainBus.emit(event: "Result", args: result);
}
}
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this, duration: const Duration(milliseconds: 2000));
mainBus.onBus(event: "ValidationEnds", onEvent: _onGameEnd);
}
@override
void dispose() {
mainBus.offBus(event: "ValidationEnds", callBack: _onGameEnd);
super.dispose();
}
@override
Widget build(BuildContext context) {
var mode = Theme.of(context).brightness;
return Stack(
children: [
Positioned.fill(
child: Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).brightness == Brightness.dark ? Colors.grey[850] : Colors.white,
elevation: 0.0,
shadowColor: Colors.transparent,
toolbarHeight: 80.0,
titleTextStyle: TextStyle(
color: Theme.of(context).brightness == Brightness.dark ? Colors.grey[100] : Colors.black,
fontWeight: FontWeight.bold,
fontSize: 20.0,
),
title: const Text('WORDLE'),
centerTitle: true,
//iconTheme: const IconThemeData(color: Colors.black),
actions: [
AnimatedSwitcher(
duration: const Duration(milliseconds: 750),
reverseDuration: const Duration(milliseconds: 750),
switchInCurve: Curves.bounceOut,
switchOutCurve: Curves.bounceIn,
transitionBuilder: (child, animation) {
var rotateAnimation = Tween<double>(begin: 0, end: 2 * pi).animate(animation);
var opacAnimation = Tween<double>(begin: 0, end: 1).animate(animation);
return AnimatedBuilder(
animation: rotateAnimation,
builder: (context, child) {
return Transform(
transform: Matrix4.rotationZ(rotateAnimation.status == AnimationStatus.reverse ? 2 * pi - rotateAnimation.value : rotateAnimation.value),
alignment: Alignment.center,
child: Opacity(
opacity: opacAnimation.value,
child: child,
),
);
},
child: child,
);
},
child: IconButton(
key: ValueKey(mode),
icon: mode == Brightness.light ? const Icon(Icons.dark_mode_outlined) : const Icon(Icons.dark_mode),
onPressed: () => mainBus.emit(event: "ToggleTheme", args: []),
),
),
IconButton(
icon: const Icon(Icons.help_outline_outlined),
//color: Colors.black,
onPressed: (){
showInstructionDialog(context: context);
},
),
IconButton(
icon: const Icon(Icons.refresh_rounded),
//color: Colors.black,
onPressed: (){
mainBus.emit(event: "NewGame", args: []);
},
),
],
),
body: Container(
child: ValidationProvider(
database: widget.database,
wordLen: widget.wordLen,
maxChances: widget.maxChances,
gameMode: widget.gameMode,
child: WordleDisplayWidget(wordLen: widget.wordLen, maxChances: widget.maxChances),
),
color: Theme.of(context).brightness == Brightness.dark ? Colors.grey[850] : Colors.white,
),
),
),
Positioned.fill(
child: PartyPopperGenerator(
direction: PopDirection.fowardX,
motionCurveX: FunctionCurve(func: (t) {
return - t * t / 2 + t;
}),
motionCurveY: FunctionCurve(func: (t) {
return 4 / 3 * t * t - t / 3;
}),
numbers: 50,
posX: -60.0,
posY: 30.0,
pieceHeight: 15.0,
pieceWidth: 30.0,
controller: _controller,
),
),
Positioned.fill(
child: PartyPopperGenerator(
direction: PopDirection.backwardX,
motionCurveX: FunctionCurve(func: (t) {
return - t * t / 2 + t;
}),
motionCurveY: FunctionCurve(func: (t) {
return 4 / 3 * t * t - t / 3;
}),
numbers: 50,
posX: -60.0,
posY: 30.0,
pieceHeight: 15.0,
pieceWidth: 30.0,
controller: _controller,
),
),
],
);
}
}