-
BINassets/images/level_1_image.png
-
BINassets/images/level_2_image.png
-
BINassets/images/level_4_image.png
-
BINassets/images/level_screen_image.png
-
BINassets/images/splash_screen_image.png
-
BINassets/images/start.png
-
3assets/images/svg/check.svg
-
3assets/images/svg/lock.svg
-
3assets/images/svg/start.svg
-
3lib/main.dart
-
95lib/screens/level_list/screen/level_list_screen.dart
-
178lib/screens/level_list/widgets/level_widget.dart
-
140lib/screens/level_list/widgets/lock_level_widget.dart
-
143lib/screens/level_list/widgets/payed_level_widget.dart
-
54lib/screens/login_screen_name.dart
-
180lib/screens/menu_screen.dart
-
5lib/screens/photo/photo_screen_large.dart
-
152lib/screens/puzzle/top_bar.dart
-
220lib/screens/puzzle_screen.dart
-
489lib/screens/puzzle_solo_screen.dart
-
43lib/screens/splash/screen/splash_screen.dart
-
19lib/utils/extensions/context_extension.dart
-
4lib/utils/extensions/string_extensions.dart
-
308lib/widgets/animated_grid.dart
-
67lib/widgets/grid.dart
-
62lib/widgets/login_widgets/name_field.dart
-
72lib/widgets/login_widgets/start_game_widget.dart
-
39lib/widgets/login_widgets/start_game_widget/start_game_button.dart
-
2lib/widgets/menu_widgets/menu_widgets.dart
-
108lib/widgets/menu_widgets/multiplayer_button.dart
-
44lib/widgets/menu_widgets/solo_button.dart
-
53lib/widgets/photo_screen/pick_image_button.dart
-
28lib/widgets/puzzle_widgets/moves_text.dart
-
26lib/widgets/puzzle_widgets/player_text.dart
-
2lib/widgets/puzzle_widgets/puzzle_widgets.dart
-
73lib/widgets/puzzle_widgets/solo/timer_widget.dart
-
6lib/widgets/solo_screen/solo_screen_export.dart
-
42pubspec.lock
-
5pubspec.yaml
After Width: 70 | Height: 70 | Size: 10 KiB |
After Width: 70 | Height: 71 | Size: 11 KiB |
After Width: 70 | Height: 71 | Size: 13 KiB |
After Width: 214 | Height: 296 | Size: 54 KiB |
After Width: 266 | Height: 209 | Size: 45 KiB |
After Width: 63 | Height: 63 | Size: 1.8 KiB |
@ -0,0 +1,3 @@ |
|||
<svg id="Icon_-_Check" data-name="Icon - Check" xmlns="http://www.w3.org/2000/svg" width="7.807" height="5.577" viewBox="0 0 7.807 5.577"> |
|||
<path id="Vector_" data-name="Vector " d="M7.564.193a.744.744,0,0,1,.05,1.05L3.9,5.333a.744.744,0,0,1-.982.1L.311,3.579a.744.744,0,1,1,.864-1.21L3.24,3.844,6.514.243A.744.744,0,0,1,7.564.193Z" transform="translate(0 0)" fill="#5f34fa"/> |
|||
</svg> |
@ -0,0 +1,3 @@ |
|||
<svg xmlns="http://www.w3.org/2000/svg" width="6.643" height="8.636" viewBox="0 0 6.643 8.636"> |
|||
<path id="Icon_ionic-ios-lock" data-name="Icon ionic-ios-lock" d="M12.562,6.364h-.5V5.394a1.993,1.993,0,1,0-3.986-.027v1h-.5a.833.833,0,0,0-.83.83V11.18a.833.833,0,0,0,.83.83h4.982a.833.833,0,0,0,.83-.83V7.194A.833.833,0,0,0,12.562,6.364Zm-2.2,2.591v1.428a.3.3,0,0,1-.276.3.291.291,0,0,1-.305-.291V8.955a.664.664,0,1,1,.581,0Zm1.121-2.591H8.66v-1a1.412,1.412,0,0,1,2.823,0Z" transform="translate(-6.75 -3.374)" fill="#6536f2"/> |
|||
</svg> |
@ -0,0 +1,3 @@ |
|||
<svg id="icon-play" xmlns="http://www.w3.org/2000/svg" width="7.426" height="9.027" viewBox="0 0 7.426 9.027"> |
|||
<path id="Shape" d="M1.095,8.811A2,2,0,0,1,0,7.025V2A2,2,0,0,1,3.184.388L6.608,2.9h0a2,2,0,0,1,0,3.226L3.183,8.638a2,2,0,0,1-2.088.173Z" transform="translate(0 0)" fill="#ff9a00"/> |
|||
</svg> |
@ -0,0 +1,178 @@ |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:flutter_svg/flutter_svg.dart'; |
|||
import 'package:my_flutter_puzzle/screens/level_list/screen/level_list_screen.dart'; |
|||
import 'package:my_flutter_puzzle/utils/extensions/context_extension.dart'; |
|||
import 'package:my_flutter_puzzle/utils/extensions/string_extensions.dart'; |
|||
|
|||
class LevelWidget extends StatelessWidget { |
|||
final Level level; |
|||
|
|||
const LevelWidget({Key? key, required this.level}) : super(key: key); |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
return Container( |
|||
padding: const EdgeInsetsDirectional.only(top: 10, start: 8, end: 8, bottom: 10), |
|||
margin: const EdgeInsets.only(bottom: 16), |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.circular(16), |
|||
gradient: const LinearGradient( |
|||
colors: [ |
|||
Color(0xff5E34F5), |
|||
Color(0xff4425B1), |
|||
], |
|||
begin: Alignment.topCenter, |
|||
end: Alignment.bottomCenter, |
|||
), |
|||
border: Border.all( |
|||
color: const Color(0xff6135FD), |
|||
width: 1, |
|||
), |
|||
), |
|||
child: Row( |
|||
crossAxisAlignment: CrossAxisAlignment.end, |
|||
children: [ |
|||
Stack( |
|||
alignment: AlignmentDirectional.centerEnd, |
|||
children: [ |
|||
Container( |
|||
width: context.width * 70 / 820, |
|||
height: context.width * 70 / 820, |
|||
margin: const EdgeInsetsDirectional.only(end: 16), |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.circular(8), |
|||
image: DecorationImage( |
|||
image: AssetImage(level.image), |
|||
), |
|||
), |
|||
), |
|||
Container( |
|||
width: context.width * 28 / 820, |
|||
height: context.width * 28 / 820, |
|||
margin: const EdgeInsetsDirectional.only(end: 6), |
|||
decoration: BoxDecoration( |
|||
shape: BoxShape.circle, |
|||
color: Colors.red, |
|||
border: Border.all( |
|||
color: const Color(0xff6136FE), |
|||
), |
|||
gradient: const LinearGradient( |
|||
colors: [ |
|||
Color(0xff6135FC), |
|||
Color(0xff4925CE), |
|||
], |
|||
begin: Alignment.topCenter, |
|||
end: Alignment.bottomCenter, |
|||
), |
|||
), |
|||
child: Container( |
|||
padding: EdgeInsets.all(context.width * 5 / 820), |
|||
margin: EdgeInsets.all(context.width * 5 / 820), |
|||
decoration: const BoxDecoration( |
|||
color: Color(0xffF7B500), |
|||
shape: BoxShape.circle, |
|||
), |
|||
child: SvgPicture.asset('check'.svgPath), |
|||
), |
|||
), |
|||
], |
|||
), |
|||
Column( |
|||
crossAxisAlignment: CrossAxisAlignment.start, |
|||
children: [ |
|||
Row( |
|||
children: [ |
|||
Text( |
|||
'Level ${level.level}', |
|||
style: const TextStyle( |
|||
color: Colors.white, |
|||
fontSize: 20, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
), |
|||
const SizedBox(width: 12), |
|||
Text( |
|||
'${level.puzzleSize}*${level.puzzleSize} | 00:56', |
|||
style: const TextStyle( |
|||
color: Color(0xffBCACF4), |
|||
fontSize: 16, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
), |
|||
], |
|||
), |
|||
const SizedBox(height: 8), |
|||
const Text( |
|||
'Keyboard', |
|||
style: TextStyle( |
|||
color: Colors.white, |
|||
fontSize: 18, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
), |
|||
], |
|||
), |
|||
const Spacer(), |
|||
Container( |
|||
padding: const EdgeInsets.all(3), |
|||
decoration: BoxDecoration( |
|||
color: const Color(0xff5F358F), |
|||
borderRadius: BorderRadius.circular(36), |
|||
), |
|||
child: Container( |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.circular(31), |
|||
gradient: const LinearGradient( |
|||
colors: [ |
|||
Color(0xffFFC600), |
|||
Color(0xffFF5A00), |
|||
], |
|||
begin: Alignment.topCenter, |
|||
end: Alignment.bottomCenter, |
|||
), |
|||
), |
|||
child: Row( |
|||
mainAxisAlignment: MainAxisAlignment.center, |
|||
children: [ |
|||
const SizedBox(width: 6), |
|||
Container( |
|||
width: context.width * 26 / 540, |
|||
height: context.width * 26 / 540, |
|||
padding: const EdgeInsets.all(9), |
|||
margin: const EdgeInsets.symmetric(vertical: 3), |
|||
decoration: BoxDecoration( |
|||
border: Border.all( |
|||
color: Colors.white, |
|||
width: 1, |
|||
), |
|||
gradient: const LinearGradient( |
|||
colors: [ |
|||
Colors.white, |
|||
Color(0xffD5D5D5), |
|||
], |
|||
begin: Alignment.topCenter, |
|||
end: Alignment.bottomCenter, |
|||
), |
|||
shape: BoxShape.circle, |
|||
), |
|||
child: SvgPicture.asset('start'.svgPath), |
|||
), |
|||
const SizedBox(width: 8), |
|||
const Text( |
|||
'Start', |
|||
style: TextStyle( |
|||
color: Colors.white, |
|||
fontSize: 14, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
), |
|||
const SizedBox(width: 14), |
|||
], |
|||
), |
|||
), |
|||
), |
|||
], |
|||
), |
|||
); |
|||
} |
|||
} |
@ -0,0 +1,140 @@ |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:flutter_svg/flutter_svg.dart'; |
|||
import 'package:my_flutter_puzzle/screens/level_list/screen/level_list_screen.dart'; |
|||
import 'package:my_flutter_puzzle/utils/extensions/context_extension.dart'; |
|||
import 'package:my_flutter_puzzle/utils/extensions/string_extensions.dart'; |
|||
|
|||
class LockLevelWidget extends StatelessWidget { |
|||
final Level level; |
|||
|
|||
const LockLevelWidget({Key? key, required this.level}) : super(key: key); |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
return Container( |
|||
padding: const EdgeInsets.all(8), |
|||
margin: const EdgeInsets.only(bottom: 16), |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.circular(16), |
|||
gradient: LinearGradient( |
|||
colors: [ |
|||
const Color(0xff6236FF).withOpacity(0.5), |
|||
const Color(0xff311B80).withOpacity(0.5), |
|||
], |
|||
begin: Alignment.topCenter, |
|||
end: Alignment.bottomCenter, |
|||
), |
|||
border: Border.all( |
|||
color: const Color(0xff6135FD), |
|||
width: 1, |
|||
), |
|||
), |
|||
child: Row( |
|||
crossAxisAlignment: CrossAxisAlignment.end, |
|||
children: [ |
|||
Container( |
|||
width: context.width * 70 / 820, |
|||
height: context.width * 70 / 820, |
|||
margin: const EdgeInsetsDirectional.only(end: 16), |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.circular(8), |
|||
image: DecorationImage( |
|||
image: AssetImage(level.image), |
|||
opacity: 0.8, |
|||
), |
|||
), |
|||
), |
|||
Column( |
|||
crossAxisAlignment: CrossAxisAlignment.start, |
|||
children: [ |
|||
Row( |
|||
children: [ |
|||
Text( |
|||
'Level ${level.level}', |
|||
style: TextStyle( |
|||
color: Colors.white.withOpacity(0.5), |
|||
fontSize: 20, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
), |
|||
const SizedBox(width: 12), |
|||
Text( |
|||
'${level.puzzleSize}*${level.puzzleSize} | 00:56', |
|||
style: TextStyle( |
|||
color: const Color(0xffBCACF4).withOpacity(0.5), |
|||
fontSize: 16, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
), |
|||
], |
|||
), |
|||
const SizedBox(height: 8), |
|||
Text( |
|||
'Keyboard', |
|||
style: TextStyle( |
|||
color: Colors.white.withOpacity(0.5), |
|||
fontSize: 18, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
), |
|||
], |
|||
), |
|||
const Spacer(), |
|||
Column( |
|||
children: [ |
|||
Text( |
|||
'Solve lvl ${level.level - 1}', |
|||
style: const TextStyle( |
|||
color: Colors.white, |
|||
fontSize: 12, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
), |
|||
const SizedBox(height: 8), |
|||
Container( |
|||
padding: const EdgeInsets.all(3), |
|||
decoration: BoxDecoration( |
|||
color: const Color(0xff5F358F).withOpacity(0.8), |
|||
borderRadius: BorderRadius.circular(36), |
|||
), |
|||
child: Container( |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.circular(31), |
|||
color: const Color(0xff5D32DE), |
|||
), |
|||
child: Row( |
|||
mainAxisAlignment: MainAxisAlignment.center, |
|||
children: [ |
|||
const SizedBox(width: 6), |
|||
Container( |
|||
width: context.width * 26 / 540, |
|||
height: context.width * 26 / 540, |
|||
padding: const EdgeInsets.all(10), |
|||
margin: const EdgeInsets.symmetric(vertical: 3), |
|||
decoration: const BoxDecoration( |
|||
color: Color(0xffAF99EF), |
|||
shape: BoxShape.circle, |
|||
), |
|||
child: SvgPicture.asset('lock'.svgPath), |
|||
), |
|||
const SizedBox(width: 8), |
|||
Text( |
|||
'Lock', |
|||
style: TextStyle( |
|||
color: Colors.white.withOpacity(0.8), |
|||
fontSize: 14, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
), |
|||
const SizedBox(width: 14), |
|||
], |
|||
), |
|||
), |
|||
), |
|||
], |
|||
), |
|||
], |
|||
), |
|||
); |
|||
} |
|||
} |
@ -0,0 +1,143 @@ |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:flutter_svg/flutter_svg.dart'; |
|||
import 'package:my_flutter_puzzle/screens/level_list/screen/level_list_screen.dart'; |
|||
import 'package:my_flutter_puzzle/utils/extensions/context_extension.dart'; |
|||
import 'package:my_flutter_puzzle/utils/extensions/string_extensions.dart'; |
|||
|
|||
class PayedLevelWidget extends StatelessWidget { |
|||
final Level level; |
|||
|
|||
const PayedLevelWidget({ |
|||
Key? key, |
|||
required this.level, |
|||
}) : super(key: key); |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
return Container( |
|||
padding: const EdgeInsets.all(8), |
|||
margin: const EdgeInsets.only(bottom: 16), |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.circular(16), |
|||
gradient: LinearGradient( |
|||
colors: [ |
|||
const Color(0xff6236FF).withOpacity(0.5), |
|||
const Color(0xff311B80).withOpacity(0.5), |
|||
], |
|||
begin: Alignment.topCenter, |
|||
end: Alignment.bottomCenter, |
|||
), |
|||
border: Border.all( |
|||
color: const Color(0xff6135FD), |
|||
width: 1, |
|||
), |
|||
), |
|||
child: Row( |
|||
crossAxisAlignment: CrossAxisAlignment.end, |
|||
children: [ |
|||
Container( |
|||
width: context.width * 70 / 820, |
|||
height: context.width * 70 / 820, |
|||
margin: const EdgeInsetsDirectional.only(end: 16), |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.circular(8), |
|||
image: DecorationImage( |
|||
image: AssetImage(level.image), |
|||
opacity: 0.8, |
|||
), |
|||
), |
|||
), |
|||
Column( |
|||
crossAxisAlignment: CrossAxisAlignment.start, |
|||
children: [ |
|||
Row( |
|||
children: [ |
|||
Text( |
|||
'Level ${level.level}', |
|||
style: TextStyle( |
|||
color: Colors.white.withOpacity(0.5), |
|||
fontSize: 20, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
), |
|||
const SizedBox(width: 12), |
|||
Text( |
|||
'${level.puzzleSize}*${level.puzzleSize} | 00:56', |
|||
style: TextStyle( |
|||
color: const Color(0xffBCACF4).withOpacity(0.5), |
|||
fontSize: 16, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
), |
|||
], |
|||
), |
|||
const SizedBox(height: 8), |
|||
Text( |
|||
'Keyboard', |
|||
style: TextStyle( |
|||
color: Colors.white.withOpacity(0.5), |
|||
fontSize: 18, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
), |
|||
], |
|||
), |
|||
const Spacer(), |
|||
Column( |
|||
children: [ |
|||
const Text( |
|||
'\$ 2', |
|||
style: TextStyle( |
|||
color: Colors.white, |
|||
fontSize: 14, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
), |
|||
const SizedBox(height: 8), |
|||
Container( |
|||
padding: const EdgeInsets.all(3), |
|||
decoration: BoxDecoration( |
|||
color: const Color(0xff5F358F).withOpacity(0.8), |
|||
borderRadius: BorderRadius.circular(36), |
|||
), |
|||
child: Container( |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.circular(31), |
|||
color: const Color(0xff7853FF), |
|||
), |
|||
child: Row( |
|||
mainAxisAlignment: MainAxisAlignment.center, |
|||
children: [ |
|||
const SizedBox(width: 6), |
|||
Container( |
|||
width: context.width * 26 / 540, |
|||
height: context.width * 26 / 540, |
|||
padding: const EdgeInsets.all(10), |
|||
margin: const EdgeInsets.symmetric(vertical: 3), |
|||
decoration: const BoxDecoration( |
|||
color: Colors.white , |
|||
shape: BoxShape.circle, |
|||
), |
|||
child: SvgPicture.asset('lock'.svgPath), |
|||
), |
|||
const SizedBox(width: 8), |
|||
Text( |
|||
'Buy', |
|||
style: TextStyle( |
|||
color: Colors.white.withOpacity(0.8), |
|||
fontSize: 14, |
|||
fontWeight: FontWeight.bold, |
|||
), |
|||
), |
|||
const SizedBox(width: 14), |
|||
], |
|||
), |
|||
), |
|||
), |
|||
], |
|||
), |
|||
], |
|||
), |
|||
); |
|||
} |
|||
} |
@ -1,54 +0,0 @@ |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:my_flutter_puzzle/widgets/login_widgets/name_field.dart'; |
|||
|
|||
class LoginScreenName extends StatefulWidget { |
|||
const LoginScreenName({Key? key}) : super(key: key); |
|||
|
|||
@override |
|||
State<LoginScreenName> createState() => _LoginScreenNameState(); |
|||
} |
|||
|
|||
class _LoginScreenNameState extends State<LoginScreenName> { |
|||
late final TextEditingController _nameTextController; |
|||
late final FocusNode _nameFocusNode; |
|||
|
|||
String _nameString = ''; |
|||
|
|||
@override |
|||
void initState() { |
|||
super.initState(); |
|||
_nameTextController = TextEditingController(); |
|||
_nameFocusNode = FocusNode(); |
|||
} |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
var screenSize = MediaQuery.of(context).size; |
|||
return GestureDetector( |
|||
onTap: () => _nameFocusNode.unfocus(), |
|||
child: Scaffold( |
|||
backgroundColor: Colors.white, |
|||
body: Center( |
|||
child: SizedBox( |
|||
width: screenSize.width * 0.5, |
|||
child: Column( |
|||
mainAxisAlignment: MainAxisAlignment.center, |
|||
children: [ |
|||
NameField( |
|||
focusNode: _nameFocusNode, |
|||
onChange: (value) => setState( |
|||
() => _nameString = value, |
|||
), |
|||
), |
|||
const SizedBox(height: 24), |
|||
// StartGameWidget( |
|||
// nameString: _nameString, |
|||
// ), |
|||
], |
|||
), |
|||
), |
|||
), |
|||
), |
|||
); |
|||
} |
|||
} |
@ -1,180 +0,0 @@ |
|||
// import 'package:cloud_firestore/cloud_firestore.dart'; |
|||
// import 'package:flutter/material.dart'; |
|||
// import 'package:flutter_riverpod/flutter_riverpod.dart'; |
|||
// import 'package:my_flutter_puzzle/application/states/player_matching_state.dart'; |
|||
// import 'package:my_flutter_puzzle/models/user_info.dart'; |
|||
// import 'package:my_flutter_puzzle/providers.dart'; |
|||
// import 'package:my_flutter_puzzle/res/palette.dart'; |
|||
// import 'package:my_flutter_puzzle/utils/database_client.dart'; |
|||
// import 'package:my_flutter_puzzle/screens/puzzle_screen.dart'; |
|||
// import 'package:my_flutter_puzzle/widgets/menu_widgets/menu_widgets.dart'; |
|||
|
|||
// class MenuScreen extends ConsumerStatefulWidget { |
|||
// const MenuScreen({ |
|||
// Key? key, |
|||
// required this.userData, |
|||
// }) : super(key: key); |
|||
|
|||
// final UserData userData; |
|||
|
|||
// @override |
|||
// ConsumerState<ConsumerStatefulWidget> createState() => _MenuScreenState(); |
|||
// } |
|||
|
|||
// class _MenuScreenState extends ConsumerState<MenuScreen> { |
|||
// final numberList = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; |
|||
// late final UserData userData; |
|||
|
|||
// @override |
|||
// void initState() { |
|||
// super.initState(); |
|||
// userData = widget.userData; |
|||
// numberList.shuffle(); |
|||
// } |
|||
|
|||
// @override |
|||
// Widget build(BuildContext context) { |
|||
// var screenSize = MediaQuery.of(context).size; |
|||
|
|||
// ref.listen(playerMatchingNotifierProvider, (previous, next) { |
|||
// if (next is PlayerMatched) { |
|||
// Navigator.of(context).push( |
|||
// MaterialPageRoute( |
|||
// builder: (context) => PuzzleScreen( |
|||
// initialList: numberList, |
|||
// id: next.id, |
|||
// myInfo: userData, |
|||
// ), |
|||
// ), |
|||
// ); |
|||
// } |
|||
// }); |
|||
|
|||
// return Scaffold( |
|||
// backgroundColor: Colors.white, |
|||
// body: Center( |
|||
// child: SizedBox( |
|||
// width: screenSize.width * 0.5, |
|||
// child: Consumer( |
|||
// builder: (context, ref, child) { |
|||
// final state = ref.watch(playerMatchingNotifierProvider); |
|||
|
|||
// return state.when( |
|||
// () => Column( |
|||
// mainAxisAlignment: MainAxisAlignment.center, |
|||
// children: [ |
|||
// const Text( |
|||
// 'Game Mode', |
|||
// style: TextStyle( |
|||
// fontSize: 30, |
|||
// // fontWeight: FontWeight.bold, |
|||
// color: Palette.crimson, |
|||
// ), |
|||
// ), |
|||
// const SizedBox(height: 24), |
|||
// MultiplayerButton( |
|||
// myInfo: userData, |
|||
// list: numberList, |
|||
// ), |
|||
// const SizedBox(height: 16), |
|||
// const SoloButton(), |
|||
// const SizedBox(height: 30), |
|||
// ], |
|||
// ), |
|||
// processing: () => Row( |
|||
// mainAxisAlignment: MainAxisAlignment.center, |
|||
// children: const [ |
|||
// CircularProgressIndicator( |
|||
// valueColor: |
|||
// AlwaysStoppedAnimation<Color>(Palette.violet), |
|||
// ), |
|||
// SizedBox(width: 16), |
|||
// Text( |
|||
// 'Finding player ...', |
|||
// style: TextStyle( |
|||
// fontSize: 24, |
|||
// ), |
|||
// ), |
|||
// ], |
|||
// ), |
|||
// isMatched: (id) => Row( |
|||
// mainAxisAlignment: MainAxisAlignment.center, |
|||
// children: const [ |
|||
// Icon( |
|||
// Icons.check_circle, |
|||
// color: Palette.violet, |
|||
// size: 50, |
|||
// ), |
|||
// SizedBox(width: 16), |
|||
// Text( |
|||
// 'Found player', |
|||
// style: TextStyle( |
|||
// fontSize: 24, |
|||
// ), |
|||
// ), |
|||
// ], |
|||
// ), |
|||
// isQueued: () => PlayerQueuedWidget( |
|||
// myInfo: userData, |
|||
// ), |
|||
// error: (message) => Text( |
|||
// message.toString(), |
|||
// style: const TextStyle( |
|||
// fontSize: 24, |
|||
// ), |
|||
// ), |
|||
// ); |
|||
// }, |
|||
// ), |
|||
// ), |
|||
// )); |
|||
// } |
|||
// } |
|||
|
|||
// class PlayerQueuedWidget extends ConsumerWidget { |
|||
// PlayerQueuedWidget({ |
|||
// Key? key, |
|||
// required this.myInfo, |
|||
// }) : super(key: key); |
|||
|
|||
// final UserData myInfo; |
|||
|
|||
// final _databaseClient = DatabaseClient(); |
|||
|
|||
// @override |
|||
// Widget build(BuildContext context, WidgetRef ref) { |
|||
// return StreamBuilder<DocumentSnapshot>( |
|||
// stream: _databaseClient.isMatched(myInfo: myInfo), |
|||
// builder: (context, snapshot) { |
|||
// if (snapshot.hasData && snapshot.data!.data() != null) { |
|||
// final queuedUserData = |
|||
// snapshot.data!.data() as Map<String, dynamic>; |
|||
// bool isMatched = queuedUserData['ismatched']; |
|||
|
|||
// if (isMatched) { |
|||
// WidgetsBinding.instance?.addPostFrameCallback((_) { |
|||
// ref |
|||
// .read(playerMatchingNotifierProvider.notifier) |
|||
// .foundUser(myInfo: myInfo); |
|||
// }); |
|||
// } |
|||
// } |
|||
|
|||
// return Row( |
|||
// mainAxisAlignment: MainAxisAlignment.center, |
|||
// children: const [ |
|||
// CircularProgressIndicator( |
|||
// valueColor: AlwaysStoppedAnimation<Color>(Palette.violet), |
|||
// ), |
|||
// SizedBox(width: 16), |
|||
// Text( |
|||
// 'Your are in queue ...', |
|||
// style: TextStyle( |
|||
// fontSize: 24, |
|||
// ), |
|||
// ), |
|||
// ], |
|||
// ); |
|||
// }); |
|||
// } |
|||
// } |
@ -1,152 +0,0 @@ |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:flutter_riverpod/flutter_riverpod.dart'; |
|||
|
|||
class TopBar extends ConsumerWidget { |
|||
const TopBar({ |
|||
required Color color, |
|||
required int puzzleSize, |
|||
this.padding = const EdgeInsets.fromLTRB(24.0, 16.0, 24.0, 16.0), |
|||
this.tileGap = 16, |
|||
this.isCentered = false, |
|||
Key? key, |
|||
}) : _color = color, |
|||
_puzzleSize = puzzleSize, |
|||
super(key: key); |
|||
|
|||
final Color _color; |
|||
final int _puzzleSize; |
|||
final EdgeInsets padding; |
|||
final double tileGap; |
|||
final bool isCentered; |
|||
|
|||
@override |
|||
Widget build(BuildContext context, WidgetRef ref) { |
|||
return Container( |
|||
color: _color, |
|||
child: Padding( |
|||
padding: padding, |
|||
child: Row( |
|||
mainAxisAlignment: MainAxisAlignment.center, |
|||
children: [ |
|||
isCentered ? const SizedBox() : const Spacer(), |
|||
// TextButton( |
|||
// style: _puzzleType == 'Normal' |
|||
// ? ButtonStyle( |
|||
// foregroundColor: MaterialStateProperty.resolveWith<Color>( |
|||
// (Set<MaterialState> states) { |
|||
// return Palette.blue; |
|||
// }, |
|||
// ), |
|||
// ) |
|||
// : null, |
|||
// onPressed: _puzzleType == 'Normal' |
|||
// ? null |
|||
// : () { |
|||
// ref.read(puzzleTypeNotifierProvider.notifier).changeToNormal(); |
|||
// }, |
|||
// child: Padding( |
|||
// padding: const EdgeInsets.all(8.0), |
|||
// child: Row( |
|||
// children: [ |
|||
// Opacity( |
|||
// opacity: _puzzleType == 'Normal' ? 1 : 0.5, |
|||
// child: const FaIcon(FontAwesomeIcons.rocket), |
|||
// ), |
|||
// const SizedBox(width: 8), |
|||
// Text( |
|||
// 'Normal', |
|||
// style: TextStyle( |
|||
// fontSize: 16, |
|||
// color: Colors.white.withOpacity(_puzzleType == 'Normal' ? 1 : 0.5), |
|||
// ), |
|||
// ), |
|||
// ], |
|||
// ), |
|||
// ), |
|||
// ), |
|||
// SizedBox(width: tileGap), |
|||
// TextButton( |
|||
// style: _puzzleType == 'Photo' |
|||
// ? ButtonStyle( |
|||
// foregroundColor: MaterialStateProperty.resolveWith<Color>( |
|||
// (Set<MaterialState> states) { |
|||
// return Theme.of(context).colorScheme.primary; |
|||
// }, |
|||
// ), |
|||
// ) |
|||
// : null, |
|||
// onPressed: _puzzleType == 'Photo' |
|||
// ? null |
|||
// : () { |
|||
// final state = ref.read(imageSplitterNotifierProvider); |
|||
// if (state is! ImageSplitterComplete) { |
|||
// ref.read(imageSplitterNotifierProvider.notifier).getInitialImages(puzzleSize: _puzzleSize); |
|||
// } |
|||
// |
|||
// ref.read(puzzleTypeNotifierProvider.notifier).changeToPhoto(); |
|||
// }, |
|||
// child: Padding( |
|||
// padding: const EdgeInsets.all(8.0), |
|||
// child: Row( |
|||
// children: [ |
|||
// Opacity( |
|||
// opacity: _puzzleType == 'Photo' ? 1 : 0.5, |
|||
// child: const FaIcon(FontAwesomeIcons.image), |
|||
// ), |
|||
// const SizedBox(width: 8), |
|||
// Text( |
|||
// 'Photo', |
|||
// style: TextStyle( |
|||
// fontSize: 16, |
|||
// color: Colors.white.withOpacity(_puzzleType == 'Photo' ? 1 : 0.5), |
|||
// ), |
|||
// ), |
|||
// ], |
|||
// ), |
|||
// ), |
|||
// ), |
|||
// SizedBox(width: tileGap), |
|||
// TextButton( |
|||
// style: _puzzleType == 'Multiplayer' |
|||
// ? ButtonStyle( |
|||
// foregroundColor: MaterialStateProperty.resolveWith<Color>( |
|||
// (Set<MaterialState> states) { |
|||
// return Palette.blue; |
|||
// }, |
|||
// ), |
|||
// ) |
|||
// : null, |
|||
// onPressed: _puzzleType == 'Multiplayer' |
|||
// ? null |
|||
// : () { |
|||
// // ref.read(puzzleTypeNotifierProvider.notifier).dispose(); |
|||
// |
|||
// ref.read(puzzleTypeNotifierProvider.notifier).changeToMultiplayer(); |
|||
// ref.read(emailAuthNotificationProvider.notifier).checkForSignedUser(); |
|||
// }, |
|||
// child: Padding( |
|||
// padding: const EdgeInsets.all(8.0), |
|||
// child: Row( |
|||
// children: [ |
|||
// Opacity( |
|||
// opacity: _puzzleType == 'Multiplayer' ? 1 : 0.5, |
|||
// child: const FaIcon(FontAwesomeIcons.gamepad), |
|||
// ), |
|||
// const SizedBox(width: 8), |
|||
// Text( |
|||
// 'Multiplayer', |
|||
// style: TextStyle( |
|||
// fontSize: 16, |
|||
// color: Colors.white.withOpacity(_puzzleType == 'Multiplayer' ? 1 : 0.5), |
|||
// ), |
|||
// ), |
|||
// ], |
|||
// ), |
|||
// ), |
|||
// ), |
|||
], |
|||
), |
|||
), |
|||
); |
|||
} |
|||
} |
@ -1,220 +0,0 @@ |
|||
import 'dart:developer'; |
|||
|
|||
import 'package:flutter/material.dart'; |
|||
import 'package:my_flutter_puzzle/models/user_info.dart'; |
|||
import 'package:my_flutter_puzzle/widgets/puzzle_widgets/puzzle_widgets.dart'; |
|||
|
|||
class PuzzleScreen extends StatefulWidget { |
|||
const PuzzleScreen({ |
|||
Key? key, |
|||
required this.initialList, |
|||
required this.id, |
|||
required this.myInfo, |
|||
}) : super(key: key); |
|||
|
|||
final List<int> initialList; |
|||
final String id; |
|||
final UserData myInfo; |
|||
|
|||
@override |
|||
_PuzzleScreenState createState() => _PuzzleScreenState(); |
|||
} |
|||
|
|||
class _PuzzleScreenState extends State<PuzzleScreen> { |
|||
late final List<int> myList; |
|||
late final List<int> opponentList; |
|||
int _moves = 0; |
|||
|
|||
onClick(index) { |
|||
log('-----------------------'); |
|||
log('Tapped index: $index'); |
|||
|
|||
int emptyTilePosIndex = myList.indexOf(0); |
|||
int emptyTilePosRow = emptyTilePosIndex ~/ 4; |
|||
int emptyTilePosCol = emptyTilePosIndex % 4; |
|||
|
|||
int currentTileRow = index ~/ 4; |
|||
int currentTileCol = index % 4; |
|||
|
|||
//current element moves up |
|||
|
|||
if ((currentTileRow - 1 == emptyTilePosRow) && (currentTileCol == emptyTilePosCol)) { |
|||
setState(() { |
|||
myList[emptyTilePosIndex] = myList[index]; |
|||
myList[index] = 0; |
|||
_moves++; |
|||
}); |
|||
} |
|||
|
|||
//current element moves down |
|||
|
|||
else if ((currentTileRow + 1 == emptyTilePosRow) && (currentTileCol == emptyTilePosCol)) { |
|||
setState(() { |
|||
myList[emptyTilePosIndex] = myList[index]; |
|||
myList[index] = 0; |
|||
_moves++; |
|||
}); |
|||
} |
|||
|
|||
//current element moves left |
|||
|
|||
else if ((currentTileRow == emptyTilePosRow) && (currentTileCol + 1 == emptyTilePosCol)) { |
|||
setState(() { |
|||
myList[emptyTilePosIndex] = myList[index]; |
|||
myList[index] = 0; |
|||
_moves++; |
|||
}); |
|||
} |
|||
|
|||
//current element moves right |
|||
|
|||
else if ((currentTileRow == emptyTilePosRow) && (currentTileCol - 1 == emptyTilePosCol)) { |
|||
setState(() { |
|||
myList[emptyTilePosIndex] = myList[index]; |
|||
myList[index] = 0; |
|||
_moves++; |
|||
}); |
|||
} else { |
|||
if (currentTileCol == emptyTilePosCol) { |
|||
int low; |
|||
int high; |
|||
|
|||
// multiple elements move up |
|||
|
|||
if (emptyTilePosRow < currentTileRow) { |
|||
low = emptyTilePosRow; |
|||
high = currentTileRow; |
|||
|
|||
int i = low; |
|||
while (i < high) { |
|||
setState(() { |
|||
myList[(i * 4) + emptyTilePosCol] = myList[(((i + 1) * 4) + emptyTilePosCol)]; |
|||
}); |
|||
|
|||
i += 1; |
|||
} |
|||
setState(() { |
|||
myList[(high * 4) + emptyTilePosCol] = 0; |
|||
_moves++; |
|||
}); |
|||
} |
|||
|
|||
//multiple elements move down |
|||
|
|||
else { |
|||
low = emptyTilePosRow; |
|||
high = currentTileRow; |
|||
|
|||
int i = low; |
|||
while (i > high) { |
|||
setState(() { |
|||
myList[(i * 4) + emptyTilePosCol] = myList[(((i - 1) * 4) + emptyTilePosCol)]; |
|||
}); |
|||
|
|||
i -= 1; |
|||
} |
|||
setState(() { |
|||
myList[(high * 4) + emptyTilePosCol] = 0; |
|||
_moves++; |
|||
}); |
|||
} |
|||
} |
|||
|
|||
// multiple elements move left |
|||
|
|||
// multiple elements move right |
|||
|
|||
if (currentTileRow == emptyTilePosRow) { |
|||
int low; |
|||
int high; |
|||
|
|||
// multiple elements move left |
|||
|
|||
if (emptyTilePosCol < currentTileCol) { |
|||
low = emptyTilePosCol; |
|||
high = currentTileCol; |
|||
|
|||
int i = low; |
|||
while (i < high) { |
|||
setState(() { |
|||
myList[(emptyTilePosRow * 4) + i] = myList[(emptyTilePosRow * 4) + (i + 1)]; |
|||
}); |
|||
|
|||
i += 1; |
|||
} |
|||
setState(() { |
|||
myList[high + (emptyTilePosRow * 4)] = 0; |
|||
_moves++; |
|||
}); |
|||
} |
|||
|
|||
//multiple elements move right |
|||
|
|||
else { |
|||
low = emptyTilePosCol; |
|||
high = currentTileCol; |
|||
|
|||
int i = low; |
|||
while (i > high) { |
|||
setState(() { |
|||
myList[(i + (emptyTilePosRow * 4))] = myList[(i - 1) + (emptyTilePosRow * 4)]; |
|||
}); |
|||
|
|||
i -= 1; |
|||
} |
|||
setState(() { |
|||
myList[high + (emptyTilePosRow * 4)] = 0; |
|||
_moves++; |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// _databaseClient.updateGameState( |
|||
// id: widget.id, |
|||
// mydata: widget.myInfo, |
|||
// numberList: myList, |
|||
// moves: _moves, |
|||
// ); |
|||
|
|||
log('List: $myList'); |
|||
log('-----------------------'); |
|||
} |
|||
|
|||
@override |
|||
void initState() { |
|||
super.initState(); |
|||
myList = widget.initialList; |
|||
opponentList = widget.initialList; |
|||
} |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
return Scaffold( |
|||
backgroundColor: Colors.white, |
|||
body: Row( |
|||
mainAxisAlignment: MainAxisAlignment.spaceEvenly, |
|||
children: [ |
|||
// PLAYER 1 puzzle --> my (own) |
|||
Column( |
|||
children: [ |
|||
const PlayerText( |
|||
displayName: 'PLAYER 1', |
|||
), |
|||
// TODO: Change font size |
|||
MovesText( |
|||
moves: _moves, |
|||
fontSize: 60, |
|||
), |
|||
], |
|||
), |
|||
Container( |
|||
height: MediaQuery.of(context).size.height * 0.6, |
|||
width: 2, |
|||
color: Colors.black, |
|||
), |
|||
], |
|||
), |
|||
); |
|||
} |
|||
} |
@ -1,489 +0,0 @@ |
|||
import 'dart:developer'; |
|||
|
|||
import 'package:flutter/foundation.dart'; |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:my_flutter_puzzle/res/palette.dart'; |
|||
import 'package:my_flutter_puzzle/utils/puzzle_solver.dart'; |
|||
import 'package:my_flutter_puzzle/widgets/puzzle_widgets/puzzle_widgets.dart'; |
|||
|
|||
class PuzzleSoloScreen extends StatefulWidget { |
|||
const PuzzleSoloScreen({ |
|||
Key? key, |
|||
}) : super(key: key); |
|||
|
|||
@override |
|||
_PuzzleSoloScreenState createState() => _PuzzleSoloScreenState(); |
|||
} |
|||
|
|||
class _PuzzleSoloScreenState extends State<PuzzleSoloScreen> { |
|||
late final PuzzleSolverClient _solverClient; |
|||
|
|||
List<List<int>>? _board2D; |
|||
List<int>? myList; |
|||
int _moves = 0; |
|||
final _puzzleSize = 3; |
|||
final int _animationSpeedInMilliseconds = 300; |
|||
bool _isComputing = false; |
|||
bool _isAutoSolving = false; |
|||
bool _isSolved = false; |
|||
|
|||
Map<int, FractionalOffset>? _offsetMap; |
|||
List<int> _solvedList = []; |
|||
|
|||
@override |
|||
void initState() { |
|||
super.initState(); |
|||
_solverClient = PuzzleSolverClient(size: _puzzleSize); |
|||
initBoard(); |
|||
generateSolvedList(); |
|||
} |
|||
|
|||
generateSolvedList() { |
|||
for (int i = 1; i < _puzzleSize * _puzzleSize; i++) { |
|||
_solvedList.add(i); |
|||
} |
|||
_solvedList.add(0); |
|||
} |
|||
|
|||
scrambleBoard() { |
|||
final generated2DBoard = _solverClient.createRandomBoard(); |
|||
final generated1DBoard = _solverClient.convertTo1D(generated2DBoard); |
|||
updateOffset(generated1DBoard); |
|||
setState(() { |
|||
_board2D = generated2DBoard; |
|||
myList = generated1DBoard; |
|||
_moves = 0; |
|||
_isSolved = false; |
|||
}); |
|||
} |
|||
|
|||
initBoard() { |
|||
final generated2DBoard = _solverClient.createRandomBoard(); |
|||
final generated1DBoard = _solverClient.convertTo1D(generated2DBoard); |
|||
|
|||
createOffset(generated1DBoard); |
|||
setState(() { |
|||
_board2D = generated2DBoard; |
|||
myList = generated1DBoard; |
|||
|
|||
_moves = 0; |
|||
}); |
|||
} |
|||
|
|||
startAutoSolver() async { |
|||
if (_board2D != null) { |
|||
setState(() { |
|||
_isComputing = true; |
|||
}); |
|||
|
|||
List<List<int>>? boardStates = await compute(_solverClient.runner, _solverClient.convertTo2D(myList!)); |
|||
|
|||
setState(() { |
|||
_isComputing = false; |
|||
_isAutoSolving = true; |
|||
}); |
|||
|
|||
if (boardStates != null) { |
|||
for (var board in boardStates) { |
|||
await Future.delayed(Duration( |
|||
milliseconds: _animationSpeedInMilliseconds, |
|||
)); |
|||
setState(() { |
|||
myList = board; |
|||
_moves++; |
|||
}); |
|||
updateOffset(myList!); |
|||
} |
|||
} |
|||
} |
|||
setState(() { |
|||
_isAutoSolving = false; |
|||
_isSolved = true; |
|||
}); |
|||
showCompleteDialogBox(context); |
|||
} |
|||
|
|||
isSolved(List<int> currentBoard) { |
|||
if (listEquals(currentBoard, _solvedList)) { |
|||
setState(() { |
|||
_isSolved = true; |
|||
}); |
|||
return true; |
|||
} |
|||
setState(() { |
|||
_isSolved = false; |
|||
}); |
|||
|
|||
return false; |
|||
} |
|||
|
|||
onClick(index) { |
|||
log('-----------------------'); |
|||
log('Tapped index: $index'); |
|||
|
|||
if (myList != null) { |
|||
int emptyTilePosIndex = myList!.indexOf(0); |
|||
int emptyTilePosRow = emptyTilePosIndex ~/ _puzzleSize; |
|||
int emptyTilePosCol = emptyTilePosIndex % _puzzleSize; |
|||
|
|||
int currentTileRow = index ~/ _puzzleSize; |
|||
int currentTileCol = index % _puzzleSize; |
|||
|
|||
//current element moves up |
|||
if ((currentTileRow - 1 == emptyTilePosRow) && (currentTileCol == emptyTilePosCol)) { |
|||
myList![emptyTilePosIndex] = myList![index]; |
|||
myList![index] = 0; |
|||
_moves++; |
|||
} |
|||
|
|||
//current element moves down |
|||
else if ((currentTileRow + 1 == emptyTilePosRow) && (currentTileCol == emptyTilePosCol)) { |
|||
myList![emptyTilePosIndex] = myList![index]; |
|||
myList![index] = 0; |
|||
_moves++; |
|||
} |
|||
|
|||
//current element moves left |
|||
else if ((currentTileRow == emptyTilePosRow) && (currentTileCol + 1 == emptyTilePosCol)) { |
|||
myList![emptyTilePosIndex] = myList![index]; |
|||
myList![index] = 0; |
|||
_moves++; |
|||
} |
|||
|
|||
//current element moves right |
|||
else if ((currentTileRow == emptyTilePosRow) && (currentTileCol - 1 == emptyTilePosCol)) { |
|||
myList![emptyTilePosIndex] = myList![index]; |
|||
myList![index] = 0; |
|||
_moves++; |
|||
} else { |
|||
if (currentTileCol == emptyTilePosCol) { |
|||
int low; |
|||
int high; |
|||
|
|||
// multiple elements move up |
|||
if (emptyTilePosRow < currentTileRow) { |
|||
low = emptyTilePosRow; |
|||
high = currentTileRow; |
|||
|
|||
int i = low; |
|||
while (i < high) { |
|||
myList![(i * _puzzleSize) + emptyTilePosCol] = myList![(((i + 1) * _puzzleSize) + emptyTilePosCol)]; |
|||
|
|||
i += 1; |
|||
} |
|||
|
|||
myList![(high * _puzzleSize) + emptyTilePosCol] = 0; |
|||
_moves++; |
|||
} |
|||
|
|||
//multiple elements move down |
|||
else { |
|||
low = emptyTilePosRow; |
|||
high = currentTileRow; |
|||
|
|||
int i = low; |
|||
while (i > high) { |
|||
myList![(i * _puzzleSize) + emptyTilePosCol] = myList![(((i - 1) * _puzzleSize) + emptyTilePosCol)]; |
|||
|
|||
i -= 1; |
|||
} |
|||
|
|||
myList![(high * _puzzleSize) + emptyTilePosCol] = 0; |
|||
_moves++; |
|||
} |
|||
} |
|||
|
|||
// multiple elements move left or right |
|||
if (currentTileRow == emptyTilePosRow) { |
|||
int low; |
|||
int high; |
|||
|
|||
// multiple elements move left |
|||
if (emptyTilePosCol < currentTileCol) { |
|||
low = emptyTilePosCol; |
|||
high = currentTileCol; |
|||
|
|||
int i = low; |
|||
while (i < high) { |
|||
myList![(emptyTilePosRow * _puzzleSize) + i] = myList![(emptyTilePosRow * _puzzleSize) + (i + 1)]; |
|||
|
|||
i += 1; |
|||
} |
|||
|
|||
myList![high + (emptyTilePosRow * _puzzleSize)] = 0; |
|||
_moves++; |
|||
} |
|||
|
|||
//multiple elements move right |
|||
else { |
|||
low = emptyTilePosCol; |
|||
high = currentTileCol; |
|||
|
|||
int i = low; |
|||
while (i > high) { |
|||
myList![(i + (emptyTilePosRow * _puzzleSize))] = myList![(i - 1) + (emptyTilePosRow * _puzzleSize)]; |
|||
|
|||
i -= 1; |
|||
} |
|||
|
|||
myList![high + (emptyTilePosRow * _puzzleSize)] = 0; |
|||
_moves++; |
|||
} |
|||
} |
|||
} |
|||
|
|||
// Update Offset list |
|||
// setState(() { |
|||
// updateOffset(myList!); |
|||
// }); |
|||
updateOffset(myList!); |
|||
setState(() {}); |
|||
|
|||
if (isSolved(myList!)) { |
|||
showCompleteDialogBox(context); |
|||
} |
|||
|
|||
log('List: $myList'); |
|||
log('-----------------------'); |
|||
} |
|||
} |
|||
|
|||
createOffset(List<int> board) { |
|||
Map<int, FractionalOffset> offsetMap = {}; |
|||
int j = 0; |
|||
|
|||
log('BOARD: $board'); |
|||
|
|||
for (int i = 0; i < board.length; i++) { |
|||
final xMod = i % _puzzleSize; |
|||
double x = xMod / (_puzzleSize - 1); |
|||
|
|||
if (x % i == 0 && i != 0) j++; |
|||
int yMod = j % _puzzleSize; |
|||
double y = yMod / (_puzzleSize - 1); |
|||
|
|||
offsetMap.addEntries([ |
|||
MapEntry<int, FractionalOffset>( |
|||
board[i], |
|||
FractionalOffset(x, y), |
|||
) |
|||
]); |
|||
} |
|||
|
|||
log('INITIAL OFFSET MAP: $offsetMap'); |
|||
setState(() { |
|||
_offsetMap = offsetMap; |
|||
}); |
|||
} |
|||
|
|||
updateOffset(List<int> board) { |
|||
int j = 0; |
|||
|
|||
for (int i = 0; i < board.length; i++) { |
|||
final xMod = i % _puzzleSize; |
|||
double x = xMod / (_puzzleSize - 1); |
|||
|
|||
if (x % i == 0 && i != 0) j++; |
|||
int yMod = j % _puzzleSize; |
|||
double y = yMod / (_puzzleSize - 1); |
|||
|
|||
_offsetMap![board[i]] = FractionalOffset(x, y); |
|||
} |
|||
log('OFFSET MAP: $_offsetMap'); |
|||
} |
|||
|
|||
showCompleteDialogBox(BuildContext context) { |
|||
showDialog( |
|||
context: context, |
|||
builder: (context) => Dialog( |
|||
child: Padding( |
|||
padding: const EdgeInsets.all(24.0), |
|||
child: Column( |
|||
mainAxisSize: MainAxisSize.min, |
|||
children: [ |
|||
const Text( |
|||
'Solved successfully!', |
|||
style: TextStyle(fontSize: 22), |
|||
), |
|||
const SizedBox(height: 16), |
|||
ElevatedButton( |
|||
style: ElevatedButton.styleFrom( |
|||
primary: Palette.violet, |
|||
onSurface: Palette.violet, |
|||
shape: RoundedRectangleBorder( |
|||
borderRadius: BorderRadius.circular(50), |
|||
), |
|||
), |
|||
onPressed: () { |
|||
Navigator.of(context).pop(); |
|||
}, |
|||
child: const Padding( |
|||
padding: EdgeInsets.all(16.0), |
|||
child: Text( |
|||
'OK', |
|||
style: TextStyle(fontSize: 22), |
|||
), |
|||
), |
|||
), |
|||
], |
|||
), |
|||
), |
|||
), |
|||
); |
|||
} |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
var screenSize = MediaQuery.of(context).size; |
|||
|
|||
var boardSize = screenSize.height * 0.6; |
|||
|
|||
var spacing = 4; |
|||
var eachBoxSize = (boardSize / _puzzleSize) - (spacing * (_puzzleSize - 1)); |
|||
|
|||
return Scaffold( |
|||
backgroundColor: Colors.white, |
|||
body: myList != null && _offsetMap != null |
|||
? Column( |
|||
mainAxisAlignment: MainAxisAlignment.spaceEvenly, |
|||
children: [ |
|||
Row(), |
|||
MovesText( |
|||
moves: _moves, |
|||
fontSize: 60, |
|||
), |
|||
SizedBox( |
|||
height: boardSize, |
|||
width: boardSize, |
|||
child: Stack( |
|||
children: [ |
|||
for (int i = 0; i < _offsetMap!.length; i++) |
|||
_offsetMap!.entries.toList()[i].key != 0 |
|||
? AnimatedAlign( |
|||
alignment: _offsetMap!.entries.toList()[i].value, |
|||
duration: Duration( |
|||
milliseconds: _animationSpeedInMilliseconds, |
|||
), |
|||
curve: Curves.easeInOut, |
|||
child: GestureDetector( |
|||
onTap: () => onClick(myList!.indexOf(_offsetMap!.entries.toList()[i].key)), |
|||
child: Card( |
|||
elevation: 4, |
|||
color: const Color(0xFF2868d7), |
|||
shape: RoundedRectangleBorder( |
|||
borderRadius: BorderRadius.circular(20), |
|||
), |
|||
child: SizedBox( |
|||
height: eachBoxSize, |
|||
width: eachBoxSize, |
|||
child: Center( |
|||
child: Text( |
|||
_offsetMap!.entries.toList()[i].key.toString(), |
|||
style: const TextStyle( |
|||
fontSize: 60, |
|||
fontWeight: FontWeight.bold, |
|||
color: Colors.white, |
|||
), |
|||
), |
|||
), |
|||
), |
|||
), |
|||
), |
|||
) |
|||
: const SizedBox(), |
|||
], |
|||
), |
|||
), |
|||
// AnimatedGrid( |
|||
// puzzleSize: _puzzleSize, |
|||
// key: UniqueKey(), |
|||
// number: myList!, |
|||
// offsetList: _offsetList!, |
|||
// onTap: onClick, |
|||
// color: const Color(0xFF2868d7), |
|||
// ), |
|||
const SizedBox(height: 30), |
|||
Row( |
|||
mainAxisSize: MainAxisSize.min, |
|||
children: [ |
|||
Padding( |
|||
padding: const EdgeInsets.only(bottom: 30.0), |
|||
child: SizedBox( |
|||
width: MediaQuery.of(context).size.width * 0.2, |
|||
child: ElevatedButton( |
|||
style: ElevatedButton.styleFrom( |
|||
primary: Palette.violet, |
|||
onSurface: Palette.violet, |
|||
shape: RoundedRectangleBorder( |
|||
borderRadius: BorderRadius.circular(50), |
|||
), |
|||
), |
|||
onPressed: _isComputing || _isAutoSolving || _isSolved |
|||
? null |
|||
: () { |
|||
startAutoSolver(); |
|||
}, |
|||
child: Padding( |
|||
padding: const EdgeInsets.all(16.0), |
|||
child: _isComputing || _isAutoSolving |
|||
? Row( |
|||
children: [ |
|||
const SizedBox( |
|||
width: 25, |
|||
height: 25, |
|||
child: CircularProgressIndicator( |
|||
color: Palette.violet, |
|||
strokeWidth: 2, |
|||
), |
|||
), |
|||
const SizedBox(width: 16), |
|||
Text( |
|||
_isComputing ? 'Computing ...' : 'Solving ...', |
|||
style: const TextStyle(fontSize: 20), |
|||
), |
|||
], |
|||
) |
|||
: const Text( |
|||
'Start Auto Solver', |
|||
style: TextStyle(fontSize: 22), |
|||
), |
|||
), |
|||
), |
|||
), |
|||
), |
|||
const SizedBox(width: 16.0), |
|||
Padding( |
|||
padding: const EdgeInsets.only(bottom: 30.0), |
|||
child: SizedBox( |
|||
width: MediaQuery.of(context).size.width * 0.2, |
|||
child: ElevatedButton( |
|||
style: ElevatedButton.styleFrom( |
|||
primary: Palette.crimson, |
|||
onSurface: Palette.crimson, |
|||
shape: RoundedRectangleBorder( |
|||
borderRadius: BorderRadius.circular(50), |
|||
), |
|||
), |
|||
onPressed: _isComputing || _isAutoSolving |
|||
? null |
|||
: () { |
|||
scrambleBoard(); |
|||
}, |
|||
child: const Padding( |
|||
padding: EdgeInsets.all(16.0), |
|||
child: Text( |
|||
'Scramble', |
|||
style: TextStyle(fontSize: 22), |
|||
), |
|||
), |
|||
), |
|||
), |
|||
), |
|||
], |
|||
), |
|||
], |
|||
) |
|||
: const SizedBox(), |
|||
); |
|||
} |
|||
} |
@ -0,0 +1,43 @@ |
|||
import 'dart:async'; |
|||
|
|||
import 'package:flutter/material.dart'; |
|||
import 'package:flutter_svg/flutter_svg.dart'; |
|||
import 'package:my_flutter_puzzle/screens/level_list/screen/level_list_screen.dart'; |
|||
import 'package:my_flutter_puzzle/utils/extensions/string_extensions.dart'; |
|||
|
|||
class SplashScreen extends StatefulWidget { |
|||
const SplashScreen({Key? key}) : super(key: key); |
|||
|
|||
@override |
|||
State<SplashScreen> createState() => _SplashScreenState(); |
|||
} |
|||
|
|||
class _SplashScreenState extends State<SplashScreen> { |
|||
@override |
|||
void initState() { |
|||
Timer(const Duration(milliseconds: 2000), () { |
|||
Navigator.push(context, MaterialPageRoute( |
|||
builder: (context) { |
|||
return const LevelListScreen(); |
|||
}, |
|||
)); |
|||
}); |
|||
super.initState(); |
|||
} |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
return Scaffold( |
|||
backgroundColor: const Color(0xff6236FF), |
|||
body: Center( |
|||
child: Container( |
|||
decoration: BoxDecoration( |
|||
image: DecorationImage( |
|||
image: AssetImage('splash_screen_image'.pngPath), |
|||
), |
|||
), |
|||
), |
|||
), |
|||
); |
|||
} |
|||
} |
@ -0,0 +1,19 @@ |
|||
import 'package:flutter/material.dart'; |
|||
|
|||
extension ContextExtentions on BuildContext { |
|||
double get height { |
|||
return MediaQuery.of(this).size.height; |
|||
} |
|||
|
|||
double get width { |
|||
return MediaQuery.of(this).size.width; |
|||
} |
|||
|
|||
double get horizontallyMargin { |
|||
return MediaQuery.of(this).size.width * 0.05; |
|||
} |
|||
|
|||
double get verticallyMargin { |
|||
return MediaQuery.of(this).size.height * 0.025; |
|||
} |
|||
} |
@ -1,308 +0,0 @@ |
|||
import 'package:flutter/material.dart'; |
|||
|
|||
class AnimatedGrid extends StatefulWidget { |
|||
const AnimatedGrid({ |
|||
Key? key, |
|||
required this.number, |
|||
required this.offsetList, |
|||
required this.onTap, |
|||
required this.color, |
|||
required this.puzzleSize, |
|||
}) : super(key: key); |
|||
|
|||
final Function onTap; |
|||
final List<int> number; |
|||
final List<FractionalOffset> offsetList; |
|||
final Color color; |
|||
final int puzzleSize; |
|||
|
|||
@override |
|||
State<AnimatedGrid> createState() => _AnimatedGridState(); |
|||
} |
|||
|
|||
class _AnimatedGridState extends State<AnimatedGrid> { |
|||
late List<FractionalOffset> _offsetList; |
|||
|
|||
@override |
|||
void initState() { |
|||
_offsetList = widget.offsetList; |
|||
super.initState(); |
|||
} |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
var screenSize = MediaQuery.of(context).size; |
|||
var boardSize = screenSize.width * 0.4; |
|||
|
|||
var spacing = 4; |
|||
var eachBoxSize = |
|||
(boardSize / widget.puzzleSize) - (spacing * (widget.puzzleSize - 1)); |
|||
|
|||
return SizedBox( |
|||
height: boardSize, |
|||
width: boardSize, |
|||
child: Stack( |
|||
children: [ |
|||
for (int i = 0; i < widget.offsetList.length; i++) |
|||
widget.number[i] != 0 |
|||
? AnimatedAlign( |
|||
alignment: widget.offsetList[i], |
|||
duration: const Duration(seconds: 1), |
|||
curve: Curves.easeInOut, |
|||
child: GestureDetector( |
|||
onTap: () => widget.onTap(i), |
|||
child: Card( |
|||
elevation: 4, |
|||
color: widget.color, |
|||
shape: RoundedRectangleBorder( |
|||
borderRadius: BorderRadius.circular(20), |
|||
), |
|||
child: SizedBox( |
|||
height: eachBoxSize, |
|||
width: eachBoxSize, |
|||
child: Center( |
|||
child: Text( |
|||
widget.number[i].toString(), |
|||
style: const TextStyle( |
|||
fontSize: 60, |
|||
fontWeight: FontWeight.bold, |
|||
color: Colors.white, |
|||
), |
|||
), |
|||
), |
|||
), |
|||
), |
|||
), |
|||
) |
|||
: const SizedBox(), |
|||
], |
|||
), |
|||
); |
|||
|
|||
// ----------------------------- |
|||
// Working implementation: |
|||
// ----------------------------- |
|||
// return SizedBox( |
|||
// height: screenSize.height * 0.7, |
|||
// width: screenSize.width * 0.4, |
|||
// child: GridView.builder( |
|||
// gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( |
|||
// crossAxisCount: puzzleSize, |
|||
// ), |
|||
// itemCount: number.length, |
|||
// itemBuilder: (context, index) { |
|||
// return number[index] != 0 |
|||
// ? Padding( |
|||
// padding: const EdgeInsets.all(2.0), |
|||
// child: GestureDetector( |
|||
// onTap: () => onTap(index), |
|||
// child: AnimatedPositioned( |
|||
// duration: Duration(milliseconds: 600), |
|||
// child: Container( |
|||
// height: 20, |
|||
// width: 20, |
|||
// color: Colors.orange, |
|||
// ), |
|||
// ), |
|||
// ), |
|||
// ) |
|||
// // ? MouseRegion( |
|||
// // child: Padding( |
|||
// // padding: const EdgeInsets.all(2.0), |
|||
// // child: GestureDetector( |
|||
// // onTap: () => onTap(index), |
|||
// // child: Card( |
|||
// // elevation: 4, |
|||
// // color: color, |
|||
// // // dark -> 0xFF14407a |
|||
// // // light -> 0xFF43b9fd |
|||
// // shape: RoundedRectangleBorder( |
|||
// // borderRadius: BorderRadius.circular(20), |
|||
// // ), |
|||
// // child: SizedBox( |
|||
// // height: 20, |
|||
// // width: 20, |
|||
// // child: Center( |
|||
// // child: Text( |
|||
// // number[index].toString(), |
|||
// // style: const TextStyle( |
|||
// // fontSize: 60, |
|||
// // fontWeight: FontWeight.bold, |
|||
// // color: Colors.white, |
|||
// // ), |
|||
// // ), |
|||
// // ), |
|||
// // ), |
|||
// // ), |
|||
// // ), |
|||
// // ), |
|||
// // ) |
|||
// : const SizedBox(); |
|||
// // }, |
|||
// // ), |
|||
// // ); |
|||
// } |
|||
} |
|||
} |
|||
|
|||
// class AnimatedGrid extends StatefulWidget { |
|||
// const AnimatedGrid({ |
|||
// Key? key, |
|||
// required this.number, |
|||
// required this.offsetList, |
|||
// required this.onTap, |
|||
// required this.color, |
|||
// required this.puzzleSize, |
|||
// }) : super(key: key); |
|||
|
|||
// final Function onTap; |
|||
// final List<int> number; |
|||
// final List<FractionalOffset> offsetList; |
|||
// final Color color; |
|||
// final int puzzleSize; |
|||
|
|||
// @override |
|||
// State<AnimatedGrid> createState() => _AnimatedGridState(); |
|||
// } |
|||
|
|||
// class _AnimatedGridState extends State<AnimatedGrid> { |
|||
// // FractionalOffset offset = FractionalOffset(0, 0); |
|||
// late final List<int> _numberList; |
|||
// // late final int _puzzleSize; |
|||
|
|||
// @override |
|||
// void initState() { |
|||
// _numberList = widget.number; |
|||
// // _puzzleSize = widget.puzzleSize; |
|||
// // print(_numberList); |
|||
// // print(widget.offsetList); |
|||
// super.initState(); |
|||
// } |
|||
|
|||
// // calculateOffset() { |
|||
// // List<FractionalOffset> offsetList = []; |
|||
|
|||
// // for (int i = 0; i < _puzzleSize; i++) { |
|||
// // int yMod = i % _puzzleSize; |
|||
// // double y = yMod / (_puzzleSize - 1); |
|||
// // for (int j = 0; j < _puzzleSize; j++) { |
|||
// // final xMod = _numberList[i][j] % _puzzleSize; |
|||
// // double x = xMod / (_puzzleSize - 1); |
|||
// // offsetList.add(FractionalOffset(x, y)); |
|||
// // } |
|||
// // } |
|||
// // } |
|||
|
|||
// @override |
|||
// Widget build(BuildContext context) { |
|||
// var screenSize = MediaQuery.of(context).size; |
|||
// var boardSize = screenSize.width * 0.4; |
|||
|
|||
// var spacing = 4; |
|||
// var eachBoxSize = |
|||
// (boardSize / widget.puzzleSize) - (spacing * (widget.puzzleSize - 1)); |
|||
|
|||
// return SizedBox( |
|||
// height: boardSize, |
|||
// width: boardSize, |
|||
// child: Stack( |
|||
// children: [ |
|||
// for (var offset in widget.offsetList) |
|||
// AnimatedAlign( |
|||
// alignment: offset, |
|||
// duration: const Duration(seconds: 1), |
|||
// curve: Curves.easeInOut, |
|||
// child: Container( |
|||
// height: eachBoxSize, |
|||
// width: eachBoxSize, |
|||
// color: Colors.black, |
|||
// ), |
|||
// ), |
|||
// // AnimatedAlign( |
|||
// // alignment: FractionalOffset(1, 0), |
|||
// // duration: Duration(seconds: 1), |
|||
// // curve: Curves.easeInOut, |
|||
// // child: Container( |
|||
// // height: eachBoxSize, |
|||
// // width: eachBoxSize, |
|||
// // color: Colors.black, |
|||
// // ), |
|||
// // ), |
|||
// // AnimatedAlign( |
|||
// // alignment: FractionalOffset(0.5, 1), |
|||
// // duration: Duration(seconds: 1), |
|||
// // curve: Curves.easeInOut, |
|||
// // child: Container( |
|||
// // height: eachBoxSize, |
|||
// // width: eachBoxSize, |
|||
// // color: Colors.black, |
|||
// // ), |
|||
// // ), |
|||
// ], |
|||
// ), |
|||
// ); |
|||
|
|||
// // ----------------------------- |
|||
// // Working implementation: |
|||
// // ----------------------------- |
|||
// // return SizedBox( |
|||
// // height: screenSize.height * 0.7, |
|||
// // width: screenSize.width * 0.4, |
|||
// // child: GridView.builder( |
|||
// // gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( |
|||
// // crossAxisCount: puzzleSize, |
|||
// // ), |
|||
// // itemCount: number.length, |
|||
// // itemBuilder: (context, index) { |
|||
// // return number[index] != 0 |
|||
// // ? Padding( |
|||
// // padding: const EdgeInsets.all(2.0), |
|||
// // child: GestureDetector( |
|||
// // onTap: () => onTap(index), |
|||
// // child: AnimatedPositioned( |
|||
// // duration: Duration(milliseconds: 600), |
|||
// // child: Container( |
|||
// // height: 20, |
|||
// // width: 20, |
|||
// // color: Colors.orange, |
|||
// // ), |
|||
// // ), |
|||
// // ), |
|||
// // ) |
|||
// // // ? MouseRegion( |
|||
// // // child: Padding( |
|||
// // // padding: const EdgeInsets.all(2.0), |
|||
// // // child: GestureDetector( |
|||
// // // onTap: () => onTap(index), |
|||
// // // child: Card( |
|||
// // // elevation: 4, |
|||
// // // color: color, |
|||
// // // // dark -> 0xFF14407a |
|||
// // // // light -> 0xFF43b9fd |
|||
// // // shape: RoundedRectangleBorder( |
|||
// // // borderRadius: BorderRadius.circular(20), |
|||
// // // ), |
|||
// // // child: SizedBox( |
|||
// // // height: 20, |
|||
// // // width: 20, |
|||
// // // child: Center( |
|||
// // // child: Text( |
|||
// // // number[index].toString(), |
|||
// // // style: const TextStyle( |
|||
// // // fontSize: 60, |
|||
// // // fontWeight: FontWeight.bold, |
|||
// // // color: Colors.white, |
|||
// // // ), |
|||
// // // ), |
|||
// // // ), |
|||
// // // ), |
|||
// // // ), |
|||
// // // ), |
|||
// // // ), |
|||
// // // ) |
|||
// // : const SizedBox(); |
|||
// // }, |
|||
// // ), |
|||
// // ); |
|||
// } |
|||
// } |
@ -1,67 +0,0 @@ |
|||
import 'package:flutter/material.dart'; |
|||
|
|||
class Grid extends StatelessWidget { |
|||
const Grid({ |
|||
Key? key, |
|||
required this.number, |
|||
required this.onTap, |
|||
required this.color, |
|||
required this.puzzleSize, |
|||
}) : super(key: key); |
|||
|
|||
final Function onTap; |
|||
final List<dynamic> number; |
|||
final Color color; |
|||
final int puzzleSize; |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
var screenSize = MediaQuery.of(context).size; |
|||
|
|||
return SizedBox( |
|||
height: screenSize.height * 0.7, |
|||
width: screenSize.width * 0.4, |
|||
child: GridView.builder( |
|||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( |
|||
crossAxisCount: puzzleSize, |
|||
), |
|||
itemCount: number.length, |
|||
itemBuilder: (context, index) { |
|||
return number[index] != 0 |
|||
? MouseRegion( |
|||
child: Padding( |
|||
padding: const EdgeInsets.all(2.0), |
|||
child: GestureDetector( |
|||
onTap: () => onTap(index), |
|||
child: Card( |
|||
elevation: 4, |
|||
color: color, |
|||
// dark -> 0xFF14407a |
|||
// light -> 0xFF43b9fd |
|||
shape: RoundedRectangleBorder( |
|||
borderRadius: BorderRadius.circular(20), |
|||
), |
|||
child: SizedBox( |
|||
height: 20, |
|||
width: 20, |
|||
child: Center( |
|||
child: Text( |
|||
number[index].toString(), |
|||
style: const TextStyle( |
|||
fontSize: 60, |
|||
fontWeight: FontWeight.bold, |
|||
color: Colors.white, |
|||
), |
|||
), |
|||
), |
|||
), |
|||
), |
|||
), |
|||
), |
|||
) |
|||
: const SizedBox(); |
|||
}, |
|||
), |
|||
); |
|||
} |
|||
} |
@ -1,62 +0,0 @@ |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:my_flutter_puzzle/res/palette.dart'; |
|||
|
|||
class NameField extends StatefulWidget { |
|||
final FocusNode focusNode; |
|||
final Function(String) onChange; |
|||
|
|||
const NameField({ |
|||
Key? key, |
|||
required this.focusNode, |
|||
required this.onChange, |
|||
}) : super(key: key); |
|||
|
|||
@override |
|||
State<NameField> createState() => _NameFieldState(); |
|||
} |
|||
|
|||
class _NameFieldState extends State<NameField> { |
|||
late final TextEditingController _nameTextController; |
|||
late final FocusNode _nameFocusNode; |
|||
|
|||
@override |
|||
void initState() { |
|||
super.initState(); |
|||
_nameTextController = TextEditingController(); |
|||
_nameFocusNode = widget.focusNode; |
|||
} |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
return TextField( |
|||
controller: _nameTextController, |
|||
focusNode: _nameFocusNode, |
|||
style: const TextStyle( |
|||
fontSize: 24, |
|||
color: Palette.crimson, |
|||
), |
|||
cursorColor: Palette.violet, |
|||
decoration: InputDecoration( |
|||
border: const UnderlineInputBorder(), |
|||
focusedBorder: const UnderlineInputBorder( |
|||
borderSide: BorderSide( |
|||
color: Palette.violet, |
|||
width: 3, |
|||
), |
|||
), |
|||
enabledBorder: UnderlineInputBorder( |
|||
borderSide: BorderSide( |
|||
color: Palette.violet.withOpacity(0.5), |
|||
width: 2, |
|||
), |
|||
), |
|||
hintText: 'Enter your name', |
|||
hintStyle: TextStyle( |
|||
fontSize: 22, |
|||
color: Palette.violet.withOpacity(0.2), |
|||
), |
|||
), |
|||
onChanged: (value) => widget.onChange(value), |
|||
); |
|||
} |
|||
} |
@ -1,72 +0,0 @@ |
|||
// import 'package:flutter/material.dart'; |
|||
// import 'package:flutter_riverpod/flutter_riverpod.dart'; |
|||
// import 'package:my_flutter_puzzle/application/states/anonymous_auth_state.dart'; |
|||
// import 'package:my_flutter_puzzle/providers.dart'; |
|||
// import 'package:my_flutter_puzzle/res/palette.dart'; |
|||
// import 'package:my_flutter_puzzle/screens/menu_screen.dart'; |
|||
// import 'package:my_flutter_puzzle/screens/puzzle_screen.dart'; |
|||
// import 'package:my_flutter_puzzle/widgets/login_widgets/start_game_widget/start_game_button.dart'; |
|||
|
|||
// class StartGameWidget extends ConsumerWidget { |
|||
// const StartGameWidget({ |
|||
// Key? key, |
|||
// required String nameString, |
|||
// }) : _nameString = nameString, |
|||
// super(key: key); |
|||
|
|||
// final String _nameString; |
|||
|
|||
// @override |
|||
// Widget build(BuildContext context, WidgetRef ref) { |
|||
// ref.listen(anonymousAuthNotificationProvider, (previous, next) { |
|||
// if (next is StorageDone) { |
|||
// Navigator.of(context).pushAndRemoveUntil( |
|||
// MaterialPageRoute( |
|||
// builder: (context) => MenuScreen( |
|||
// userData: next.userData, |
|||
// ), |
|||
// ), |
|||
// (route) => false, |
|||
// ); |
|||
// } |
|||
// }); |
|||
|
|||
// return Consumer( |
|||
// builder: (context, ref, child) { |
|||
// final state = ref.watch(anonymousAuthNotificationProvider); |
|||
|
|||
// return state.when( |
|||
// () => StartGameButton( |
|||
// nameString: _nameString, |
|||
// ), |
|||
// processing: () => const CircularProgressIndicator( |
|||
// valueColor: AlwaysStoppedAnimation<Color>(Palette.violet), |
|||
// ), |
|||
// done: (_) => const CircularProgressIndicator( |
|||
// valueColor: AlwaysStoppedAnimation<Color>(Palette.violet), |
|||
// ), |
|||
// storingInfo: () => const CircularProgressIndicator( |
|||
// valueColor: AlwaysStoppedAnimation<Color>(Palette.violet), |
|||
// ), |
|||
// storageDone: (userData) => const Icon( |
|||
// Icons.check, |
|||
// size: 50, |
|||
// color: Palette.violet, |
|||
// ), |
|||
// // done: (_) => const Icon( |
|||
// // Icons.check, |
|||
// // size: 50, |
|||
// // color: Palette.violet, |
|||
// // ), |
|||
// error: (message) => Column( |
|||
// children: [ |
|||
// Text('$message'), |
|||
// const SizedBox(height: 16), |
|||
// StartGameButton(nameString: _nameString), |
|||
// ], |
|||
// ), |
|||
// ); |
|||
// }, |
|||
// ); |
|||
// } |
|||
// } |
@ -1,39 +0,0 @@ |
|||
// import 'package:flutter/material.dart'; |
|||
// import 'package:flutter_riverpod/flutter_riverpod.dart'; |
|||
// import 'package:my_flutter_puzzle/providers.dart'; |
|||
// import 'package:my_flutter_puzzle/res/palette.dart'; |
|||
|
|||
// class StartGameButton extends ConsumerWidget { |
|||
// const StartGameButton({ |
|||
// Key? key, |
|||
// required String nameString, |
|||
// }) : _nameString = nameString, |
|||
// super(key: key); |
|||
|
|||
// final String _nameString; |
|||
|
|||
// @override |
|||
// Widget build(BuildContext context, WidgetRef ref) { |
|||
// return SizedBox( |
|||
// width: double.maxFinite, |
|||
// child: ElevatedButton( |
|||
// style: ElevatedButton.styleFrom( |
|||
// primary: Palette.violet, |
|||
// onSurface: Palette.violet, |
|||
// ), |
|||
// onPressed: _nameString.isEmpty || _nameString.length < 3 |
|||
// ? null |
|||
// : () => ref |
|||
// .read(anonymousAuthNotificationProvider.notifier) |
|||
// .triggerAnonymousLogin(name: _nameString), |
|||
// child: const Padding( |
|||
// padding: EdgeInsets.all(16.0), |
|||
// child: Text( |
|||
// 'Start game', |
|||
// style: TextStyle(fontSize: 22), |
|||
// ), |
|||
// ), |
|||
// ), |
|||
// ); |
|||
// } |
|||
// } |
@ -1,2 +0,0 @@ |
|||
export 'multiplayer_button.dart'; |
|||
export 'solo_button.dart'; |
@ -1,108 +0,0 @@ |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:flutter_riverpod/flutter_riverpod.dart'; |
|||
import 'package:my_flutter_puzzle/models/user_info.dart'; |
|||
import 'package:my_flutter_puzzle/res/palette.dart'; |
|||
|
|||
class MultiplayerButton extends ConsumerStatefulWidget { |
|||
const MultiplayerButton({ |
|||
Key? key, |
|||
required this.myInfo, |
|||
required this.list, |
|||
}) : super(key: key); |
|||
|
|||
final UserData myInfo; |
|||
final List<int> list; |
|||
|
|||
@override |
|||
ConsumerState<ConsumerStatefulWidget> createState() => _MultiplayerButtonState(); |
|||
} |
|||
|
|||
class _MultiplayerButtonState extends ConsumerState<MultiplayerButton> { |
|||
late final List<int> numberList; |
|||
|
|||
@override |
|||
void initState() { |
|||
super.initState(); |
|||
numberList = widget.list; |
|||
numberList.shuffle(); |
|||
} |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
return SizedBox( |
|||
width: double.maxFinite, |
|||
child: OutlinedButton( |
|||
style: OutlinedButton.styleFrom( |
|||
primary: Palette.violet, |
|||
onSurface: Palette.violet, |
|||
shape: RoundedRectangleBorder( |
|||
borderRadius: BorderRadius.circular(50), |
|||
), |
|||
side: const BorderSide( |
|||
width: 2, |
|||
color: Palette.violet, |
|||
), |
|||
), |
|||
onPressed: () { |
|||
// ref |
|||
// .read(playerMatchingNotifierProvider.notifier) |
|||
// .triggerMatching(myInfo: widget.myInfo, numbers: numberList); |
|||
}, |
|||
child: const Padding( |
|||
padding: EdgeInsets.all(16.0), |
|||
child: Text( |
|||
'Multiplayer', |
|||
style: TextStyle(fontSize: 22), |
|||
), |
|||
), |
|||
), |
|||
); |
|||
} |
|||
} |
|||
|
|||
// class MultiplayerButton extends StatefulWidget { |
|||
// final UserData myInfo; |
|||
// MultiplayerButton({ |
|||
// Key? key, |
|||
// required this.myInfo, |
|||
// }) : super(key: key); |
|||
|
|||
// @override |
|||
// State<MultiplayerButton> createState() => _MultiplayerButtonState(); |
|||
// } |
|||
|
|||
// class _MultiplayerButtonState extends State<MultiplayerButton> { |
|||
// final numberList = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; |
|||
|
|||
// @override |
|||
// Widget build(BuildContext context) { |
|||
// return SizedBox( |
|||
// width: double.maxFinite, |
|||
// child: OutlinedButton( |
|||
// style: OutlinedButton.styleFrom( |
|||
// primary: Palette.violet, |
|||
// onSurface: Palette.violet, |
|||
// shape: RoundedRectangleBorder( |
|||
// borderRadius: BorderRadius.circular(50), |
|||
// ), |
|||
// side: const BorderSide( |
|||
// width: 2, |
|||
// color: Palette.violet, |
|||
// ), |
|||
// ), |
|||
// onPressed: () { |
|||
// ref.read(playerMatchingNotifierProvider.notifier).triggerMatching( |
|||
// myInfo: widget.myInfo, |
|||
// numbers: [14, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 15]); |
|||
// }, |
|||
// child: const Padding( |
|||
// padding: EdgeInsets.all(16.0), |
|||
// child: Text( |
|||
// 'Multiplayer', |
|||
// style: TextStyle(fontSize: 22), |
|||
// ), |
|||
// ), |
|||
// ), |
|||
// ); |
|||
// } |
|||
// } |
@ -1,44 +0,0 @@ |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:my_flutter_puzzle/res/palette.dart'; |
|||
import 'package:my_flutter_puzzle/screens/puzzle_solo_screen.dart'; |
|||
|
|||
class SoloButton extends StatelessWidget { |
|||
const SoloButton({ |
|||
Key? key, |
|||
}) : super(key: key); |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
return SizedBox( |
|||
width: double.maxFinite, |
|||
child: OutlinedButton( |
|||
style: OutlinedButton.styleFrom( |
|||
primary: Palette.violet, |
|||
onSurface: Palette.violet, |
|||
shape: RoundedRectangleBorder( |
|||
borderRadius: BorderRadius.circular(50), |
|||
), |
|||
side: const BorderSide( |
|||
width: 2, |
|||
color: Palette.violet, |
|||
), |
|||
), |
|||
onPressed: () { |
|||
Navigator.of(context).pushAndRemoveUntil( |
|||
MaterialPageRoute( |
|||
builder: (context) => const PuzzleSoloScreen(), |
|||
), |
|||
(route) => false, |
|||
); |
|||
}, |
|||
child: const Padding( |
|||
padding: EdgeInsets.all(16.0), |
|||
child: Text( |
|||
'Solo', |
|||
style: TextStyle(fontSize: 22), |
|||
), |
|||
), |
|||
), |
|||
); |
|||
} |
|||
} |
@ -1,53 +0,0 @@ |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:flutter_riverpod/flutter_riverpod.dart'; |
|||
|
|||
class PickImageButton extends ConsumerWidget { |
|||
const PickImageButton({ |
|||
Key? key, |
|||
required this.text, |
|||
required this.onTap, |
|||
this.padding = const EdgeInsets.only(top: 13.0, bottom: 12.0), |
|||
this.width = 145, |
|||
}) : super(key: key); |
|||
|
|||
final String text; |
|||
final Function()? onTap; |
|||
final EdgeInsets padding; |
|||
final double width; |
|||
|
|||
@override |
|||
Widget build(BuildContext context, WidgetRef ref) { |
|||
return SizedBox( |
|||
width: width, |
|||
child: ElevatedButton( |
|||
style: ButtonStyle( |
|||
shape: MaterialStateProperty.all<RoundedRectangleBorder>( |
|||
RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)), |
|||
), |
|||
backgroundColor: MaterialStateProperty.resolveWith<Color>( |
|||
(Set<MaterialState> states) { |
|||
if (states.contains(MaterialState.pressed)) { |
|||
return Theme.of(context).colorScheme.primary.withOpacity(0.5); |
|||
} else if (states.contains(MaterialState.disabled)) { |
|||
return Theme.of(context).colorScheme.primary.withOpacity(0.5); |
|||
} |
|||
|
|||
return Theme.of(context).colorScheme.primary; |
|||
}, |
|||
), |
|||
), |
|||
onPressed: onTap, |
|||
child: Padding( |
|||
padding: padding, |
|||
child: Text( |
|||
text, |
|||
style: TextStyle( |
|||
fontSize: 16, |
|||
color: Colors.white.withOpacity(onTap == null ? 0.6 : 1), |
|||
), |
|||
), |
|||
), |
|||
), |
|||
); |
|||
} |
|||
} |
@ -1,28 +0,0 @@ |
|||
import 'package:flutter/material.dart'; |
|||
|
|||
class MovesText extends StatelessWidget { |
|||
const MovesText({ |
|||
Key? key, |
|||
required int moves, |
|||
required this.fontSize, |
|||
}) : _moves = moves, |
|||
super(key: key); |
|||
|
|||
final int _moves; |
|||
final double fontSize; |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
return Padding( |
|||
padding: const EdgeInsets.fromLTRB(0, 8, 0, 24), |
|||
child: Text( |
|||
'$_moves Moves', |
|||
style: TextStyle( |
|||
fontSize: fontSize, |
|||
fontWeight: FontWeight.bold, |
|||
color: Colors.black, |
|||
), |
|||
), |
|||
); |
|||
} |
|||
} |
@ -1,26 +0,0 @@ |
|||
import 'package:flutter/material.dart'; |
|||
|
|||
class PlayerText extends StatelessWidget { |
|||
final String displayName; |
|||
|
|||
const PlayerText({ |
|||
Key? key, |
|||
required this.displayName, |
|||
}) : super(key: key); |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
return Padding( |
|||
padding: const EdgeInsets.only(top: 24.0), |
|||
child: Text( |
|||
displayName, |
|||
style: const TextStyle( |
|||
fontSize: 20, |
|||
fontWeight: FontWeight.bold, |
|||
color: Color(0xFF14407a), |
|||
letterSpacing: 2, |
|||
), |
|||
), |
|||
); |
|||
} |
|||
} |
@ -1,2 +0,0 @@ |
|||
export 'moves_text.dart'; |
|||
export 'player_text.dart'; |
@ -1,73 +0,0 @@ |
|||
import 'dart:async'; |
|||
|
|||
import 'package:flutter/material.dart'; |
|||
|
|||
class TimerWidget extends StatefulWidget { |
|||
const TimerWidget({ |
|||
Key? key, |
|||
required this.fontSize, |
|||
required this.color, |
|||
}) : super(key: key); |
|||
|
|||
final double fontSize; |
|||
final Color color; |
|||
|
|||
@override |
|||
_TimerWidgetState createState() => _TimerWidgetState(); |
|||
} |
|||
|
|||
class _TimerWidgetState extends State<TimerWidget> { |
|||
late final Timer _timer; |
|||
int _start = 0; |
|||
|
|||
void startTimer() { |
|||
_timer = Timer.periodic( |
|||
const Duration(seconds: 1), |
|||
(Timer timer) => setState(() => _start++), |
|||
); |
|||
} |
|||
|
|||
String printDuration() { |
|||
var duration = Duration(seconds: _start); |
|||
String twoDigits(int n) => n.toString().padLeft(2, "0"); |
|||
String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60)); |
|||
String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60)); |
|||
return "${twoDigits(duration.inHours)}:$twoDigitMinutes:$twoDigitSeconds"; |
|||
} |
|||
|
|||
@override |
|||
void initState() { |
|||
startTimer(); |
|||
super.initState(); |
|||
} |
|||
|
|||
@override |
|||
void dispose() { |
|||
_timer.cancel(); |
|||
super.dispose(); |
|||
} |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
return Center( |
|||
child: Row( |
|||
mainAxisSize: MainAxisSize.min, |
|||
children: [ |
|||
Text( |
|||
printDuration(), |
|||
style: TextStyle( |
|||
fontSize: widget.fontSize, |
|||
color: widget.color, |
|||
), |
|||
), |
|||
const SizedBox(width: 8), |
|||
Icon( |
|||
Icons.timer, |
|||
color: widget.color, |
|||
size: widget.fontSize * 1.3, |
|||
) |
|||
], |
|||
), |
|||
); |
|||
} |
|||
} |
@ -1,6 +0,0 @@ |
|||
export 'animated_dash.dart'; |
|||
export 'countdown_widget.dart'; |
|||
export 'game_button_widget.dart'; |
|||
export 'moves_tiles_widget.dart'; |
|||
export 'puzzle_widget.dart'; |
|||
export 'timer_widget.dart'; |