game_screen.dart 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. import 'package:flame/game.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter/services.dart';
  4. import 'package:vibration/vibration.dart';
  5. import '../game/zentap_game.dart';
  6. import '../utils/colors.dart';
  7. import '../utils/settings_manager.dart';
  8. import 'components/animated_background.dart';
  9. class GameScreen extends StatefulWidget {
  10. final bool isZenMode;
  11. const GameScreen({
  12. super.key,
  13. required this.isZenMode,
  14. });
  15. @override
  16. State<GameScreen> createState() => _GameScreenState();
  17. }
  18. class _GameScreenState extends State<GameScreen> {
  19. late ZenTapGame game;
  20. bool _isPaused = false;
  21. @override
  22. void initState() {
  23. super.initState();
  24. game = ZenTapGame();
  25. game.setZenMode(widget.isZenMode);
  26. // Hide system UI for immersive experience
  27. SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
  28. }
  29. @override
  30. void dispose() {
  31. // Restore system UI
  32. SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
  33. super.dispose();
  34. }
  35. @override
  36. Widget build(BuildContext context) {
  37. return Scaffold(
  38. backgroundColor: ZenColors.appBackground,
  39. body: AnimatedBackground(
  40. isZenMode: widget.isZenMode,
  41. child: Stack(
  42. children: [
  43. // Game Widget with tap detection
  44. GestureDetector(
  45. onTapDown: (details) {
  46. // Add haptic feedback on tap
  47. if (SettingsManager.isHapticsEnabled) {
  48. try {
  49. Vibration.vibrate(duration: 30);
  50. } catch (e) {
  51. // Vibration not supported on this platform
  52. }
  53. }
  54. // Convert screen position to game position
  55. final position = Vector2(
  56. details.localPosition.dx,
  57. details.localPosition.dy,
  58. );
  59. game.handleTap(position);
  60. },
  61. child: GameWidget<ZenTapGame>.controlled(
  62. gameFactory: () => game,
  63. ),
  64. ),
  65. // Top UI Overlay
  66. SafeArea(
  67. child: Padding(
  68. padding: const EdgeInsets.all(16.0),
  69. child: Row(
  70. children: [
  71. // Back Button
  72. IconButton(
  73. onPressed: _showExitDialog,
  74. icon: const Icon(
  75. Icons.arrow_back,
  76. color: ZenColors.primaryText,
  77. size: 28,
  78. ),
  79. style: IconButton.styleFrom(
  80. backgroundColor: ZenColors.black.withValues(alpha: 0.3),
  81. shape: const CircleBorder(),
  82. ),
  83. ),
  84. const Spacer(),
  85. // Mode Indicator
  86. Container(
  87. padding: const EdgeInsets.symmetric(
  88. horizontal: 16,
  89. vertical: 8,
  90. ),
  91. decoration: BoxDecoration(
  92. color: ZenColors.black.withValues(alpha: 0.3),
  93. borderRadius: BorderRadius.circular(20),
  94. ),
  95. child: Text(
  96. widget.isZenMode ? 'ZEN MODE' : 'PLAY MODE',
  97. style: TextStyle(
  98. color: ZenColors.primaryText,
  99. fontSize: 14,
  100. fontWeight: FontWeight.w600,
  101. letterSpacing: 1.0,
  102. ),
  103. ),
  104. ),
  105. const Spacer(),
  106. // Pause Button
  107. IconButton(
  108. onPressed: _togglePause,
  109. icon: Icon(
  110. _isPaused ? Icons.play_arrow : Icons.pause,
  111. color: ZenColors.primaryText,
  112. size: 28,
  113. ),
  114. style: IconButton.styleFrom(
  115. backgroundColor: ZenColors.black.withValues(alpha: 0.3),
  116. shape: const CircleBorder(),
  117. ),
  118. ),
  119. ],
  120. ),
  121. ),
  122. ),
  123. // Pause Overlay
  124. if (_isPaused) _buildPauseOverlay(),
  125. ],
  126. ),
  127. ),
  128. );
  129. }
  130. Widget _buildPauseOverlay() {
  131. return Container(
  132. color: ZenColors.black.withValues(alpha: 0.8),
  133. child: Center(
  134. child: Container(
  135. margin: const EdgeInsets.all(40),
  136. padding: const EdgeInsets.all(30),
  137. decoration: BoxDecoration(
  138. color: ZenColors.uiElements,
  139. borderRadius: BorderRadius.circular(20),
  140. ),
  141. child: Column(
  142. mainAxisSize: MainAxisSize.min,
  143. children: [
  144. const Text(
  145. 'Paused',
  146. style: TextStyle(
  147. color: ZenColors.primaryText,
  148. fontSize: 32,
  149. fontWeight: FontWeight.bold,
  150. ),
  151. ),
  152. const SizedBox(height: 20),
  153. Text(
  154. 'Take a moment to breathe',
  155. style: TextStyle(
  156. color: ZenColors.secondaryText,
  157. fontSize: 16,
  158. ),
  159. ),
  160. const SizedBox(height: 30),
  161. // Resume Button
  162. ElevatedButton(
  163. onPressed: _togglePause,
  164. style: ElevatedButton.styleFrom(
  165. backgroundColor: ZenColors.buttonBackground,
  166. foregroundColor: ZenColors.buttonText,
  167. padding: const EdgeInsets.symmetric(
  168. horizontal: 40,
  169. vertical: 15,
  170. ),
  171. shape: RoundedRectangleBorder(
  172. borderRadius: BorderRadius.circular(12),
  173. ),
  174. ),
  175. child: const Text(
  176. 'Resume',
  177. style: TextStyle(
  178. fontSize: 18,
  179. fontWeight: FontWeight.w600,
  180. ),
  181. ),
  182. ),
  183. ],
  184. ),
  185. ),
  186. ),
  187. );
  188. }
  189. void _togglePause() {
  190. if (SettingsManager.isHapticsEnabled) {
  191. try {
  192. Vibration.vibrate(duration: 50);
  193. } catch (e) {
  194. // Vibration not supported on this platform
  195. }
  196. }
  197. setState(() {
  198. _isPaused = !_isPaused;
  199. if (_isPaused) {
  200. game.pauseGame();
  201. } else {
  202. game.resumeGame();
  203. }
  204. });
  205. }
  206. void _showExitDialog() {
  207. if (SettingsManager.isHapticsEnabled) {
  208. try {
  209. Vibration.vibrate(duration: 50);
  210. } catch (e) {
  211. // Vibration not supported on this platform
  212. }
  213. }
  214. showDialog(
  215. context: context,
  216. builder: (BuildContext context) {
  217. return AlertDialog(
  218. backgroundColor: ZenColors.uiElements,
  219. title: const Text(
  220. 'Leave Game?',
  221. style: TextStyle(color: ZenColors.primaryText),
  222. ),
  223. content: Text(
  224. 'Are you sure you want to return to the main menu?',
  225. style: TextStyle(color: ZenColors.secondaryText),
  226. ),
  227. actions: [
  228. TextButton(
  229. onPressed: () => Navigator.of(context).pop(),
  230. child: Text(
  231. 'Cancel',
  232. style: TextStyle(color: ZenColors.links),
  233. ),
  234. ),
  235. ElevatedButton(
  236. onPressed: () {
  237. Navigator.of(context).pop(); // Close dialog
  238. Navigator.of(context).pop(); // Return to main menu
  239. },
  240. style: ElevatedButton.styleFrom(
  241. backgroundColor: ZenColors.red,
  242. foregroundColor: ZenColors.white,
  243. ),
  244. child: const Text('Leave'),
  245. ),
  246. ],
  247. );
  248. },
  249. );
  250. }
  251. }