diff --git a/assets/images/jpg/level-1.jpg b/assets/images/jpg/level-1.jpg
new file mode 100644
index 0000000..31c2349
Binary files /dev/null and b/assets/images/jpg/level-1.jpg differ
diff --git a/assets/images/jpg/level-2.jpg b/assets/images/jpg/level-2.jpg
new file mode 100644
index 0000000..ff9f70b
Binary files /dev/null and b/assets/images/jpg/level-2.jpg differ
diff --git a/assets/images/jpg/level-3.jpg b/assets/images/jpg/level-3.jpg
new file mode 100644
index 0000000..ac94565
Binary files /dev/null and b/assets/images/jpg/level-3.jpg differ
diff --git a/assets/images/jpg/level-4.jpg b/assets/images/jpg/level-4.jpg
new file mode 100644
index 0000000..a2a3038
Binary files /dev/null and b/assets/images/jpg/level-4.jpg differ
diff --git a/assets/images/jpg/level-5.jpg b/assets/images/jpg/level-5.jpg
new file mode 100644
index 0000000..b7acdac
Binary files /dev/null and b/assets/images/jpg/level-5.jpg differ
diff --git a/assets/images/jpg/level-6.jpg b/assets/images/jpg/level-6.jpg
new file mode 100644
index 0000000..0f2af64
Binary files /dev/null and b/assets/images/jpg/level-6.jpg differ
diff --git a/assets/images/jpg/level-7.jpg b/assets/images/jpg/level-7.jpg
new file mode 100644
index 0000000..1985d7f
Binary files /dev/null and b/assets/images/jpg/level-7.jpg differ
diff --git a/assets/images/jpg/level-8.jpg b/assets/images/jpg/level-8.jpg
new file mode 100644
index 0000000..2f01d12
Binary files /dev/null and b/assets/images/jpg/level-8.jpg differ
diff --git a/assets/images/level_1_image.png b/assets/images/level_1_image.png
deleted file mode 100644
index c591db0..0000000
Binary files a/assets/images/level_1_image.png and /dev/null differ
diff --git a/assets/images/level_2_image.png b/assets/images/level_2_image.png
deleted file mode 100644
index 7e8e3b3..0000000
Binary files a/assets/images/level_2_image.png and /dev/null differ
diff --git a/assets/images/level_4_image.png b/assets/images/level_4_image.png
deleted file mode 100644
index 450e231..0000000
Binary files a/assets/images/level_4_image.png and /dev/null differ
diff --git a/assets/images/png/avatar.png b/assets/images/png/avatar.png
new file mode 100644
index 0000000..723b362
Binary files /dev/null and b/assets/images/png/avatar.png differ
diff --git a/assets/images/default_image.png b/assets/images/png/default_image.png
similarity index 100%
rename from assets/images/default_image.png
rename to assets/images/png/default_image.png
diff --git a/assets/images/level_screen_image.png b/assets/images/png/level_screen_image.png
similarity index 100%
rename from assets/images/level_screen_image.png
rename to assets/images/png/level_screen_image.png
diff --git a/assets/images/puzzle_side_image.png b/assets/images/png/puzzle_side_image.png
similarity index 100%
rename from assets/images/puzzle_side_image.png
rename to assets/images/png/puzzle_side_image.png
diff --git a/assets/images/splash_screen_image.png b/assets/images/png/splash_screen_image.png
similarity index 100%
rename from assets/images/splash_screen_image.png
rename to assets/images/png/splash_screen_image.png
diff --git a/assets/images/start.png b/assets/images/png/start.png
similarity index 100%
rename from assets/images/start.png
rename to assets/images/png/start.png
diff --git a/assets/images/svg/flash.svg b/assets/images/svg/flash.svg
new file mode 100644
index 0000000..5eedea7
--- /dev/null
+++ b/assets/images/svg/flash.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/images/svg/refresh.svg b/assets/images/svg/refresh.svg
new file mode 100644
index 0000000..ffdd85a
--- /dev/null
+++ b/assets/images/svg/refresh.svg
@@ -0,0 +1,4 @@
+
diff --git a/assets/images/svg/timer.svg b/assets/images/svg/timer.svg
new file mode 100644
index 0000000..dbc4064
--- /dev/null
+++ b/assets/images/svg/timer.svg
@@ -0,0 +1,3 @@
+
diff --git a/lib/application/notifiers/image_splitter_notifier.dart b/lib/application/notifiers/image_splitter_notifier.dart
index bb7a7f6..ba6af56 100644
--- a/lib/application/notifiers/image_splitter_notifier.dart
+++ b/lib/application/notifiers/image_splitter_notifier.dart
@@ -1,10 +1,7 @@
-import 'dart:developer';
-
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:my_flutter_puzzle/application/states/image_splitter_state.dart';
-import 'package:my_flutter_puzzle/res/strings.dart';
import 'package:my_flutter_puzzle/utils/image_splitter.dart';
class ImageSplitterNotifier extends StateNotifier {
diff --git a/lib/cubits/count_down_timer_cubit.dart b/lib/cubits/count_down_timer_cubit.dart
index 22de9c3..bf6ad5c 100644
--- a/lib/cubits/count_down_timer_cubit.dart
+++ b/lib/cubits/count_down_timer_cubit.dart
@@ -2,17 +2,25 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:my_flutter_puzzle/cubits/base_cubit_type.dart';
class CountDownTimerCubit extends Cubit> {
- CountDownTimerCubit() : super(BaseCubitType(eventName: CountDownTimerState.empty));
+ CountDownTimerCubit()
+ : super(
+ BaseCubitType(
+ eventName: CountDownTimerState.empty,
+ ),
+ );
void empty() => emit(BaseCubitType(eventName: CountDownTimerState.empty));
void start() => emit(BaseCubitType(eventName: CountDownTimerState.start));
void stop() => emit(BaseCubitType(eventName: CountDownTimerState.stop));
+
+ void reset() => emit(BaseCubitType(eventName: CountDownTimerState.reset));
}
enum CountDownTimerState {
empty,
start,
stop,
+ reset,
}
diff --git a/lib/main.dart b/lib/main.dart
index 68d55b0..a55fa24 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -5,8 +5,10 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:my_flutter_puzzle/cubits/count_down_timer_cubit.dart';
import 'package:my_flutter_puzzle/res/palette.dart';
import 'package:my_flutter_puzzle/screens/level_list/screen/level_list_screen.dart';
+import 'package:my_flutter_puzzle/screens/puzzle/puzzle_starter_screen.dart';
import 'package:my_flutter_puzzle/screens/splash/screen/splash_screen.dart';
import 'package:my_flutter_puzzle/utils/color_brightness.dart';
+import 'package:my_flutter_puzzle/utils/extensions/string_extensions.dart';
import 'package:url_strategy/url_strategy.dart';
void main() async {
@@ -26,6 +28,12 @@ class MyApp extends StatelessWidget {
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight,
]);
+ Level level = Level(
+ image: 'level-1'.jpgPath,
+ duration: 4,
+ puzzleSize: 3,
+ level: 1,
+ );
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
return BlocProvider(
create: (context) => CountDownTimerCubit(),
@@ -50,7 +58,12 @@ class MyApp extends StatelessWidget {
onSurface: Colors.white38,
),
),
- home: const SplashScreen(),
+ home: PuzzleStarterScreen(
+ duration: level.duration,
+ puzzleSize: level.puzzleSize,
+ image: level.image,
+ level: level.level,
+ ),
),
);
}
diff --git a/lib/screens/level_list/screen/level_list_screen.dart b/lib/screens/level_list/screen/level_list_screen.dart
index 68aaf09..e43193f 100644
--- a/lib/screens/level_list/screen/level_list_screen.dart
+++ b/lib/screens/level_list/screen/level_list_screen.dart
@@ -18,15 +18,54 @@ class _LevelListScreenState extends State {
@override
void initState() {
- _levelList.add(Level(image: 'level_1_image'.pngPath, duration: 4, puzzleSize: 3, level: 1));
- _levelList.add(Level(image: 'level_1_image'.pngPath, duration: 4, puzzleSize: 3, level: 2));
- _levelList.add(Level(image: 'level_1_image'.pngPath, duration: 4, puzzleSize: 3, level: 3));
- _levelList.add(Level(image: 'level_2_image'.pngPath, duration: 6, puzzleSize: 4, level: 4));
- _levelList.add(Level(image: 'level_2_image'.pngPath, duration: 6, puzzleSize: 4, level: 5));
- _levelList.add(Level(image: 'level_2_image'.pngPath, duration: 6, puzzleSize: 4, level: 6));
- _levelList.add(Level(image: 'level_4_image'.pngPath, duration: 8, puzzleSize: 5, level: 7));
- _levelList.add(Level(image: 'level_4_image'.pngPath, duration: 8, puzzleSize: 5, level: 8));
- _levelList.add(Level(image: 'level_4_image'.pngPath, duration: 8, puzzleSize: 5, level: 9));
+ _levelList.add(Level(
+ image: 'level-1'.jpgPath,
+ duration: 4,
+ puzzleSize: 3,
+ level: 1,
+ ));
+ _levelList.add(Level(
+ image: 'level-2'.jpgPath,
+ duration: 4,
+ puzzleSize: 3,
+ level: 2,
+ ));
+ _levelList.add(Level(
+ image: 'level-3'.jpgPath,
+ duration: 4,
+ puzzleSize: 3,
+ level: 3,
+ ));
+ _levelList.add(Level(
+ image: 'level-4'.jpgPath,
+ duration: 4,
+ puzzleSize: 3,
+ level: 4,
+ ));
+ _levelList.add(Level(
+ image: 'level-5'.jpgPath,
+ duration: 4,
+ puzzleSize: 3,
+ level: 5,
+ ));
+ _levelList.add(Level(
+ image: 'level-6'.jpgPath,
+ duration: 4,
+ puzzleSize: 3,
+ level: 6,
+ ));
+ _levelList.add(Level(
+ image: 'level-7'.jpgPath,
+ duration: 6,
+ puzzleSize: 4,
+ level: 7,
+ ));
+ _levelList.add(Level(
+ image: 'level-8'.jpgPath,
+ duration: 6,
+ puzzleSize: 4,
+ level: 8,
+ ));
super.initState();
}
@@ -51,7 +90,9 @@ class _LevelListScreenState extends State {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
- padding: EdgeInsets.only(top: context.height * 33 / 540, bottom: context.height * 12 / 540),
+ padding: EdgeInsets.only(
+ top: context.height * 33 / 540,
+ bottom: context.height * 12 / 540),
child: const Text(
'Levels',
style: TextStyle(
@@ -103,6 +144,7 @@ class _LevelListScreenState extends State {
duration: level.duration,
puzzleSize: level.puzzleSize,
image: level.image,
+ level: level.level,
);
},
),
diff --git a/lib/screens/photo/photo_screen.dart b/lib/screens/photo/photo_screen.dart
index ca2e06a..d0226a3 100644
--- a/lib/screens/photo/photo_screen.dart
+++ b/lib/screens/photo/photo_screen.dart
@@ -19,6 +19,7 @@ class PhotoScreen extends ConsumerStatefulWidget {
required this.puzzleSize,
required this.riveController,
required this.duration,
+ required this.level,
Key? key,
}) : super(key: key);
@@ -26,6 +27,7 @@ class PhotoScreen extends ConsumerStatefulWidget {
final PuzzleData initialPuzzleData;
final int duration;
final int puzzleSize;
+ final int level;
final RiveAnimationController riveController;
@override
@@ -50,7 +52,8 @@ class _PhotoScreenState extends ConsumerState {
@override
Widget build(BuildContext context) {
- ref.listen(puzzleNotifierProvider(_solverClient), (previous, PuzzleState next) {
+ ref.listen(puzzleNotifierProvider(_solverClient),
+ (previous, PuzzleState next) {
if (next is PuzzleSolved) {
BlocProvider.of(context).stop();
}
@@ -67,7 +70,8 @@ class _PhotoScreenState extends ConsumerState {
onSecondary: Theme.of(context).colorScheme.onSecondary,
error: Theme.of(context).colorScheme.error,
onError: Theme.of(context).colorScheme.onError,
- background: next.palette.darkMutedColor?.color ?? Palette.blue.darken(0.3),
+ background:
+ next.palette.darkMutedColor?.color ?? Palette.blue.darken(0.3),
onBackground: Colors.white,
surface: Theme.of(context).colorScheme.surface,
onSurface: Theme.of(context).colorScheme.onSurface,
@@ -88,6 +92,7 @@ class _PhotoScreenState extends ConsumerState {
data: _themeData,
child: PhotoScreenLarge(
solverClient: _solverClient,
+ level: widget.level,
initialPuzzleData: _initialPuzzleData,
duration: widget.duration,
puzzleSize: _puzzleSize,
@@ -105,7 +110,8 @@ class _PhotoScreenState extends ConsumerState {
onSecondary: Theme.of(context).colorScheme.onSecondary,
error: Theme.of(context).colorScheme.error,
onError: Theme.of(context).colorScheme.onError,
- background: palette.darkMutedColor?.color ?? Palette.blue.darken(0.3),
+ background:
+ palette.darkMutedColor?.color ?? Palette.blue.darken(0.3),
onBackground: Colors.white,
surface: Theme.of(context).colorScheme.surface,
onSurface: Theme.of(context).colorScheme.onSurface,
@@ -117,6 +123,7 @@ class _PhotoScreenState extends ConsumerState {
solverClient: _solverClient,
initialPuzzleData: _initialPuzzleData,
puzzleSize: _puzzleSize,
+ level: widget.level,
riveController: _riveController,
duration: widget.duration,
),
@@ -128,6 +135,7 @@ class _PhotoScreenState extends ConsumerState {
solverClient: _solverClient,
initialPuzzleData: _initialPuzzleData,
duration: widget.duration,
+ level: widget.level,
puzzleSize: _puzzleSize,
riveController: _riveController,
),
diff --git a/lib/screens/photo/photo_screen_large.dart b/lib/screens/photo/photo_screen_large.dart
index 4dd0a1e..7e2d870 100644
--- a/lib/screens/photo/photo_screen_large.dart
+++ b/lib/screens/photo/photo_screen_large.dart
@@ -1,12 +1,15 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/flutter_svg.dart';
import 'package:my_flutter_puzzle/application/states/image_splitter_state.dart';
import 'package:my_flutter_puzzle/application/states/puzzle_state.dart';
import 'package:my_flutter_puzzle/cubits/count_down_timer_cubit.dart';
import 'package:my_flutter_puzzle/models/puzzle_data.dart';
import 'package:my_flutter_puzzle/providers.dart';
import 'package:my_flutter_puzzle/res/puzzle_constants.dart';
+import 'package:my_flutter_puzzle/utils/extensions/context_extension.dart';
+import 'package:my_flutter_puzzle/utils/extensions/string_extensions.dart';
import 'package:my_flutter_puzzle/utils/puzzle_solver.dart';
import 'package:my_flutter_puzzle/utils/utils.dart';
import 'package:my_flutter_puzzle/widgets/photo_screen/image_viewer.dart';
@@ -25,6 +28,7 @@ class PhotoScreenLarge extends ConsumerStatefulWidget {
required this.puzzleSize,
required this.riveController,
required this.duration,
+ required this.level,
Key? key,
}) : super(key: key);
@@ -32,10 +36,12 @@ class PhotoScreenLarge extends ConsumerStatefulWidget {
final PuzzleData initialPuzzleData;
final int puzzleSize;
final int duration;
+ final int level;
final RiveAnimationController riveController;
@override
- ConsumerState createState() => _SoloScreenLargeState();
+ ConsumerState createState() =>
+ _SoloScreenLargeState();
}
class _SoloScreenLargeState extends ConsumerState {
@@ -65,7 +71,8 @@ class _SoloScreenLargeState extends ConsumerState {
@override
Widget build(BuildContext context) {
- ref.listen(puzzleNotifierProvider(_solverClient), (previous, PuzzleState next) {
+ ref.listen(puzzleNotifierProvider(_solverClient),
+ (previous, PuzzleState next) {
if (next is PuzzleInitializing) {
setState(() {
_isStartPressed = true;
@@ -83,9 +90,11 @@ class _SoloScreenLargeState extends ConsumerState {
_previousImage = next.image;
_previousPalette = next.palette;
});
- ref.read(puzzleNotifierProvider(_solverClient).notifier).initializePuzzle(
- initialPuzzleData: _initialPuzzleData,
- );
+ ref
+ .read(puzzleNotifierProvider(_solverClient).notifier)
+ .initializePuzzle(
+ initialPuzzleData: _initialPuzzleData,
+ );
}
});
@@ -95,101 +104,127 @@ class _SoloScreenLargeState extends ConsumerState {
return true;
},
child: Scaffold(
- backgroundColor: Theme.of(context).colorScheme.background,
+ backgroundColor: const Color(0xff4400CE),
body: SafeArea(
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Padding(
- padding: const EdgeInsetsDirectional.symmetric(horizontal: 10),
- child: Column(
+ child: Padding(
+ padding: EdgeInsets.symmetric(
+ horizontal: context.width * 30 / 812,
+ vertical: context.height * 20 / 375,
+ ),
+ child: Row(
+ children: [
+ Column(
mainAxisAlignment: MainAxisAlignment.center,
- crossAxisAlignment: CrossAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.start,
children: [
- Visibility(
- visible: !_isStartPressed,
- child: ImageViewer(
- puzzleSize: _puzzleSize,
- previousImage: _previousImage,
- previousPalette: _previousPalette,
- imageSize: 200,
- ),
+ Row(
+ children: [
+ SvgPicture.asset('flash'.svgPath),
+ const SizedBox(width: 8),
+ Text(
+ 'Level ${widget.level}',
+ style: const TextStyle(
+ color: Colors.white,
+ fontWeight: FontWeight.bold,
+ fontSize: 16,
+ ),
+ ),
+ const SizedBox(width: 18),
+ GestureDetector(
+ onTap: _resetTimer,
+ child: Container(
+ width: context.width * 22 / 540,
+ height: context.width * 22 / 540,
+ padding: const EdgeInsets.all(5),
+ margin: const EdgeInsets.symmetric(vertical: 3),
+ decoration: const BoxDecoration(
+ color: Colors.white,
+ shape: BoxShape.circle,
+ ),
+ child: SvgPicture.asset('refresh'.svgPath),
+ ),
+ ),
+ ],
),
- const SizedBox(height: 32),
- MovesTilesWidget(solverClient: _solverClient, fontSize: 16),
- const SizedBox(height: 32),
- ],
- ),
- ),
- SingleChildScrollView(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: [
- CountDownTimerWidget(
- duration: widget.duration,
- finishCallback: () {
- if (!_puzzleSolved) {
- Utils.instance.showToast(context, 'TimeOut');
- Future.delayed(const Duration(milliseconds: 1500), () {
- Navigator.pop(context);
- });
- }
- },
+ const SizedBox(height: 21),
+ ImageViewer(
+ puzzleSize: _puzzleSize,
+ previousImage: _previousImage,
+ previousPalette: _previousPalette,
+ imageSize: 200,
),
const SizedBox(height: 12),
- Consumer(
- builder: (context, ref, child) {
- final state = ref.watch(imageSplitterNotifierProvider);
-
- return state.maybeWhen(
- () => PuzzleWidget(
- solverClient: _solverClient,
- boardSize: _boardSize,
- eachBoxSize: _eachBoxSize,
- initialPuzzleData: _initialPuzzleData,
- fontSize: _fontSize,
- images: _previousImages,
- kInitialSpeed: kInitialSpeed,
- ),
- complete: (image, images, palette) {
- _previousImages = images;
- _previousImage = image;
- _previousPalette = palette;
+ MovesTilesWidget(
+ solverClient: _solverClient,
+ fontSize: 16,
+ ),
+ ],
+ ),
+ SizedBox(width: context.width * 60 / 812),
+ SingleChildScrollView(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ children: [
+ CountDownTimerWidget(
+ duration: widget.duration,
+ finishCallback: _finishTime,
+ ),
+ const SizedBox(height: 23),
+ Consumer(
+ builder: (context, ref, child) {
+ final state = ref.watch(
+ imageSplitterNotifierProvider,
+ );
+ return state.maybeWhen(
+ () => PuzzleWidget(
+ solverClient: _solverClient,
+ boardSize: _boardSize,
+ eachBoxSize: _eachBoxSize,
+ initialPuzzleData: _initialPuzzleData,
+ fontSize: _fontSize,
+ images: _previousImages,
+ kInitialSpeed: kInitialSpeed,
+ ),
+ complete: (image, images, palette) {
+ _previousImages = images;
+ _previousImage = image;
+ _previousPalette = palette;
- return PuzzleWidget(
+ return PuzzleWidget(
+ solverClient: _solverClient,
+ boardSize: _boardSize,
+ eachBoxSize: _eachBoxSize,
+ initialPuzzleData: _initialPuzzleData,
+ fontSize: _fontSize,
+ images: images,
+ kInitialSpeed: kInitialSpeed,
+ );
+ },
+ orElse: () => PuzzleWidget(
solverClient: _solverClient,
boardSize: _boardSize,
eachBoxSize: _eachBoxSize,
initialPuzzleData: _initialPuzzleData,
fontSize: _fontSize,
- images: images,
+ images: _previousImages,
kInitialSpeed: kInitialSpeed,
- );
- },
- orElse: () => PuzzleWidget(
- solverClient: _solverClient,
- boardSize: _boardSize,
- eachBoxSize: _eachBoxSize,
- initialPuzzleData: _initialPuzzleData,
- fontSize: _fontSize,
- images: _previousImages,
- kInitialSpeed: kInitialSpeed,
- ),
- );
- },
- ),
- const SizedBox(height: 30),
- ],
+ ),
+ );
+ },
+ ),
+ ],
+ ),
),
- ),
- Padding(
- padding: const EdgeInsetsDirectional.symmetric(horizontal: 10),
- child: Stack(
+ SizedBox(width: context.width * 38 / 812),
+ Stack(
+ alignment: Alignment.center,
children: [
- AnimatedDash(
- boardSize: _boardSize * 0.8,
- riveController: _riveController,
- onInit: (_) => setState(() {}),
+ SizedBox(
+ width: context.width * 126 / 812,
+ height: context.height * 251 / 375,
+ child: Image(
+ image: AssetImage('avatar'.pngPath),
+ ),
),
Column(
mainAxisSize: MainAxisSize.max,
@@ -199,7 +234,8 @@ class _SoloScreenLargeState extends ConsumerState {
CountdownWidget(
isStartPressed: _isStartPressed,
onFinish: () {
- BlocProvider.of(context).start();
+ BlocProvider.of(context)
+ .start();
setState(() {
_isStartPressed = false;
});
@@ -210,11 +246,24 @@ class _SoloScreenLargeState extends ConsumerState {
),
],
),
- ),
- ],
+ ],
+ ),
),
),
),
);
}
+
+ void _finishTime() {
+ if (!_puzzleSolved) {
+ Utils.instance.showToast(context, 'TimeOut');
+ Future.delayed(const Duration(milliseconds: 1500), () {
+ Navigator.pop(context);
+ });
+ }
+ }
+
+ void _resetTimer() {
+ BlocProvider.of(context).reset();
+ }
}
diff --git a/lib/screens/puzzle/puzzle_starter_screen.dart b/lib/screens/puzzle/puzzle_starter_screen.dart
index d8bfd7c..fa45923 100644
--- a/lib/screens/puzzle/puzzle_starter_screen.dart
+++ b/lib/screens/puzzle/puzzle_starter_screen.dart
@@ -11,12 +11,14 @@ class PuzzleStarterScreen extends ConsumerStatefulWidget {
final int puzzleSize;
final String image;
final int duration;
+ final int level;
const PuzzleStarterScreen({
Key? key,
required this.duration,
required this.puzzleSize,
required this.image,
+ required this.level,
}) : super(key: key);
@override
@@ -57,6 +59,7 @@ class _SoloScreenState extends ConsumerState {
child: PhotoScreen(
solverClient: _solverClient,
initialPuzzleData: _initialPuzzleData,
+ level: widget.level,
duration: widget.duration,
puzzleSize: _puzzleSize,
riveController: _riveController,
diff --git a/lib/screens/splash/screen/splash_screen.dart b/lib/screens/splash/screen/splash_screen.dart
index 18f1cdc..577f031 100644
--- a/lib/screens/splash/screen/splash_screen.dart
+++ b/lib/screens/splash/screen/splash_screen.dart
@@ -1,7 +1,6 @@
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';
diff --git a/lib/utils/extensions/string_extensions.dart b/lib/utils/extensions/string_extensions.dart
index 4ed93bc..72f72de 100644
--- a/lib/utils/extensions/string_extensions.dart
+++ b/lib/utils/extensions/string_extensions.dart
@@ -1,6 +1,10 @@
extension StringExtension on String {
String get pngPath {
- return 'assets/images/$this.png';
+ return 'assets/images/png/$this.png';
+ }
+
+ String get jpgPath {
+ return 'assets/images/jpg/$this.jpg';
}
String get rivePath {
diff --git a/lib/utils/image_splitter.dart b/lib/utils/image_splitter.dart
index 225ee8a..475c5c2 100644
--- a/lib/utils/image_splitter.dart
+++ b/lib/utils/image_splitter.dart
@@ -1,23 +1,16 @@
-import 'dart:developer';
-
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:image/image.dart' as image_lib;
import 'package:palette_generator/palette_generator.dart';
-import 'package:tuple/tuple.dart';
class ImageSplitter {
List splitImage(Map mapData) {
List input = mapData['input'];
int size = mapData['size'];
- // convert image to image from image package
image_lib.Image image = image_lib.decodeImage(input)!;
-
int x = 0, y = 0;
int width = (image.width / size).round();
int height = (image.height / size).round();
-
- // split image to parts
List parts = [];
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
@@ -38,7 +31,8 @@ class ImageSplitter {
}
Future getImagePalette(ImageProvider imageProvider) async {
- final paletteGenerator = await PaletteGenerator.fromImageProvider(imageProvider);
+ final paletteGenerator =
+ await PaletteGenerator.fromImageProvider(imageProvider);
return paletteGenerator;
}
diff --git a/lib/utils/puzzle_solver.dart b/lib/utils/puzzle_solver.dart
index 6fbeb9b..fe55522 100644
--- a/lib/utils/puzzle_solver.dart
+++ b/lib/utils/puzzle_solver.dart
@@ -128,14 +128,6 @@ class PuzzleSolverClient {
return board;
}
- void plainPrint(List> b) {
- for (var i in b) {
- for (var j in i) {
- print('$j ');
- }
- }
- }
-
int nodeManhattan(List> board) {
int sum = 0;
int n = board.length;
@@ -153,7 +145,6 @@ class PuzzleSolverClient {
int manhattan(List> board, Set goalNums) {
int sum = 0;
- int count = 0;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (goalNums.contains(board[i][j])) {
@@ -310,7 +301,6 @@ class PuzzleSolverClient {
}
List> goalStates = [];
- int count = 1;
String flag = 'A_STAR';
if (flag == 'A_STAR') {
@@ -330,7 +320,6 @@ class PuzzleSolverClient {
);
queue.add(Tuple2(root.depth + hScaleFactor * root.heuristic, root));
while (queue.isNotEmpty) {
- count += 1;
final node = queue.removeFirst().item2;
if (isGoal(node.board, goalStates[currGoal])) {
queue.clear();
diff --git a/lib/widgets/photo_screen/image_viewer.dart b/lib/widgets/photo_screen/image_viewer.dart
index 7073dba..a5ca769 100644
--- a/lib/widgets/photo_screen/image_viewer.dart
+++ b/lib/widgets/photo_screen/image_viewer.dart
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:my_flutter_puzzle/providers.dart';
+import 'package:my_flutter_puzzle/utils/extensions/context_extension.dart';
import 'package:palette_generator/palette_generator.dart';
class ImageViewer extends ConsumerWidget {
@@ -24,18 +25,17 @@ class ImageViewer extends ConsumerWidget {
final state = ref.watch(imageSplitterNotifierProvider);
return state.maybeWhen(
() => const SizedBox(),
- complete: (image, images, palette) => Column(
- mainAxisSize: MainAxisSize.min,
- children: [
- ClipRRect(
- borderRadius: BorderRadius.circular(20),
- child: Image(
- image: image.image,
- height: imageSize,
- width: imageSize,
- ),
+ complete: (image, images, palette) => SizedBox(
+ width: context.width * 202 / 812,
+ height: context.width * 202 / 812,
+ child: ClipRRect(
+ borderRadius: BorderRadius.circular(8),
+ child: Image(
+ image: image.image,
+ height: imageSize,
+ width: imageSize,
),
- ],
+ ),
),
orElse: () => previousImage != null
? Padding(
diff --git a/lib/widgets/solo_screen/animated_dash.dart b/lib/widgets/solo_screen/animated_dash.dart
index 7415ec5..9a9155c 100644
--- a/lib/widgets/solo_screen/animated_dash.dart
+++ b/lib/widgets/solo_screen/animated_dash.dart
@@ -22,20 +22,7 @@ class AnimatedDash extends StatelessWidget {
Widget build(BuildContext context) {
return Align(
alignment: Alignment.bottomCenter,
- child: Padding(
- padding: _padding,
- // child: SizedBox(
- // width: boardSize * 0.75,
- // height: boardSize * 0.75,
- // child: RiveAnimation.asset(
- // 'assets/rive/dash.riv',
- // fit: BoxFit.contain,
- // antialiasing: true,
- // controllers: [_riveController],
- // onInit: _onInit,
- // ),
- // ),
- ),
+ child: Padding(padding: _padding),
);
}
}
diff --git a/lib/widgets/solo_screen/count_down_timer_widget.dart b/lib/widgets/solo_screen/count_down_timer_widget.dart
index a73e2e7..f443fd8 100644
--- a/lib/widgets/solo_screen/count_down_timer_widget.dart
+++ b/lib/widgets/solo_screen/count_down_timer_widget.dart
@@ -2,8 +2,10 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_svg/flutter_svg.dart';
import 'package:my_flutter_puzzle/cubits/base_cubit_type.dart';
import 'package:my_flutter_puzzle/cubits/count_down_timer_cubit.dart';
+import 'package:my_flutter_puzzle/utils/extensions/string_extensions.dart';
class CountDownTimerWidget extends StatefulWidget {
final int duration;
@@ -41,7 +43,8 @@ class _CountDownTimerWidgetState extends State {
void resetTimer() {
stopTimer();
- setState(() => myDuration = const Duration(days: 5));
+ setState(() => myDuration = Duration(minutes: widget.duration));
+ startTimer();
}
void setCountDown() {
@@ -80,23 +83,25 @@ class _CountDownTimerWidgetState extends State {
_cubit.empty();
});
break;
+ case CountDownTimerState.reset:
+ WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
+ resetTimer();
+ _cubit.empty();
+ });
+ break;
}
return Row(
children: [
Text(
'$hours:$minutes:$seconds',
style: const TextStyle(
- fontSize: 30,
+ fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
const SizedBox(width: 8),
- const Icon(
- Icons.timer,
- color: Colors.white,
- size: 30,
- )
+ SvgPicture.asset('timer'.svgPath),
],
);
},
diff --git a/lib/widgets/solo_screen/countdown_widget.dart b/lib/widgets/solo_screen/countdown_widget.dart
index 37254db..348d31f 100644
--- a/lib/widgets/solo_screen/countdown_widget.dart
+++ b/lib/widgets/solo_screen/countdown_widget.dart
@@ -21,54 +21,51 @@ class CountdownWidget extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
return Visibility(
visible: _isStartPressed,
- child: SizedBox(
- width: 250.0,
- child: DefaultTextStyle(
- style: const TextStyle(
- fontSize: 150.0,
- color: Colors.white,
- fontFamily: 'GoogleSans',
- ),
- child: AnimatedTextKit(
- isRepeatingAnimation: false,
- pause: const Duration(milliseconds: 0),
- onFinished: _onFinish,
- animatedTexts: [
- RotateAnimatedText(
- '3',
- transitionHeight: 100 * 2.5,
- textStyle: const TextStyle(
- color: Colors.white,
- ),
- duration: Duration(milliseconds: _kInitialSpeed),
+ child: DefaultTextStyle(
+ style: const TextStyle(
+ fontSize: 80,
+ color: Colors.white,
+ fontFamily: 'GoogleSans',
+ ),
+ child: AnimatedTextKit(
+ isRepeatingAnimation: false,
+ pause: const Duration(milliseconds: 0),
+ onFinished: _onFinish,
+ animatedTexts: [
+ RotateAnimatedText(
+ '3',
+ transitionHeight: 100 * 2.5,
+ textStyle: const TextStyle(
+ color: Colors.white,
),
- RotateAnimatedText(
- '2',
- transitionHeight: 100 * 2.5,
- textStyle: const TextStyle(
- color: Colors.white,
- ),
- duration: Duration(milliseconds: _kInitialSpeed),
+ duration: Duration(milliseconds: _kInitialSpeed),
+ ),
+ RotateAnimatedText(
+ '2',
+ transitionHeight: 100 * 2.5,
+ textStyle: const TextStyle(
+ color: Colors.white,
),
- RotateAnimatedText(
- '1',
- transitionHeight: 100 * 2.5,
- textStyle: const TextStyle(
- color: Colors.white,
- ),
- duration: Duration(milliseconds: _kInitialSpeed),
+ duration: Duration(milliseconds: _kInitialSpeed),
+ ),
+ RotateAnimatedText(
+ '1',
+ transitionHeight: 100 * 2.5,
+ textStyle: const TextStyle(
+ color: Colors.white,
),
- RotateAnimatedText(
- 'GO!',
- textStyle: const TextStyle(
- fontSize: 120.0,
- color: Colors.white,
- ),
- transitionHeight: 120 * 2.5,
- duration: Duration(milliseconds: _kInitialSpeed),
+ duration: Duration(milliseconds: _kInitialSpeed),
+ ),
+ RotateAnimatedText(
+ 'GO!',
+ textStyle: const TextStyle(
+ fontSize: 60,
+ color: Colors.white,
),
- ],
- ),
+ transitionHeight: 120 * 2.5,
+ duration: Duration(milliseconds: _kInitialSpeed),
+ ),
+ ],
),
),
);
diff --git a/lib/widgets/solo_screen/moves_tiles_widget.dart b/lib/widgets/solo_screen/moves_tiles_widget.dart
index 18278b9..150b752 100644
--- a/lib/widgets/solo_screen/moves_tiles_widget.dart
+++ b/lib/widgets/solo_screen/moves_tiles_widget.dart
@@ -2,8 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:my_flutter_puzzle/providers.dart';
import 'package:my_flutter_puzzle/utils/puzzle_solver.dart';
-
-import 'moves_tiles_widget/moves_tiles_text.dart';
+import 'package:my_flutter_puzzle/widgets/solo_screen/moves_tiles_widget/moves_tiles_text.dart';
class MovesTilesWidget extends StatelessWidget {
const MovesTilesWidget({
@@ -21,7 +20,6 @@ class MovesTilesWidget extends StatelessWidget {
return Consumer(
builder: (context, ref, child) {
final state = ref.watch(puzzleNotifierProvider(_solverClient));
-
return state.when(
() => MovesTilesText(
moves: 0,
diff --git a/lib/widgets/solo_screen/moves_tiles_widget/moves_tiles_text.dart b/lib/widgets/solo_screen/moves_tiles_widget/moves_tiles_text.dart
index f0fee5f..9650642 100644
--- a/lib/widgets/solo_screen/moves_tiles_widget/moves_tiles_text.dart
+++ b/lib/widgets/solo_screen/moves_tiles_widget/moves_tiles_text.dart
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
+import 'package:my_flutter_puzzle/utils/extensions/context_extension.dart';
class MovesTilesText extends StatelessWidget {
final int moves;
@@ -14,30 +15,86 @@ class MovesTilesText extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return RichText(
- text: TextSpan(
- style: TextStyle(
- fontSize: fontSize,
- // fontWeight: FontWeight.w500,
- color: Colors.white,
- ),
- children: [
- TextSpan(
- text: moves.toString(),
- style: const TextStyle(
- fontWeight: FontWeight.w600,
+ return Row(
+ children: [
+ Container(
+ height: context.height * 32 / 375,
+ width: context.width * 94 / 812,
+ padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
+ decoration: BoxDecoration(
+ border: Border.all(color: const Color(0xff6236FF), width: 1),
+ borderRadius: BorderRadius.circular(26),
+ gradient: const LinearGradient(
+ colors: [
+ Color(0xff4824CB),
+ Color(0xff6236FF),
+ ],
+ begin: Alignment.topCenter,
+ end: Alignment.bottomCenter,
),
),
- const TextSpan(text: ' Moves | '),
- TextSpan(
- text: tiles.toString(),
- style: const TextStyle(
- fontWeight: FontWeight.w600,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ const Text(
+ 'Tiles',
+ style: TextStyle(
+ color: Colors.white,
+ fontWeight: FontWeight.bold,
+ fontSize: 12,
+ ),
+ ),
+ Text(
+ '$tiles',
+ style: const TextStyle(
+ color: Colors.white,
+ fontWeight: FontWeight.bold,
+ fontSize: 12,
+ ),
+ ),
+ ],
+ ),
+ ),
+ const SizedBox(width: 12),
+ Container(
+ height: context.height * 32 / 375,
+ width: context.width * 94 / 812,
+ padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
+ decoration: BoxDecoration(
+ border: Border.all(color: const Color(0xff6236FF), width: 1),
+ borderRadius: BorderRadius.circular(26),
+ gradient: const LinearGradient(
+ colors: [
+ Color(0xff4824CB),
+ Color(0xff6236FF),
+ ],
+ begin: Alignment.topCenter,
+ end: Alignment.bottomCenter,
),
),
- const TextSpan(text: ' Tiles'),
- ],
- ),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ const Text(
+ 'Move',
+ style: TextStyle(
+ color: Colors.white,
+ fontWeight: FontWeight.bold,
+ fontSize: 12,
+ ),
+ ),
+ Text(
+ '$moves',
+ style: const TextStyle(
+ color: Colors.white,
+ fontWeight: FontWeight.bold,
+ fontSize: 12,
+ ),
+ ),
+ ],
+ ),
+ ),
+ ],
);
}
}
diff --git a/lib/widgets/solo_screen/puzzle_widget/puzzle_board.dart b/lib/widgets/solo_screen/puzzle_widget/puzzle_board.dart
index 08b5433..daa48c1 100644
--- a/lib/widgets/solo_screen/puzzle_widget/puzzle_board.dart
+++ b/lib/widgets/solo_screen/puzzle_widget/puzzle_board.dart
@@ -59,7 +59,7 @@ class PuzzleBoard extends ConsumerWidget {
elevation: 4,
color: Theme.of(context).colorScheme.primary.withOpacity(isEnabled ? 1 : 0.5),
shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(10),
+ borderRadius: BorderRadius.circular(8),
),
child: SizedBox(
height: eachBoxSize,
@@ -82,7 +82,7 @@ class PuzzleBoard extends ConsumerWidget {
child: Opacity(
opacity: isEnabled ? 1 : 0.5,
child: ClipRRect(
- borderRadius: BorderRadius.circular(10),
+ borderRadius: BorderRadius.circular(8),
child:
images![int.parse(puzzleData.offsetMap.entries.toList()[i].key.toString()) - 1],
),
diff --git a/pubspec.yaml b/pubspec.yaml
index fdf443e..58e72a0 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -36,6 +36,8 @@ flutter:
assets:
- assets/rive/dash.riv
- assets/images/
+ - assets/images/jpg/
+ - assets/images/png/
- assets/images/svg/
fonts:
- family: GoogleSans
diff --git a/test/my_queue_test.dart b/test/my_queue_test.dart
deleted file mode 100644
index 30fae35..0000000
--- a/test/my_queue_test.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-import 'package:flutter_test/flutter_test.dart';
-import 'package:freezed_annotation/freezed_annotation.dart';
-import 'package:tuple/tuple.dart';
-
-void main() {
- test('queue test', () {
- final queue = HeapPriorityQueue>((a, b) => a.item1.compareTo(b.item1));
- queue.add(const Tuple2(5, 515));
- queue.add(const Tuple2(3, 245));
- queue.add(const Tuple2(8, 645));
- queue.add(const Tuple2(2, 345));
- });
-}
diff --git a/test/puzzle_solver_test.dart b/test/puzzle_solver_test.dart
deleted file mode 100644
index 725a5c3..0000000
--- a/test/puzzle_solver_test.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-import 'package:flutter_test/flutter_test.dart';
-import 'package:my_flutter_puzzle/utils/puzzle_solver.dart';
-
-void main() {
- test('solver logic test', () {
- final solver = PuzzleSolverClient(size: 4);
- final board = solver.createRandomBoard();
-
- final boardStates = solver.runner(board);
- if (boardStates != null) {
- for (var board in boardStates) {
- print(board);
- }
- }
- });
-}
diff --git a/test/widget_test.dart b/test/widget_test.dart
deleted file mode 100644
index 2b89594..0000000
--- a/test/widget_test.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-// This is a basic Flutter widget test.
-//
-// To perform an interaction with a widget in your test, use the WidgetTester
-// utility that Flutter provides. For example, you can send tap and scroll
-// gestures. You can also use WidgetTester to find child widgets in the widget
-// tree, read text, and verify that the values of widget properties are correct.
-
-import 'package:flutter/material.dart';
-import 'package:flutter_test/flutter_test.dart';
-import 'package:my_flutter_puzzle/main.dart';
-
-void main() {
- testWidgets('Counter increments smoke test', (WidgetTester tester) async {
- // Build our app and trigger a frame.
- await tester.pumpWidget(const MyApp());
-
- // Verify that our counter starts at 0.
- expect(find.text('0'), findsOneWidget);
- expect(find.text('1'), findsNothing);
-
- // Tap the '+' icon and trigger a frame.
- await tester.tap(find.byIcon(Icons.add));
- await tester.pump();
-
- // Verify that our counter has incremented.
- expect(find.text('0'), findsNothing);
- expect(find.text('1'), findsOneWidget);
- });
-}