game_page.dart 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import 'dart:async';
  2. import 'package:battle/button/button_controller.dart';
  3. import 'package:battle/data/card.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:widget/widget.dart';
  6. import '../button/button_painter.dart';
  7. import 'setting_page.dart';
  8. import 'view/count_down_dialog.dart';
  9. class GamePage extends StatefulWidget {
  10. final CardItem card;
  11. const GamePage({
  12. super.key,
  13. required this.card,
  14. });
  15. @override
  16. State<GamePage> createState() => _GamePageState();
  17. }
  18. class _GamePageState extends State<GamePage> with SingleTickerProviderStateMixin {
  19. late ButtonController _controller;
  20. Timer? _timer;
  21. int _count = 0;
  22. @override
  23. void initState() {
  24. super.initState();
  25. _controller = ButtonController(widget.card, vsync: this);
  26. }
  27. void _createTimer() {
  28. _timer?.cancel();
  29. _timer = Timer.periodic(const Duration(milliseconds: 250), (count) {
  30. if (mounted) {
  31. setState(() {
  32. _count = count.tick;
  33. });
  34. }
  35. });
  36. }
  37. @override
  38. Widget build(BuildContext context) {
  39. return Scaffold(
  40. body: Stack(
  41. children: [
  42. Positioned.fill(
  43. child: ColorFiltered(
  44. colorFilter: const ColorFilter.matrix(<double>[
  45. 0.299, 0.587, 0.114, 0, 0, //r
  46. 0.299, 0.587, 0.114, 0, 0, //g
  47. 0.299, 0.587, 0.114, 0, 0, //b
  48. 0, 0, 0, 0.1, 0, //a
  49. ]),
  50. child: Image.asset(
  51. 'assets/images/background.png',
  52. repeat: ImageRepeat.repeat,
  53. cacheWidth: 182,
  54. cacheHeight: 52,
  55. ),
  56. ),
  57. ),
  58. Positioned.fill(
  59. child: SafeArea(
  60. top: true,
  61. bottom: true,
  62. child: Column(
  63. children: [
  64. Expanded(
  65. child: Column(
  66. mainAxisSize: MainAxisSize.min,
  67. mainAxisAlignment: MainAxisAlignment.center,
  68. children: [
  69. Padding(
  70. padding: const EdgeInsets.symmetric(horizontal: 16),
  71. child: Align(
  72. alignment: Alignment.centerLeft,
  73. child: Container(
  74. padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
  75. decoration: BoxDecoration(
  76. borderRadius: BorderRadius.circular(40),
  77. color: Theme.of(context).colorScheme.primaryContainer,
  78. ),
  79. child: Row(
  80. mainAxisSize: MainAxisSize.min,
  81. children: [
  82. const Icon(Icons.timer),
  83. const SizedBox(width: 8),
  84. Text(
  85. '${Duration(milliseconds: _count * 250).inSeconds}秒',
  86. style: Theme.of(context).textTheme.titleLarge,
  87. ),
  88. const SizedBox(width: 8),
  89. ],
  90. ),
  91. ),
  92. ),
  93. ),
  94. const SizedBox(height: 16),
  95. Padding(
  96. padding: const EdgeInsets.symmetric(horizontal: 16),
  97. child: BattleBoard(
  98. card: ClipRRect(
  99. borderRadius: BorderRadius.circular(8),
  100. child: Container(
  101. width: double.infinity,
  102. height: double.infinity,
  103. color: Colors.grey,
  104. child: Image.asset(
  105. widget.card.assetPath,
  106. fit: BoxFit.cover,
  107. ),
  108. ),
  109. ),
  110. button: CustomPaint(
  111. painter: ButtonPainter(controller: _controller),
  112. child: const SizedBox.expand(),
  113. ),
  114. ),
  115. ),
  116. const SizedBox(height: 32),
  117. Padding(
  118. padding: const EdgeInsets.symmetric(horizontal: 16),
  119. child: ButtonBar(
  120. alignment: MainAxisAlignment.spaceAround,
  121. children: [
  122. FilledButton(
  123. onPressed: () {
  124. showCountDown(context).then((_) {
  125. _createTimer();
  126. _controller.startOrReset();
  127. });
  128. },
  129. child: const Text('开始'),
  130. ),
  131. FilledButton(
  132. onPressed: () {
  133. _controller.stop();
  134. _timer?.cancel();
  135. },
  136. child: const Text('停止'),
  137. ),
  138. ],
  139. ),
  140. ),
  141. ],
  142. ),
  143. ),
  144. ],
  145. ),
  146. ),
  147. ),
  148. Positioned(
  149. right: 16,
  150. top: MediaQuery.of(context).padding.top + 16,
  151. child: IconButton(
  152. icon: const Icon(Icons.settings),
  153. onPressed: () {
  154. Navigator.push(context, MaterialPageRoute(builder: (_) {
  155. return const SettingPage();
  156. }));
  157. },
  158. ),
  159. ),
  160. ],
  161. ),
  162. );
  163. }
  164. }