diff --git a/assets/images/map_background.png b/assets/images/map_background.png
index e033ac9..3bb3c65 100644
Binary files a/assets/images/map_background.png and b/assets/images/map_background.png differ
diff --git a/assets/images/planet_1.png b/assets/images/planet_1.png
new file mode 100644
index 0000000..640194f
Binary files /dev/null and b/assets/images/planet_1.png differ
diff --git a/assets/images/planet_10.png b/assets/images/planet_10.png
new file mode 100644
index 0000000..1fa1a68
Binary files /dev/null and b/assets/images/planet_10.png differ
diff --git a/assets/images/planet_2.png b/assets/images/planet_2.png
new file mode 100644
index 0000000..8081d99
Binary files /dev/null and b/assets/images/planet_2.png differ
diff --git a/assets/images/planet_3.png b/assets/images/planet_3.png
new file mode 100644
index 0000000..6a01dd5
Binary files /dev/null and b/assets/images/planet_3.png differ
diff --git a/assets/images/planet_4.png b/assets/images/planet_4.png
new file mode 100644
index 0000000..b5dfb04
Binary files /dev/null and b/assets/images/planet_4.png differ
diff --git a/assets/images/planet_5.png b/assets/images/planet_5.png
new file mode 100644
index 0000000..6dbb435
Binary files /dev/null and b/assets/images/planet_5.png differ
diff --git a/assets/images/planet_6.png b/assets/images/planet_6.png
new file mode 100644
index 0000000..c6c6130
Binary files /dev/null and b/assets/images/planet_6.png differ
diff --git a/assets/images/planet_7.png b/assets/images/planet_7.png
new file mode 100644
index 0000000..dfca92e
Binary files /dev/null and b/assets/images/planet_7.png differ
diff --git a/assets/images/planet_8.png b/assets/images/planet_8.png
new file mode 100644
index 0000000..ba311cd
Binary files /dev/null and b/assets/images/planet_8.png differ
diff --git a/assets/images/planet_9.png b/assets/images/planet_9.png
new file mode 100644
index 0000000..42f2e35
Binary files /dev/null and b/assets/images/planet_9.png differ
diff --git a/assets/images/planet_final.png b/assets/images/planet_final.png
new file mode 100644
index 0000000..4a71f0b
Binary files /dev/null and b/assets/images/planet_final.png differ
diff --git a/assets/images/satellite.png b/assets/images/satellite.png
new file mode 100644
index 0000000..25bd9e4
Binary files /dev/null and b/assets/images/satellite.png differ
diff --git a/assets/svg/diamond_container.svg b/assets/svg/diamond_container.svg
new file mode 100644
index 0000000..ef874cf
--- /dev/null
+++ b/assets/svg/diamond_container.svg
@@ -0,0 +1,116 @@
+
diff --git a/assets/svg/home_button.svg b/assets/svg/home_button.svg
new file mode 100644
index 0000000..5b293a6
--- /dev/null
+++ b/assets/svg/home_button.svg
@@ -0,0 +1,156 @@
+
diff --git a/assets/svg/icon_play.svg b/assets/svg/icon_play.svg
new file mode 100644
index 0000000..8058889
--- /dev/null
+++ b/assets/svg/icon_play.svg
@@ -0,0 +1,30 @@
+
diff --git a/lib/common_ui/resources/my_assets.dart b/lib/common_ui/resources/my_assets.dart
index 3e88f68..cc9809d 100644
--- a/lib/common_ui/resources/my_assets.dart
+++ b/lib/common_ui/resources/my_assets.dart
@@ -14,7 +14,6 @@ class MyAssets {
static const String level = 'assets/images/level.png';
static const String finishedLevel = 'assets/images/finished_level.png';
static const String currentLevel = 'assets/images/current_level.png';
- static const String homeButton = 'assets/images/home_button.png';
static const String error = 'assets/images/error.png';
static const String leaf = 'assets/images/leaf.png';
static const String happyPersons = 'assets/images/happy_persons.png';
@@ -27,6 +26,18 @@ class MyAssets {
static const String intro_3 = 'assets/images/intro_3.jpg';
static const String intro_4 = 'assets/images/intro_4.jpg';
static const String intro_5 = 'assets/images/intro_5.jpg';
+ static const String planet1 = 'assets/images/planet_1.png';
+ static const String planet2 = 'assets/images/planet_2.png';
+ static const String planet3 = 'assets/images/planet_3.png';
+ static const String planet4 = 'assets/images/planet_4.png';
+ static const String planet5 = 'assets/images/planet_5.png';
+ static const String planet6 = 'assets/images/planet_6.png';
+ static const String planet7 = 'assets/images/planet_7.png';
+ static const String planet8 = 'assets/images/planet_8.png';
+ static const String planet9 = 'assets/images/planet_9.png';
+ static const String planet10 = 'assets/images/planet_10.png';
+ static const String satellite = 'assets/images/satellite.png';
+ static const String planetFinal = 'assets/images/planet_final.png';
/// SVG
static const String closeBtn = 'assets/svg/close_btn.svg';
@@ -58,6 +69,9 @@ class MyAssets {
static const String lang = 'assets/svg/lang.svg';
static const String unMusic = 'assets/svg/unmusic.svg';
static const String globe = 'assets/svg/globe.svg';
+ static const String homeButton = 'assets/svg/home_button.svg';
+ static const String diamondContainer = 'assets/svg/diamond_container.svg';
+ static const String iconPlay = 'assets/svg/icon_play.svg';
static final List images = [
@@ -71,7 +85,6 @@ class MyAssets {
level,
finishedLevel,
currentLevel,
- homeButton,
error,
leaf,
happyPersons,
diff --git a/lib/common_ui/resources/my_audios.dart b/lib/common_ui/resources/my_audios.dart
index e499c25..854205d 100644
--- a/lib/common_ui/resources/my_audios.dart
+++ b/lib/common_ui/resources/my_audios.dart
@@ -5,4 +5,5 @@ class MyAudios {
static const String homeMusic = 'assets/audios/home.mp3';
static const String clickButton = 'assets/audios/click_button.mp3';
+ static const String back = 'assets/audios/back.mp3';
}
\ No newline at end of file
diff --git a/lib/core/routers/my_routes.dart b/lib/core/routers/my_routes.dart
index 900366f..a33b00f 100644
--- a/lib/core/routers/my_routes.dart
+++ b/lib/core/routers/my_routes.dart
@@ -110,6 +110,7 @@ GoRouter get appPages => GoRouter(
LevelBloc(
locator(),
locator(instanceName: MyConstants.mainAudioService),
+ locator(instanceName: MyConstants.effectAudioService),
)..add(SetCurrentLevelEvent()),
child: const LevelPage(),
),
diff --git a/lib/core/widgets/inkwell/my_inkwell.dart b/lib/core/widgets/inkwell/my_inkwell.dart
index 2967c7d..9901be7 100644
--- a/lib/core/widgets/inkwell/my_inkwell.dart
+++ b/lib/core/widgets/inkwell/my_inkwell.dart
@@ -12,6 +12,7 @@ class MyInkwell extends StatefulWidget {
this.borderRadius,
this.highlightColor,
this.splashColor,
+ this.audio,
});
final VoidCallback? onTap;
@@ -19,6 +20,7 @@ class MyInkwell extends StatefulWidget {
final BorderRadius? borderRadius;
final Color? highlightColor;
final Color? splashColor;
+ final String? audio;
@override
State createState() => _MyInkwellState();
@@ -35,7 +37,7 @@ class _MyInkwellState extends State {
}
void playAudio() {
- audioService.setAudio(assetPath: MyAudios.clickButton);
+ audioService.setAudio(assetPath: widget.audio ?? MyAudios.clickButton);
audioService.play();
}
diff --git a/lib/features/level/presentation/bloc/level_bloc.dart b/lib/features/level/presentation/bloc/level_bloc.dart
index b72a7f6..ac39a9b 100644
--- a/lib/features/level/presentation/bloc/level_bloc.dart
+++ b/lib/features/level/presentation/bloc/level_bloc.dart
@@ -9,6 +9,7 @@ import 'package:hadi_hoda_flutter/core/routers/my_routes.dart';
import 'package:hadi_hoda_flutter/core/services/audio_service.dart';
import 'package:hadi_hoda_flutter/core/status/base_status.dart';
import 'package:hadi_hoda_flutter/core/utils/local_storage.dart';
+import 'package:hadi_hoda_flutter/core/utils/screen_size.dart';
import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart';
import 'package:hadi_hoda_flutter/features/level/domain/entity/level_location.dart';
import 'package:hadi_hoda_flutter/features/level/domain/usecases/get_levels_usecase.dart';
@@ -20,9 +21,10 @@ class LevelBloc extends Bloc {
/// ------------constructor------------
LevelBloc(
this._getLeveslUseCase,
- this._audioService,
+ this._mainAudioService,
+ this._effectAudioService,
) : super(const LevelState()) {
- volumeStream = _audioService.volumeStream();
+ volumeStream = _mainAudioService.volumeStream();
on(_getLevelListEvent);
on(_setCurrentLevelEvent);
on(_startScrollEvent);
@@ -39,34 +41,35 @@ class LevelBloc extends Bloc {
final GetLevelsUseCase _getLeveslUseCase;
/// ------------Variables------------
- final List bottomLocationList = [
- LevelLocation(bottom: -20, left: 30, index: 1),
- LevelLocation(bottom: 50, left: 100, index: 2),
- LevelLocation(bottom: 150, left: 60, index: 3),
- LevelLocation(bottom: 210, left: 110, index: 4),
- LevelLocation(bottom: 260, right: 70, index: 5),
- LevelLocation(top: 170, right: 40, index: 6),
- LevelLocation(top: 70, right: 70, index: 7),
- LevelLocation(top: -20, right: 70, index: 8),
+ final List locationList = [
+ LevelLocation(bottom: 0.13.h, left: 0.2.w, index: 0),
+ LevelLocation(bottom: 0.25.h, left: 0.43.w, index: 1),
+ LevelLocation(bottom: 0.35.h, left: 0.22.w, index: 2),
+ LevelLocation(bottom: 0.5.h, left: 0.35.w, index: 3),
+ LevelLocation(bottom: 0.57.h, left: 0.6.w, index: 4),
+ LevelLocation(bottom: 0.65.h, left: 0.8.w, index: 5),
+ LevelLocation(bottom: 0.8.h, left: 0.82.w, index: 6),
+ LevelLocation(bottom: 1.0.h, left: 0.76.w, index: 7),
+ LevelLocation(bottom: 1.15.h, left: 0.6.w, index: 8),
+ LevelLocation(bottom: 1.2.h, left: 0.3.w, index: 9),
+ LevelLocation(bottom: 1.3.h, left: 0.07.w, index: 10),
+ LevelLocation(bottom: 1.38.h, left: 0.3.w, index: 11),
+ LevelLocation(bottom: 1.44.h, left: 0.55.w, index: 12),
+ LevelLocation(bottom: 1.54.h, left: 0.68.w, index: 13),
+ LevelLocation(bottom: 1.63.h, left: 0.6.w, index: 14),
+ LevelLocation(bottom: 1.75.h, left: 0.63.w, index: 15),
+ LevelLocation(bottom: 1.84.h, left: 0.43.w, index: 16),
+ LevelLocation(bottom: 1.82.h, left: 0.17.w, index: 17),
+ LevelLocation(bottom: 1.96.h, left: 0.05.w, index: 18),
+ LevelLocation(bottom: 2.08.h, left: 0.1.w, index: 19),
+ LevelLocation(bottom: 2.14.h, left: 0.3.w, index: 20),
+ LevelLocation(bottom: 2.24.h, left: 0.35.w, index: 21),
+ LevelLocation(bottom: 2.35.h, left: 0.2.w, index: 22),
+ LevelLocation(bottom: 2.44.h, left: 0.14.w, index: 23),
+ LevelLocation(bottom: 2.55.h, left: 0.28.w, index: 24),
];
- final List topLocationList = [
- LevelLocation(bottom: 30, right: 80, index: 9),
- LevelLocation(bottom: 70, left: 20, index: 10),
- LevelLocation(bottom: 150, left: 50, index: 11),
- LevelLocation(bottom: 180, left: 140, index: 12),
- LevelLocation(bottom: 260, right: 20, index: 13),
- LevelLocation(bottom: 370, right: 30, index: 14),
- LevelLocation(bottom: 420, left: 40, index: 15),
- LevelLocation(top: 410, left: 0, index: 16),
- LevelLocation(top: 320, left: 60, index: 17),
- LevelLocation(top: 220, left: 80, index: 18),
- LevelLocation(top: 130, left: 20, index: 19),
- LevelLocation(top: 50, left: 70, index: 20),
- ];
-
- final List bottom8LevelList = [];
- final List top12LevelList = [];
+ final List levelList = [];
late final Stream volumeStream;
@@ -74,7 +77,8 @@ class LevelBloc extends Bloc {
/// ------------Controllers------------
final ScrollController scrollController = ScrollController();
- final AudioService _audioService;
+ final AudioService _mainAudioService;
+ final AudioService _effectAudioService;
/// ------------Functions------------
void goToQuestionPage(BuildContext context, LevelEntity level){
@@ -105,7 +109,10 @@ class LevelBloc extends Bloc {
}
Future changeMute() async {
- await _audioService.changeMute();
+ await Future.wait([
+ _mainAudioService.changeMute(),
+ _effectAudioService.changeMute(),
+ ]);
}
/// ------------Api Calls------------
@@ -117,10 +124,7 @@ class LevelBloc extends Bloc {
await _getLeveslUseCase(LevelParams()).then((value) {
value.fold(
(data) async {
- bottom8LevelList.addAll(data.take(8));
- if(data.length > 8){
- top12LevelList.addAll(data.sublist(8, data.length));
- }
+ levelList.addAll(data);
try {
emit(state.copyWith(
getLevelStatus: const BaseComplete(''),
diff --git a/lib/features/level/presentation/ui/level_page.dart b/lib/features/level/presentation/ui/level_page.dart
index f0500ed..a1d89ed 100644
--- a/lib/features/level/presentation/ui/level_page.dart
+++ b/lib/features/level/presentation/ui/level_page.dart
@@ -1,25 +1,31 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart';
+import 'package:hadi_hoda_flutter/common_ui/resources/my_audios.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart';
import 'package:hadi_hoda_flutter/core/utils/screen_size.dart';
+import 'package:hadi_hoda_flutter/core/utils/set_platform_size.dart';
import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart';
+import 'package:hadi_hoda_flutter/core/widgets/inkwell/my_inkwell.dart';
import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart';
import 'package:hadi_hoda_flutter/features/level/presentation/bloc/level_bloc.dart';
import 'package:hadi_hoda_flutter/features/level/presentation/bloc/level_event.dart';
import 'package:hadi_hoda_flutter/features/level/presentation/bloc/level_state.dart';
-import 'package:hadi_hoda_flutter/features/level/presentation/ui/widgets/bottom_path.dart';
-import 'package:hadi_hoda_flutter/features/level/presentation/ui/widgets/hint_level_widget.dart';
+import 'package:hadi_hoda_flutter/features/level/presentation/ui/widgets/diamond_level.dart';
+import 'package:hadi_hoda_flutter/features/level/presentation/ui/widgets/level_path.dart';
import 'package:hadi_hoda_flutter/features/level/presentation/ui/widgets/level_widget.dart';
-import 'package:hadi_hoda_flutter/features/level/presentation/ui/widgets/top_path.dart';
+import 'package:hadi_hoda_flutter/features/level/presentation/ui/widgets/play_button.dart';
class LevelPage extends StatelessWidget {
- const LevelPage({super.key});
+ const LevelPage({super.key});
+
+
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
+ alignment: Alignment.center,
children: [
SingleChildScrollView(
controller: context.read().scrollController,
@@ -28,62 +34,176 @@ class LevelPage extends StatelessWidget {
alignment: Alignment.center,
children: [
_background(),
- _topPath(context),
- _bottomPath(context),
+ _path(context),
+ _levelLocation(context),
+ _planets(context),
],
),
),
_topButtons(context),
- _hintMission(context)
+ _playButton(context)
],
),
);
}
- Widget _hintMission(BuildContext context) {
- return BlocBuilder(
- buildWhen: (previous, current) =>
- previous.chooseLevel?.id != current.chooseLevel?.id,
- builder: (context, state) {
- if (state.chooseLevel?.id != null) {
- return Positioned(
- bottom: MediaQuery.viewPaddingOf(context).bottom + MySpaces.s10,
- right: MySpaces.s16,
- left: MySpaces.s16,
- child: HintLevelWidget(
- level: state.chooseLevel ?? LevelEntity(),
- onTap: (level) =>
- context.read().goToQuestionPage(context, level),
- ),
- );
- } else {
- return SizedBox.shrink();
- }
- }
+ Positioned _planets(BuildContext context) {
+ return Positioned.fill(
+ child: Stack(
+ alignment: Alignment.center,
+ children: [
+ Positioned(
+ bottom: 0.3.h,
+ right: setSize(context: context, mobile: -40, tablet: -80),
+ child: MyImage(
+ image: MyAssets.planet1,
+ size: setSize(context: context, mobile: 180),
+ ),
+ ),
+ Positioned(
+ bottom: setSize(context: context, mobile: 0.65.h, tablet: 0.9.h),
+ child: MyImage(
+ image: MyAssets.planet2,
+ size: setSize(context: context, mobile: 110),
+ ),
+ ),
+ Positioned(
+ bottom: setSize(context: context, mobile: 0.8.h, tablet: 1.15.h),
+ left: setSize(context: context, mobile: -120, tablet: -200),
+ child: MyImage(
+ image: MyAssets.planet3,
+ size: setSize(context: context, mobile: 300),
+ ),
+ ),
+ Positioned(
+ bottom: setSize(context: context, mobile: 1.3.h, tablet: 1.75.h),
+ right: 40,
+ child: MyImage(
+ image: MyAssets.planet4,
+ size: setSize(context: context, mobile: 120),
+ ),
+ ),
+ Positioned(
+ bottom: setSize(context: context, mobile: 1.5.h, tablet: 2.0.h),
+ left: setSize(context: context, mobile: -130, tablet: -220),
+ child: MyImage(
+ image: MyAssets.planet5,
+ size: setSize(context: context, mobile: 300),
+ ),
+ ),
+ Positioned(
+ bottom: setSize(context: context, mobile: 1.85.h, tablet: 2.55.h),
+ right: setSize(context: context, mobile: 20, tablet: 20),
+ child: MyImage(
+ image: MyAssets.planet6,
+ size: setSize(context: context, mobile: 80),
+ ),
+ ),
+ Positioned(
+ bottom: setSize(context: context, mobile: 1.95.h, tablet: 2.6.h),
+ child: MyImage(
+ image: MyAssets.planet7,
+ size: setSize(context: context, mobile: 120),
+ ),
+ ),
+ Positioned(
+ bottom: setSize(context: context, mobile: 2.1.h, tablet: 2.8.h),
+ right: setSize(context: context, mobile: -50, tablet: -120),
+ child: MyImage(
+ image: MyAssets.planet8,
+ size: setSize(context: context, mobile: 250),
+ ),
+ ),
+ Positioned(
+ bottom: setSize(context: context, mobile: 2.3.h, tablet: 3.1.h),
+ left: -20,
+ child: MyImage(
+ image: MyAssets.planet9,
+ size: setSize(context: context, mobile: 100),
+ ),
+ ),
+ Positioned(
+ bottom: setSize(context: context, mobile: 2.5.h, tablet: 3.4.h),
+ child: MyImage(
+ image: MyAssets.planet10,
+ size: setSize(context: context, mobile: 60),
+ ),
+ ),
+ Positioned(
+ bottom: setSize(context: context, mobile: 2.55.h, tablet: 3.45.h),
+ right: 20,
+ child: MyImage(
+ image: MyAssets.satellite,
+ size: setSize(context: context, mobile: 80),
+ ),
+ ),
+ Positioned(
+ bottom: setSize(context: context, mobile: 2.6.h, tablet: 3.5.h),
+ left: setSize(context: context, mobile: 40),
+ child: MyImage(
+ image: MyAssets.planetFinal,
+ size: setSize(context: context, mobile: 300),
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+
+ Positioned _path(BuildContext context) {
+ return Positioned.fill(
+ top: setSize(context: context, mobile: 0.3.h, tablet: 0.37.h),
+ bottom: setSize(context: context, mobile: 0.15.h, tablet: 200),
+ left: MySpaces.s30,
+ right: MySpaces.s30,
+ child: LevelPath(
+ width: setSize(context: context, tablet: 0.45.w, mobile: 0.9.w) ?? 0,
+ height: setSize(context: context, tablet: 1.75.h, mobile: 2.55.h) ?? 0,
+ ),
);
}
+ Widget _playButton(BuildContext context) {
+ return BlocBuilder(
+ buildWhen: (previous, current) =>
+ previous.chooseLevel?.id != current.chooseLevel?.id,
+ builder: (context, state) {
+ return Positioned(
+ bottom: MySpaces.s20,
+ child: PlayButton(
+ level: state.chooseLevel ?? LevelEntity(),
+ onTap: (level) =>
+ context.read().goToQuestionPage(context, level),
+ ),
+ );
+ }
+ );
+ }
+
Positioned _topButtons(BuildContext context) {
return Positioned(
left: MySpaces.s16,
right: MySpaces.s16,
- top: MediaQuery.viewPaddingOf(context).top + MySpaces.s16,
+ top: MySpaces.s20,
child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ spacing: MySpaces.s16,
children: [
- InkWell(
+ MyInkwell(
onTap: () => context.read().goToHomePage(context),
+ audio: MyAudios.back,
child: MyImage(
image: MyAssets.homeButton,
),
),
+ Spacer(),
+ DiamondLevel(),
StreamBuilder(
initialData: 1,
stream: context.read().volumeStream,
- builder: (context, snapshot) => InkWell(
+ builder: (context, snapshot) => MyInkwell(
onTap: () => context.read().changeMute(),
child: MyImage(
- image: snapshot.data == 1 ? MyAssets.musicOn : MyAssets.musicOff,
+ image: snapshot.data == 0 ? MyAssets.musicOff : MyAssets.musicOn,
),
),
),
@@ -92,75 +212,44 @@ class LevelPage extends StatelessWidget {
);
}
- MyImage _background() {
- return MyImage(image: MyAssets.mapBackground, fit: BoxFit.cover);
- }
-
- Positioned _topPath(BuildContext context) {
- return Positioned(
- top: context.heightScreen * 0.16,
- left: context.widthScreen * 0.15,
- child: BlocBuilder(
- builder: (context, state) => Stack(
- children: [
- TopPath(
- height: 950,
- width: context.widthScreen * 0.6,
- ),
- ...List.generate(
- context.read().top12LevelList.length,
- (index) => Positioned(
- top: context.read().topLocationList[index].top,
- bottom: context.read().topLocationList[index].bottom,
- right: context.read().topLocationList[index].right,
- left: context.read().topLocationList[index].left,
- child: BlocBuilder(
- builder: (context, state) => LevelWidget(
- chooseLevel: state.chooseLevel,
- level: context.read().top12LevelList[index],
- type: context.read().getLevelType(index + 9),
- onTap: (LevelEntity level, LevelType type) {
- context.read().add(ChooseLevelEvent(level, type));
- },
- ),
- ),
- ),
- ),
- ],
+ Widget _background() {
+ return Stack(
+ children: [
+ MyImage(
+ image: MyAssets.mapBackground,
+ fit: BoxFit.cover,
),
- ),
+ ],
);
}
- Positioned _bottomPath(BuildContext context) {
- return Positioned(
- bottom: context.heightScreen * 0.18,
- left: context.widthScreen * 0.2,
- child: BlocBuilder(
- builder: (context, state) => Stack(
- clipBehavior: Clip.none,
+ Widget _levelLocation(BuildContext context) {
+ return BlocBuilder(
+ builder: (context, state) => Positioned.fill(
+ child: Stack(
children: [
- BottomPath(),
...List.generate(
- context.read().bottom8LevelList.length,
- (index) => Positioned(
- top: context.read().bottomLocationList[index].top,
- bottom: context.read().bottomLocationList[index].bottom,
- right: context.read().bottomLocationList[index].right,
- left: context.read().bottomLocationList[index].left,
- child: BlocBuilder(
- buildWhen: (previous, current) =>
+ context.read().levelList.length,
+ (index) => Positioned(
+ top: context.read().locationList[index].top,
+ bottom: context.read().locationList[index].bottom,
+ right: context.read().locationList[index].right,
+ left: context.read().locationList[index].left,
+ child: BlocBuilder(
+ buildWhen: (previous, current) =>
previous.chooseLevel?.id != current.chooseLevel?.id,
- builder: (context, state) => LevelWidget(
- chooseLevel: state.chooseLevel,
- level: context.read().bottom8LevelList[index],
- type: context.read().getLevelType(index + 1),
- onTap: (LevelEntity level, LevelType type) {
- context.read().add(ChooseLevelEvent(level, type));
- },
- ),
- ),
+ builder: (context, state) => LevelWidget(
+ chooseLevel: state.chooseLevel,
+ level: context.read().levelList[index],
+ type: context.read().getLevelType(index + 1),
+ onTap: (LevelEntity level, LevelType type) {
+ context.read().add(
+ ChooseLevelEvent(level, type),
+ );
+ },
),
+ ),
+ ),
),
],
),
diff --git a/lib/features/level/presentation/ui/widgets/diamond_level.dart b/lib/features/level/presentation/ui/widgets/diamond_level.dart
new file mode 100644
index 0000000..28cb1b6
--- /dev/null
+++ b/lib/features/level/presentation/ui/widgets/diamond_level.dart
@@ -0,0 +1,50 @@
+import 'package:flutter/material.dart';
+import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart';
+import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart';
+import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart';
+import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart';
+import 'package:hadi_hoda_flutter/core/utils/gap.dart';
+import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart';
+
+class DiamondLevel extends StatelessWidget {
+ const DiamondLevel({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Stack(
+ alignment: Alignment.center,
+ children: [
+ MyImage(image: MyAssets.diamondContainer),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ MyImage(image: MyAssets.diamondBig, size: 42),
+ MySpaces.s16.gapWidth,
+ ShaderMask(
+ blendMode: BlendMode.modulate,
+ shaderCallback: (bounds) => LinearGradient(
+ begin: Alignment.topCenter,
+ end: Alignment.bottomCenter,
+ colors: [Color(0XFF4BA5EA), Color(0XFF0C4EE9)],
+ ).createShader(bounds),
+ child: Text(
+ '0',
+ maxLines: 1,
+ style: MYTextStyle.button1.copyWith(
+ shadows: [
+ BoxShadow(
+ color: MyColors.black.withValues(alpha: 0.25),
+ offset: Offset(0, 1.43),
+ blurRadius: 1.43,
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ],
+ );
+ }
+}
diff --git a/lib/features/level/presentation/ui/widgets/hint_level_widget.dart b/lib/features/level/presentation/ui/widgets/hint_level_widget.dart
deleted file mode 100644
index d32c310..0000000
--- a/lib/features/level/presentation/ui/widgets/hint_level_widget.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart';
-import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart';
-import 'package:hadi_hoda_flutter/core/utils/my_localization.dart';
-import 'package:hadi_hoda_flutter/core/utils/screen_size.dart';
-import 'package:hadi_hoda_flutter/core/widgets/answer_box/styles/text_box.dart';
-import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart';
-import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart';
-
-class HintLevelWidget extends StatelessWidget {
- const HintLevelWidget({
- super.key,
- required this.level,
- this.onTap,
- });
-
- final LevelEntity level;
- final Function(LevelEntity level)? onTap;
-
- @override
- Widget build(BuildContext context) {
- return ClipPath(
- clipper: WavyBannerClipper(),
- child: Container(
- width: context.widthScreen,
- padding: EdgeInsets.symmetric(horizontal: 14, vertical: 16),
- decoration: BoxDecoration(
- gradient: LinearGradient(
- begin: Alignment.bottomCenter,
- end: Alignment.topCenter,
- colors: [Color(0XFFCADCFF), Color(0XFFFFFFFF)],
- ),
- ),
- child: Row(
- children: [
- Expanded(
- child: Column(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.start,
- spacing: MySpaces.s8,
- children: [
- Text(
- '${context.translate.step} ${level.order ?? 0}',
- ),
- Text(
- level.title ?? '',
- maxLines: 3,
- overflow: TextOverflow.ellipsis,
- ),
- ],
- ),
- ),
- InkWell(
- onTap: () => onTap?.call(level),
- child: MyImage(image: MyAssets.play, size: 70),),
- ],
- ),
- ),
- );
- }
-}
diff --git a/lib/features/level/presentation/ui/widgets/level_path.dart b/lib/features/level/presentation/ui/widgets/level_path.dart
index 8e327e2..f814cba 100644
--- a/lib/features/level/presentation/ui/widgets/level_path.dart
+++ b/lib/features/level/presentation/ui/widgets/level_path.dart
@@ -2,20 +2,38 @@ import 'package:flutter/material.dart';
import 'package:path_drawing/path_drawing.dart';
class LevelPath extends StatelessWidget {
- const LevelPath({super.key});
+ const LevelPath({
+ super.key,
+ required this.width,
+ required this.height
+ });
+
+ final double width;
+ final double height;
@override
Widget build(BuildContext context) {
- return CustomPaint(size: Size(361, 2233), painter: CurvedPathPainter());
+ return CustomPaint(
+ size: Size(width, height),
+ painter: CurvedPathPainter(width: width, height: height),
+ );
}
}
class CurvedPathPainter extends CustomPainter {
+ const CurvedPathPainter({
+ required this.width,
+ required this.height
+ });
+
+ final double width;
+ final double height;
+
@override
void paint(Canvas canvas, Size size) {
// Scale factor to fit the design
- final scaleX = size.width / 361;
- final scaleY = size.height / 2233;
+ final scaleX = size.width / width;
+ final scaleY = size.height / height;
final paint = Paint()
..color = Colors.white
diff --git a/lib/features/level/presentation/ui/widgets/level_widget.dart b/lib/features/level/presentation/ui/widgets/level_widget.dart
index 70d049d..c2d2968 100644
--- a/lib/features/level/presentation/ui/widgets/level_widget.dart
+++ b/lib/features/level/presentation/ui/widgets/level_widget.dart
@@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart';
+import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart';
+import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart';
import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart';
import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart';
@@ -13,6 +15,18 @@ enum LevelType {
LevelType.finished: MyAssets.finishedLevel,
LevelType.current: MyAssets.currentLevel,
};
+
+ static Map get textShadowColor => {
+ LevelType.unFinished: Color(0XFF5B5B5B),
+ LevelType.finished: Color(0XFF096D7B),
+ LevelType.current: Color(0XFF91500D),
+ };
+
+ static Map get textColor => {
+ LevelType.unFinished: Color(0XFFEDEDED),
+ LevelType.finished: Color(0XFFFFF2D0),
+ LevelType.current: Color(0XFFFFF2D0),
+ };
}
class LevelWidget extends StatelessWidget {
@@ -38,8 +52,29 @@ class LevelWidget extends StatelessWidget {
clipBehavior: Clip.none,
children: [
MyImage(image: LevelType.image[type] ?? MyAssets.level, size: 46),
- Text(
- '${level.order}',
+ ShaderMask(
+ blendMode: BlendMode.modulate,
+ shaderCallback: (bounds) => LinearGradient(
+ begin: Alignment.topCenter,
+ end: Alignment.bottomCenter,
+ colors: [
+ Color(0XFFFFFFFF),
+ LevelType.textColor[type] ?? MyColors.white,
+ ],
+ ).createShader(bounds),
+ child: Text(
+ '${level.order ?? 0}',
+ maxLines: 1,
+ style: MYTextStyle.button1.copyWith(
+ fontSize: 24,
+ shadows: [
+ BoxShadow(
+ color: LevelType.textShadowColor[type] ?? MyColors.white,
+ offset: Offset(0, 2.97),
+ )
+ ],
+ ),
+ ),
),
if(level.id == chooseLevel?.id)
Positioned(
diff --git a/lib/features/level/presentation/ui/widgets/play_button.dart b/lib/features/level/presentation/ui/widgets/play_button.dart
new file mode 100644
index 0000000..bd41792
--- /dev/null
+++ b/lib/features/level/presentation/ui/widgets/play_button.dart
@@ -0,0 +1,64 @@
+import 'package:flutter/material.dart';
+import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart';
+import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart';
+import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart';
+import 'package:hadi_hoda_flutter/core/utils/my_localization.dart';
+import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart';
+import 'package:hadi_hoda_flutter/core/widgets/inkwell/my_inkwell.dart';
+import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart';
+
+class PlayButton extends StatelessWidget {
+ const PlayButton({super.key, required this.level, this.onTap});
+
+ final LevelEntity level;
+ final Function(LevelEntity level)? onTap;
+
+ @override
+ Widget build(BuildContext context) {
+ return MyInkwell(
+ onTap: () => onTap?.call(level),
+ child: Stack(
+ alignment: Alignment.center,
+ children: [
+ MyImage(image: MyAssets.button2),
+ Positioned(
+ top: MySpaces.s2,
+ child: Row(
+ spacing: MySpaces.s4,
+ children: [
+ MyImage(image: MyAssets.iconPlay),
+ ShaderMask(
+ blendMode: BlendMode.modulate,
+ shaderCallback: (bounds) => LinearGradient(
+ begin: Alignment.topCenter,
+ end: Alignment.bottomCenter,
+ colors: [Color(0XFFF9601F), Color(0XFFD93D16)],
+ ).createShader(bounds),
+ child: Text(
+ context.translate.play,
+ maxLines: 1,
+ style: MYTextStyle.button1.copyWith(
+ shadows: [
+ BoxShadow(
+ color: Color(0XFFFFFFAB).withValues(alpha: 0.40),
+ offset: Offset(0, 2.61),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ Positioned(
+ bottom: MySpaces.s20,
+ child: Text(
+ '${context.translate.step} ${level.order ?? 0}',
+ style: MYTextStyle.matn3.copyWith(color: Color(0XFFD8490B)),
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb
index 07c32b4..4bad7ff 100644
--- a/lib/l10n/app_en.arb
+++ b/lib/l10n/app_en.arb
@@ -28,5 +28,6 @@
"want_to_exit": "Want To Exit?",
"exit_dialog_desc": "Come back, hero!\nThe adventure isn’t over yet",
"cancel": "Cancel",
- "exit": "Exit"
+ "exit": "Exit",
+ "play": "PLAY"
}
\ No newline at end of file
diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart
index 205ea03..f4ec348 100644
--- a/lib/l10n/app_localizations.dart
+++ b/lib/l10n/app_localizations.dart
@@ -273,6 +273,12 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'Exit'**
String get exit;
+
+ /// No description provided for @play.
+ ///
+ /// In en, this message translates to:
+ /// **'PLAY'**
+ String get play;
}
class _AppLocalizationsDelegate
diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart
index fbc64fa..319b54d 100644
--- a/lib/l10n/app_localizations_en.dart
+++ b/lib/l10n/app_localizations_en.dart
@@ -103,4 +103,7 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get exit => 'Exit';
+
+ @override
+ String get play => 'PLAY';
}