├── .firebase
├── hosting.YnVpbGQvd2Vi.cache
└── hosting.YnVpbGRcd2Vi.cache
├── .firebaserc
├── .gitignore
├── .metadata
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── README.md
├── analysis_options.yaml
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── roll_the_ball
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable-v21
│ │ │ └── launch_background.xml
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── values-night
│ │ │ └── styles.xml
│ │ │ └── values
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── assets
├── audio
│ ├── ballTap.mp3
│ ├── ballroll.mp3
│ ├── immutableTile.mp3
│ └── missionPassed.mp3
├── images
│ ├── back.svg
│ ├── board-background.svg
│ ├── board.svg
│ ├── btn_play.svg
│ ├── btn_setting.svg
│ ├── buttons
│ │ ├── levels.svg
│ │ └── next.svg
│ ├── disabled_back.svg
│ ├── disabled_restart.svg
│ ├── disabled_setting.svg
│ ├── moon.svg
│ ├── restart.svg
│ ├── setting.svg
│ ├── tiles
│ │ ├── tile0.svg
│ │ ├── tile1.svg
│ │ ├── tile10.svg
│ │ ├── tile11.svg
│ │ ├── tile12.svg
│ │ ├── tile13.svg
│ │ ├── tile14.svg
│ │ ├── tile15.svg
│ │ ├── tile16.svg
│ │ ├── tile17.svg
│ │ ├── tile18.svg
│ │ ├── tile19.svg
│ │ ├── tile2.svg
│ │ ├── tile20.svg
│ │ ├── tile21.svg
│ │ ├── tile3.svg
│ │ ├── tile4.svg
│ │ ├── tile5.svg
│ │ ├── tile6.svg
│ │ ├── tile7.svg
│ │ ├── tile8.svg
│ │ └── tile9.svg
│ └── way_for_ball.svg
├── lottie
│ └── snoopd.json
└── rive
│ └── bird.riv
├── firebase.json
├── fonts
├── Cairo
│ └── Cairo-Regular.ttf
└── Shizuru
│ └── Shizuru-Regular.ttf
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Podfile
├── Podfile.lock
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
└── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-App-1024x1024@1x.png
│ │ ├── Icon-App-20x20@1x.png
│ │ ├── Icon-App-20x20@2x.png
│ │ ├── Icon-App-20x20@3x.png
│ │ ├── Icon-App-29x29@1x.png
│ │ ├── Icon-App-29x29@2x.png
│ │ ├── Icon-App-29x29@3x.png
│ │ ├── Icon-App-40x40@1x.png
│ │ ├── Icon-App-40x40@2x.png
│ │ ├── Icon-App-40x40@3x.png
│ │ ├── Icon-App-60x60@2x.png
│ │ ├── Icon-App-60x60@3x.png
│ │ ├── Icon-App-76x76@1x.png
│ │ ├── Icon-App-76x76@2x.png
│ │ └── Icon-App-83.5x83.5@2x.png
│ └── LaunchImage.imageset
│ │ ├── Contents.json
│ │ ├── LaunchImage.png
│ │ ├── LaunchImage@2x.png
│ │ ├── LaunchImage@3x.png
│ │ └── README.md
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ └── Runner-Bridging-Header.h
├── lib
├── layout
│ ├── breakpoints.dart
│ ├── layout.dart
│ ├── responsive_gap.dart
│ └── responsive_layout_builder.dart
├── main.dart
├── screens
│ ├── puzzle
│ │ ├── blocs
│ │ │ ├── ball
│ │ │ │ ├── ball_bloc.dart
│ │ │ │ ├── ball_event.dart
│ │ │ │ └── ball_state.dart
│ │ │ ├── puzzle
│ │ │ │ ├── puzzle_bloc.dart
│ │ │ │ ├── puzzle_event.dart
│ │ │ │ └── puzzle_state.dart
│ │ │ └── timer
│ │ │ │ ├── timer_bloc.dart
│ │ │ │ ├── timer_event.dart
│ │ │ │ └── timer_state.dart
│ │ ├── puzzle_screen.dart
│ │ └── puzzle_widgets
│ │ │ ├── background.dart
│ │ │ ├── ball.dart
│ │ │ ├── ball_view.dart
│ │ │ ├── board.dart
│ │ │ ├── puzzle_bottom_view.dart
│ │ │ ├── puzzle_top_view.dart
│ │ │ ├── puzzle_view.dart
│ │ │ └── widgets.dart
│ └── start
│ │ ├── bloc
│ │ ├── bird_bloc.dart
│ │ ├── bird_event.dart
│ │ └── bird_state.dart
│ │ ├── start_screen.dart
│ │ └── start_widgets
│ │ ├── background.dart
│ │ ├── bird.dart
│ │ ├── bird_container.dart
│ │ ├── button_play.dart
│ │ ├── button_setting.dart
│ │ └── logo.dart
├── utils
│ ├── arc_map.dart
│ ├── levels_data.dart
│ ├── popup
│ │ ├── levels
│ │ │ ├── levels_popup.dart
│ │ │ └── widgets
│ │ │ │ └── level_tile.dart
│ │ ├── settings
│ │ │ └── volume.dart
│ │ └── winning
│ │ │ ├── widgets
│ │ │ └── win_button.dart
│ │ │ └── win_popup.dart
│ ├── router.dart
│ ├── screens.dart
│ └── shared_prefs.dart
└── widgets
│ ├── slide_animation.dart
│ └── swipe_detector.dart
├── pubspec.lock
├── pubspec.yaml
├── test
└── widget_test.dart
└── web
├── favicon.png
├── icons
├── Icon-192.png
├── Icon-512.png
├── Icon-maskable-192.png
└── Icon-maskable-512.png
├── index.html
├── main-background.png
└── manifest.json
/.firebase/hosting.YnVpbGQvd2Vi.cache:
--------------------------------------------------------------------------------
1 | favicon.png,1648469745842,ef6049294bf31362898aeb7918ff6d4580a718fd1d3184a8dd46623b15eae890
2 | main-background.png,1648626482435,06784d2821bd58170edde0fd1eb57b4135b7a22e513ec97bbbf61dc4b540a26b
3 | manifest.json,1648469586604,d3078d02b349302f44db575359bca90564dd9ff4890d766800755ab8137316ba
4 | assets/assets/audio/ballTap.mp3,1645206067241,07e0ac2d328f110124daf441d57900eb8b251080cb3bfb01e035e047b34fbe99
5 | assets/assets/audio/ballroll.mp3,1643209607810,4076f25b7d1d6812dac3f7e93aba418761febc5e1ebe4cf52d7470d85ecda884
6 | assets/assets/audio/immutableTile.mp3,1645206103336,1a7ae07c7731066b12c7987568f00cee0a3f597e5bb050a9d57861e8a8baec30
7 | assets/assets/audio/missionPassed.mp3,1645211263098,22d881b148006839a77ee8a5e1c1188de3785a77f21ef82ba2791141245ab54f
8 | assets/assets/images/back.svg,1648401284532,55df2e9eecf454915e7528cab7bb80849a40cea7f6df5f239a152e58c599b276
9 | assets/assets/images/board-background.svg,1648401284534,70547f7a93b5ad1a1ca2725f43bb66a4545fcd479493b3c72250f9f74f7d50a1
10 | assets/assets/images/board.svg,1648401284535,02f26d5a0acead04b4daa707a9a4e7a94f3c9c72051e5ed2e4a216f5ca314a20
11 | assets/assets/images/btn_play.svg,1648401284536,abdefbeba3ef40cd6be58943062d395d0ea59eb0c308e3d9991955c30883939c
12 | assets/assets/images/btn_setting.svg,1648401284536,65550b15c2f75e20136f42441076c4f3d4dcab399c7395105b3f362493eecd7a
13 | assets/assets/images/moon.svg,1648401284538,533a2d315a3002673f9e680e21eb47827701897697e426a9255efec1678218a5
14 | assets/assets/images/restart.svg,1648401284539,79480d4d0d4eff3d724c4deff28c05082e63c391a69d105bdc06fda9464721fa
15 | assets/assets/images/way_for_ball.svg,1648401284563,93df0dd4113ca55eac63e1ba2702ce66ee9edfde4fbf4485a91270fa53b80245
16 | assets/assets/images/buttons/levels.svg,1648401284537,2439348880d57745a524c3845bf9cbd8e463a4df192321d54b19958045956f7c
17 | assets/assets/images/buttons/next.svg,1648401284538,b6ebca5b52faa92ce92e59ab7cdd31528142455e6939752ceae4b05b4e9cf537
18 | assets/assets/images/tiles/tile0.svg,1648401284541,d6a4b8f0efadeda27d7a0fb701b828ef3bcd53acc5f74c8b93285d2bbc976985
19 | assets/assets/images/tiles/tile1.svg,1648401284541,e6032b03f6eef8052aaf61be61b55b9ee7fab798a1fc2340be7ae34df4d181f6
20 | assets/assets/images/tiles/tile10.svg,1648401284543,6967c2395b439153aa2f3ba32179bc9d6cb624040af6b1f7b636c591229c8feb
21 | assets/assets/images/tiles/tile11.svg,1648401284543,578e37d96721a25224e9bc13c195d2274cbad8b343d8c0c459ec89cdb074b2df
22 | assets/assets/images/tiles/tile12.svg,1648401284544,82b2e374fec178a394b1214fe127fe4dd785d9c513c76cc44692f41aa511311e
23 | assets/assets/images/tiles/tile13.svg,1648401284544,851c5327e5dcb05c5d97ca33da1cdc6f9de651229e3bb0d5e2031c55aa47df64
24 | assets/assets/images/tiles/tile14.svg,1648401284545,c89e9b5442c55fe50644c4a5e060cf75c4f6a4b6b015712f59871bd27120eca9
25 | assets/assets/images/tiles/tile15.svg,1648401284545,8d412bdd5c315a17b60d2377502fa3854b35cc1918db47b8b14e9bc9cb4cf8ed
26 | assets/assets/images/tiles/tile16.svg,1648401284547,3cadeda67f9c165181ef7150f61e39372245bd4e00f0090397cebd3ff3f93fcf
27 | assets/assets/images/tiles/tile17.svg,1648401284547,ce2eff4acda3856cf516b026f168ad23bc048752686944aaeb0b153bb514b06d
28 | assets/assets/images/tiles/tile18.svg,1648401284548,b91c402a73962a868eaca2cba7e6fff58f0c8d3c79392e40d4daf6886274b065
29 | assets/assets/images/tiles/tile19.svg,1648401284548,819ab872635e7d48448b8561fd4d30ef8c3798d184f60fee12e3925f542fd4a3
30 | assets/assets/images/tiles/tile2.svg,1648401284549,278cd921fb18966d7864f3f5bf095f764e8a74a7282fe9b8f36947190c326649
31 | assets/assets/images/tiles/tile20.svg,1648401284550,54f97fa0c4519cab51b5c69e68231fd2e1c4b77e54d31b6bf6b2b9a3fc1b5234
32 | assets/assets/images/tiles/tile21.svg,1648401284550,d9e44e5ac4c07d4345c7783af68b87e0f593ea51d830736f06fb574cb975e145
33 | assets/assets/images/tiles/tile3.svg,1648401284551,d9cce0fa0e25f7a1c206b4d557c36a9d279776d7e5e88dd83141df3f815f6b8c
34 | assets/assets/images/tiles/tile4.svg,1648401284553,02841328be8ccdb3f92ac722bbab57a553fbd0ec067ffa26fc8daed734dc1a26
35 | assets/assets/images/tiles/tile5.svg,1648401284554,0471349cbe580be9597f3e2b46c0311a31da7cb9481259e8d7a1dec0bff52302
36 | assets/assets/images/tiles/tile6.svg,1648401284558,843084cc1d1efb0a71f266b2db1932d77d0f456673458a26d3d0514d4abf66f4
37 | assets/assets/images/tiles/tile7.svg,1648401284559,64dfda5b1ac199ba1af003ba5829926e01666ed87b10183f9b767ec7aa1fc01b
38 | assets/assets/images/tiles/tile8.svg,1648401284559,cd3edabcd5a04a2bf74c790fcbcd3008e865bbe0ec064e6cbc2287dc161c131b
39 | assets/assets/images/tiles/tile9.svg,1648401284560,1e34cd0f8ee020397a5164b717d12bc9bbc070657007c7d6db61d7e524da2b7d
40 | assets/assets/lottie/snoopd.json,1645211157586,7a56a5a8848c3142263be3061c0743bd5280bc1b7df2bc455a28ede5b05fdd8a
41 | assets/assets/rive/bird.riv,1648401284566,48c6a519081d8ea043c3c552241322723e82004344dcc713b950d173a3d873c1
42 | assets/fonts/MaterialIcons-Regular.otf,1615596762000,5f71a8843e4edc9656c39061c2232458a6fc77e1603305960e4efa9c77f8b7a2
43 | assets/fonts/Cairo/Cairo-Regular.ttf,1465929000000,90df577e21414ce00ca0e5742ae80ce75d6770f17dfb237a115dc2dc00b64903
44 | assets/fonts/Shizuru/Shizuru-Regular.ttf,1647195832528,e495faa130fc0c720699538ebfef7a4504f486fbce1e00a8e61cc43915c6c65d
45 | canvaskit/canvaskit.js,315426600000,9ff3503a07b0494aaa30e5afa92a9a083c897951afcc402003699887fb5ac20e
46 | canvaskit/canvaskit.wasm,315426600000,4f057066d417d780f281ecc3c18ea040218529f0cfbb7179c3c8987826709108
47 | canvaskit/profiling/canvaskit.js,315426600000,b0eaf946cc777c85682e64dbe0490f2eb5922e751ea20d64866b8788b5c8f6aa
48 | canvaskit/profiling/canvaskit.wasm,315426600000,5fe6878a8edd1e290b0b7c5a770af45fca1a90d2dc650eafae8d2468ad530502
49 | icons/Icon-192.png,1648626530417,a27c5d1747c8ed7b0e01ad1ad455cae3f333803c3eb330c7ccddc7d6b524f262
50 | icons/Icon-512.png,1648626530420,5ca8c89c295da9ed31e52c8b2a964afc756cda7375df5b9329db85a45e54c9d3
51 | icons/Icon-maskable-192.png,1648626530422,a27c5d1747c8ed7b0e01ad1ad455cae3f333803c3eb330c7ccddc7d6b524f262
52 | icons/Icon-maskable-512.png,1648626530423,5ca8c89c295da9ed31e52c8b2a964afc756cda7375df5b9329db85a45e54c9d3
53 | flutter_service_worker.js,1648822624590,ebbe4c9c337aea540b13df804db820b362bb650cb629183f300af7b748a56458
54 | index.html,1648822624031,ac4192ad219229ee825f5f28c95150b0b0f12c2f04d2d4084c6d8578c1415002
55 | version.json,1648822623703,ccfefb22a16dd9db604ad6ff998dc6cd436dcd0a7b7072a0ec0166c78f93ca68
56 | assets/AssetManifest.json,1648822624010,50342253c1b037f9115f58841067ab747b1642b94848d916a6ed099cbbdd0fa5
57 | assets/FontManifest.json,1648822624010,4fd8ad26587ed53d3dd4cf2bcbb4bf408f2d75cccf9f49bf705c1dde35963a1e
58 | assets/assets/images/disabled_back.svg,1648814061626,70cc2eaf6605ccb75718fdfc98ad1a6aeeffe05091351e26834ebd7022d34ec9
59 | assets/assets/images/disabled_restart.svg,1648812870744,2900cacd1a26d055ddadf57f98d8043c64a8f6304fef3a77a0231afcdc3135dc
60 | assets/NOTICES,1648822624011,3cc5c23edc873344e360b9c56f4c669f38dd429cbaa05ed7f30e734d8928e27a
61 | main.dart.js,1648822622936,542db6eaaa79d8bddc2cc91392193131630885c5d53998cd3af07f1ba012fa83
62 |
--------------------------------------------------------------------------------
/.firebase/hosting.YnVpbGRcd2Vi.cache:
--------------------------------------------------------------------------------
1 | favicon.png,1647978363224,2dce38462e2f9124835826e78ada78051f5a44587bff1e1329d2fe1d63db07b6
2 | index.html,1648485191629,5354958a958a50b014d6c639f30ce177e02fc132f937ad8ebfe414931ba76fdb
3 | flutter_service_worker.js,1648485193093,cec048dc786c302a112c9bbee371b0aed96425cbef56057b9d6fb657722e6d06
4 | manifest.json,1647701119756,3697f3bc4bdc76cc3542c89633e8afb5f796c9ddee145654fe31183cc80b2e24
5 | version.json,1648485191258,a58ea00958d84849e9ba93e0377197868451cde2b0da084bf3d0020817c52f8d
6 | assets/AssetManifest.json,1648485191589,11f914fdfca5b5da55d52011d4e6aed5b41489f0e6ebce29c0fa1bfdeb0b526b
7 | assets/FontManifest.json,1648485191589,d14a1026bed49d60a740ef2ae4e353f05458552d8ea086164969297d59eeb7c0
8 | assets/assets/audio/ballTap.mp3,1648050408503,e8c3120a1349c6036fabdc2a0cecb5432d73891aae5147189cfa45176eb45745
9 | assets/assets/images/board-background.svg,1648173400994,c2acc5aa9a01283d0799c5319a00792c4505ce05ca463233b345dafd8030b366
10 | assets/assets/images/back.svg,1648173400993,d47d53da28b61932a34b7b59674c666da71d829fc71c7171c100394d635f7a15
11 | assets/assets/images/board.svg,1648173400995,ad1a9f64da116d7b127a5d656b279fd496aade7aae1bccda25954edc326150f2
12 | assets/assets/images/btn_play.svg,1648173400996,f2a5f78b294b6f92800265a8b7453d0eeda02f5d547ab5a4f8cf30fb7c98860b
13 | assets/assets/images/btn_setting.svg,1648173400997,1f6ffba6c37120686654db143d4306153b382d31f823d143beebead48cd55de6
14 | assets/assets/images/restart.svg,1648173401002,8e3a5fd0f62494a4aea7e497b6154e8449c7dfef00acde3606cb1dc96488ce7b
15 | assets/assets/images/moon.svg,1648173401001,f9e6a18575ce0d27bf8de97ba2d168ae03ce9a1c574976eb3b4391c930142860
16 | assets/assets/images/buttons/levels.svg,1648177508949,d2b07480e015ec1ce32f6aabfd91f4a9470d500759de0af483bd71ce93225cd1
17 | assets/assets/images/buttons/next.svg,1648173401000,60755d1b2dc7883f1cdc01df9bd9b9093a7fb857578d1bec7b8befbfdf990829
18 | assets/assets/images/tiles/tile0.svg,1648173401003,75af5124209f66cbd8ae683755c37c46d01fb71e97db6b94a0c4e5de78bcb649
19 | assets/assets/images/tiles/tile1.svg,1648174013538,ba52d67d75b5db015dd8d299ebe3ea326168cea82b31d0bf4f4e2ee52c1141d8
20 | assets/assets/images/tiles/tile10.svg,1648173401004,601739a4433f38ac4c9da4490a43dd3d0e1ef42225160b0b138410d7565fda67
21 | assets/assets/images/tiles/tile11.svg,1648173401005,fadd84e111d419c602a959a8e79509cc16748687db9f8a94c3c0ef3c3c0d28fb
22 | assets/assets/images/tiles/tile13.svg,1648173401007,ef5b3f61957af3ca942da2d675a46175e7fb3d60a74dc4bc245a80e837f7c2bd
23 | assets/assets/images/tiles/tile12.svg,1648173401006,83f5ca99e8f355db85b7694d4182c666c94df228c93115b768ba767e3f50b39a
24 | assets/assets/images/tiles/tile14.svg,1648173401007,b57791a66d7ebd15789ce4382e8ef68ddc749cfda4357a9cf347eff41ee8728c
25 | assets/assets/images/tiles/tile17.svg,1648173401010,4d2785415ab76cd0cb90fd06606d5a5d289ba1c24b1333a66f3fab56c86857c3
26 | assets/assets/images/tiles/tile16.svg,1648173401009,ac63cfb06faf8da9797a919131333b23e6c2a8bfc605395057cea3b866313dd9
27 | assets/assets/images/tiles/tile18.svg,1648173401011,78a49ea022afeed59bf59b027508673f23398e43b9b98fd1f6fa338c1af0dea4
28 | assets/assets/images/tiles/tile15.svg,1648173401008,653a8c9c55675f7eaa208b5b8536c8c4d3038ca3e5bbd3244514509cd7ad7fda
29 | assets/assets/images/tiles/tile2.svg,1648174040196,c92015a12787426827c807c0d63b0e02f009c5c9bbfb518dcbbd649a84d88551
30 | assets/assets/images/tiles/tile20.svg,1648173401014,f0a7555646e093244a0c30eae3b58ea9e9973e7f145d5247e7b36bea368adc74
31 | assets/assets/images/tiles/tile19.svg,1648173401012,383c8985c89ddcc72789f3146f616b6625ebea1bba4b7161228ad2239a4b2010
32 | assets/assets/images/tiles/tile21.svg,1648173401016,03953fc48a90043b4bb302881d36be989b635a4473474c1220ac99e8bd9fd501
33 | assets/assets/images/tiles/tile6.svg,1648173401020,2254c4724326d024aa72566d6f442cb8874a0eb457c6ab6cf7994290cd2e5506
34 | assets/assets/images/tiles/tile3.svg,1648174065955,6f3aa2e5929d429e4cdecbc62066cbe101e1ad542bc526d2c439028878e4438e
35 | assets/assets/images/way_for_ball.svg,1648173401024,3f8fc8b8a6d74170a2d341bd9e8bc82acc5eacb7a1f70a26b2151879c83cc66c
36 | assets/assets/images/tiles/tile4.svg,1648174091775,00a0ba6f9c61aadcfb2996b525d750d143a547fbaff0ff8d9248f39f428e641c
37 | assets/assets/images/tiles/tile5.svg,1648173401019,628da5dda6fcb9f0eb1545062ddfa0ab150c6358a35f118d970260f615fa30c6
38 | assets/assets/images/tiles/tile7.svg,1648173401021,f6e2b64e8a657523c4a8623e4f1aeb60372919695c3d434e1cd0e1cc8000a492
39 | assets/assets/images/tiles/tile9.svg,1648173401023,201c3d0ccfb58427ea12c2329959700f298f5288f1375e849c1fed4da5eea1cf
40 | assets/assets/images/tiles/tile8.svg,1648173401022,977a0c4006d5a8a5fc16859ffb8b07573f655d8828cd18454591f83c8809dac8
41 | assets/assets/rive/bird.riv,1648049837279,ecb9c31947c9fdfdde380d8c7eb045f323d6cd3a85ce8ddfa33b49a420e74520
42 | assets/assets/audio/immutableTile.mp3,1648050427153,fa6b01afeaf08b6c598b3f88d7bfacdabb1c7890a1b4935b3a5ca660f0a99965
43 | icons/icon.png,1644946574402,eaf2464bfb1d192fdd192a616f7b858dee456d573c6ec619648a1dcf2bdddfa6
44 | main-background.png,1648173401025,cc936d267efebaf15962570355f310d17b7c8ea26a2ee8deeeed2f9e7588dd54
45 | assets/fonts/Cairo/Cairo-Regular.ttf,1648448727461,3315545fd7ebce7d0c6f1973809cf556a09de9516be4f814da8ec6eff28f467b
46 | assets/assets/audio/ballroll.mp3,1648050403889,178332d28a306a19faff5876a97cf69a2fd7cf66eed56b2a715614ef3950cb78
47 | canvaskit/canvaskit.js,1643046523752,7335d1d2b4b78c90079b642b2c1704b4d4c64aa39c9f4b9743eb3ac8b1077e86
48 | assets/assets/lottie/snoopd.json,1647264590732,0f64368554ea4c7176cb08a09c0d666451a9ba8ca2e0d82e1eb2fdf043f14125
49 | canvaskit/profiling/canvaskit.js,1643046524211,d01d6c4c8962e36427f78f2d82c9982a1b321410f5ae14e99de0b6d9fdf9c04b
50 | assets/assets/audio/missionPassed.mp3,1648050431428,afa987f7fd945ec9cfae759a4a9c55ce58ca6d7c5515b9c0fd17c577198e46f8
51 | assets/NOTICES,1648485191589,beca0838a469529215c7e1c0b76d88d9d2483f34e828c73e10e5f37035cd1f4b
52 | assets/fonts/Shizuru/Shizuru-Regular.ttf,1647204788944,fb659cddab46be503ba6ad1ebddcee06b98bbfe6e5266cda5e5de086bf4a377b
53 | assets/fonts/MaterialIcons-Regular.otf,1643041247915,6a33dd7438073c82391fd948bbb9b48c94ef980957cdff54c0f0ac77f4e48d3e
54 | main.dart.js,1648485189598,935f56d4100acdd254e26895d19ab034039750439f467f556038f5b0e27f0c9b
55 | canvaskit/canvaskit.wasm,1643046524202,72f45c0699329fddd2f4a53e9cae8f6a2c8602430a5daddc6778174746089466
56 | canvaskit/profiling/canvaskit.wasm,1643046524490,a3b50911c38d2cd97ad057f2e3293fdc63c6e8f106c91557871da6680840110e
57 |
--------------------------------------------------------------------------------
/.firebaserc:
--------------------------------------------------------------------------------
1 | {
2 | "projects": {
3 | "default": "wayforball"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # The .vscode folder contains launch configuration and tasks you configure in
19 | # VS Code which you may wish to be included in version control, so this line
20 | # is commented out by default.
21 | #.vscode/
22 |
23 | # Flutter/Dart/Pub related
24 | **/doc/api/
25 | **/ios/Flutter/.last_build_id
26 | .dart_tool/
27 | .flutter-plugins
28 | .flutter-plugins-dependencies
29 | .packages
30 | .pub-cache/
31 | .pub/
32 | /build/
33 |
34 | # Web related
35 | lib/generated_plugin_registrant.dart
36 |
37 | # Symbolication related
38 | app.*.symbols
39 |
40 | # Obfuscation related
41 | app.*.map.json
42 |
43 | # Android Studio will place build artifacts here
44 | /android/app/debug
45 | /android/app/profile
46 | /android/app/release
47 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: cf4400006550b70f28e4b4af815151d1e74846c6
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | We as members, contributors, and leaders pledge to make participation in our
6 | community a harassment-free experience for everyone, regardless of age, body
7 | size, visible or invisible disability, ethnicity, sex characteristics, gender
8 | identity and expression, level of experience, education, socio-economic status,
9 | nationality, personal appearance, race, religion, or sexual identity
10 | and orientation.
11 |
12 | We pledge to act and interact in ways that contribute to an open, welcoming,
13 | diverse, inclusive, and healthy community.
14 |
15 | ## Our Standards
16 |
17 | Examples of behavior that contributes to a positive environment for our
18 | community include:
19 |
20 | * Demonstrating empathy and kindness toward other people
21 | * Being respectful of differing opinions, viewpoints, and experiences
22 | * Giving and gracefully accepting constructive feedback
23 | * Accepting responsibility and apologizing to those affected by our mistakes,
24 | and learning from the experience
25 | * Focusing on what is best not just for us as individuals, but for the
26 | overall community
27 |
28 | Examples of unacceptable behavior include:
29 |
30 | * The use of sexualized language or imagery, and sexual attention or
31 | advances of any kind
32 | * Trolling, insulting or derogatory comments, and personal or political attacks
33 | * Public or private harassment
34 | * Publishing others' private information, such as a physical or email
35 | address, without their explicit permission
36 | * Other conduct which could reasonably be considered inappropriate in a
37 | professional setting
38 |
39 | ## Enforcement Responsibilities
40 |
41 | Community leaders are responsible for clarifying and enforcing our standards of
42 | acceptable behavior and will take appropriate and fair corrective action in
43 | response to any behavior that they deem inappropriate, threatening, offensive,
44 | or harmful.
45 |
46 | Community leaders have the right and responsibility to remove, edit, or reject
47 | comments, commits, code, wiki edits, issues, and other contributions that are
48 | not aligned to this Code of Conduct, and will communicate reasons for moderation
49 | decisions when appropriate.
50 |
51 | ## Scope
52 |
53 | This Code of Conduct applies within all community spaces, and also applies when
54 | an individual is officially representing the community in public spaces.
55 | Examples of representing our community include using an official e-mail address,
56 | posting via an official social media account, or acting as an appointed
57 | representative at an online or offline event.
58 |
59 | ## Enforcement
60 |
61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
62 | reported to the community leaders responsible for enforcement at
63 | .
64 | All complaints will be reviewed and investigated promptly and fairly.
65 |
66 | All community leaders are obligated to respect the privacy and security of the
67 | reporter of any incident.
68 |
69 | ## Enforcement Guidelines
70 |
71 | Community leaders will follow these Community Impact Guidelines in determining
72 | the consequences for any action they deem in violation of this Code of Conduct:
73 |
74 | ### 1. Correction
75 |
76 | **Community Impact**: Use of inappropriate language or other behavior deemed
77 | unprofessional or unwelcome in the community.
78 |
79 | **Consequence**: A private, written warning from community leaders, providing
80 | clarity around the nature of the violation and an explanation of why the
81 | behavior was inappropriate. A public apology may be requested.
82 |
83 | ### 2. Warning
84 |
85 | **Community Impact**: A violation through a single incident or series
86 | of actions.
87 |
88 | **Consequence**: A warning with consequences for continued behavior. No
89 | interaction with the people involved, including unsolicited interaction with
90 | those enforcing the Code of Conduct, for a specified period of time. This
91 | includes avoiding interactions in community spaces as well as external channels
92 | like social media. Violating these terms may lead to a temporary or
93 | permanent ban.
94 |
95 | ### 3. Temporary Ban
96 |
97 | **Community Impact**: A serious violation of community standards, including
98 | sustained inappropriate behavior.
99 |
100 | **Consequence**: A temporary ban from any sort of interaction or public
101 | communication with the community for a specified period of time. No public or
102 | private interaction with the people involved, including unsolicited interaction
103 | with those enforcing the Code of Conduct, is allowed during this period.
104 | Violating these terms may lead to a permanent ban.
105 |
106 | ### 4. Permanent Ban
107 |
108 | **Community Impact**: Demonstrating a pattern of violation of community
109 | standards, including sustained inappropriate behavior, harassment of an
110 | individual, or aggression toward or disparagement of classes of individuals.
111 |
112 | **Consequence**: A permanent ban from any sort of public interaction within
113 | the community.
114 |
115 | ## Attribution
116 |
117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118 | version 2.0, available at
119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
120 |
121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct
122 | enforcement ladder](https://github.com/mozilla/diversity).
123 |
124 | [homepage]: https://www.contributor-covenant.org
125 |
126 | For answers to common questions about this code of conduct, see the FAQ at
127 | https://www.contributor-covenant.org/faq. Translations are available at
128 | https://www.contributor-covenant.org/translations.
129 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # 🌱 Contributing to hacktoberfest 2022
2 |
3 | 
4 |
5 | ### Welcome to hacktoberfest 2022 Public Repository. 👨🏻💻
6 |
7 |
A month-long celebration from October 1st - 31st sponsored by Digital Ocean and GitHub to get people involved in Open Source. Create your very first pull request to any public repository on GitHub and contribute to the open source developer community.
8 |
9 | https://hacktoberfest.com//
10 |
11 | ---
12 |
13 | ### How to Contribute to this repository
14 |
15 | - Run the project on your system and look for any bug fixes.
16 | - You can make any change, If it works and good for the app, it will be merged.
17 | - Make sure you follow the Hacktoberfest guidelines.
18 |
19 | ---
20 |
21 | ### NOTE
22 |
23 | - Make Sure you commit your changes in a new branch.
24 | - Make Sure you Give proper name to your files describing the addition.
25 | - Also Make Sure to put comments in your code wherever necessary.
26 | - While raising the PR, show the before and after of the changes in the Application.
27 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Way for Ball
2 |
3 | A slide Flutter Game.
4 |
5 | This engaging puzzle game is really simple, but challenging at the same time. The aim is straightforward – guide your ball through the maze to the exit area. The ball will not roll until you have completed the route. To create the route you must move each individual pattern and solve the puzzle. This is exactly the same as the classic jigsaw sliding games, just digital!
6 |
7 | Some tiles are movable some are not. One with bolts on them is not movable.
8 |
9 | The graphics are smooth, and the puzzles become increasingly difficult. This game tests your skill and logic, and is great fun to play!
10 |
11 | [Play here](https://wayforball.web.app/)
12 |
13 | [](https://wayforball.web.app/)
14 |
15 |
16 |
17 | ## How to contribute:
18 |
19 | - Drop a :star: on the Github repository (optional)
20 |
21 | - Before Contribute Please read [CONTRIBUTING.md](https://github.com/sb-decoder/flutter-puzzle-hack/blob/master/CONTRIBUTING.md) and [CODE_OF_CONDUCT.md](https://github.com/sb-decoder/flutter-puzzle-hack/blob/master/CODE_OF_CONDUCT.md)
22 |
23 | - Create an issue of the project or a feature you would like to add in the project and get the task assigned for youself.(Issue can be any bug fixes or any feature you want to add in this project).
24 |
25 | - Fork the repo to your Github.
26 |
27 | - Clone the Repo by going to your local Git Client in a particular local folder in your local machine by using this command with your forked repository link in place of below given link:
28 | `git clone https://github.com/nehal076/flutter-puzzle-hack`
29 | - Create a branch using below command.
30 | `git branch `
31 | - Checkout to your branch.
32 | `git checkout `
33 | - Add your code in your local machine folder.
34 | `git add . `
35 | - Commit your changes.
36 | `git commit -m""`
37 | - Push your changes.
38 | `git push --set-upstream origin `
39 |
40 | - Make a pull request! (compare your branch with the owner main branch)
41 |
42 | # Contributors
43 |
44 |
45 | Thanks to these amazing people
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 |
2 | include: package:flutter_lints/flutter.yaml
3 |
4 | linter:
5 | rules:
6 | avoid_print: false
7 | constant_identifier_names: false
8 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
9 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 | **/*.keystore
13 | **/*.jks
14 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | android {
29 | compileSdkVersion flutter.compileSdkVersion
30 |
31 | compileOptions {
32 | sourceCompatibility JavaVersion.VERSION_1_8
33 | targetCompatibility JavaVersion.VERSION_1_8
34 | }
35 |
36 | kotlinOptions {
37 | jvmTarget = '1.8'
38 | }
39 |
40 | sourceSets {
41 | main.java.srcDirs += 'src/main/kotlin'
42 | }
43 |
44 | defaultConfig {
45 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
46 | applicationId "com.example.way_for_ball"
47 | minSdkVersion flutter.minSdkVersion
48 | targetSdkVersion flutter.targetSdkVersion
49 | versionCode flutterVersionCode.toInteger()
50 | versionName flutterVersionName
51 | }
52 |
53 | buildTypes {
54 | release {
55 | // TODO: Add your own signing config for the release build.
56 | // Signing with the debug keys for now, so `flutter run --release` works.
57 | signingConfig signingConfigs.debug
58 | }
59 | }
60 | }
61 |
62 | flutter {
63 | source '../..'
64 | }
65 |
66 | dependencies {
67 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
68 | }
69 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
15 |
19 |
23 |
24 |
25 |
26 |
27 |
28 |
30 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/example/roll_the_ball/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.example.way_for_ball
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.6.10'
3 | repositories {
4 | google()
5 | mavenCentral()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:4.1.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | mavenCentral()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | }
25 | subprojects {
26 | project.evaluationDependsOn(':app')
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
7 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
4 | def properties = new Properties()
5 |
6 | assert localPropertiesFile.exists()
7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
8 |
9 | def flutterSdkPath = properties.getProperty("flutter.sdk")
10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
12 |
--------------------------------------------------------------------------------
/assets/audio/ballTap.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/assets/audio/ballTap.mp3
--------------------------------------------------------------------------------
/assets/audio/ballroll.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/assets/audio/ballroll.mp3
--------------------------------------------------------------------------------
/assets/audio/immutableTile.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/assets/audio/immutableTile.mp3
--------------------------------------------------------------------------------
/assets/audio/missionPassed.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/assets/audio/missionPassed.mp3
--------------------------------------------------------------------------------
/assets/images/back.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/board-background.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/board.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/btn_play.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/btn_setting.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/buttons/levels.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/buttons/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/disabled_back.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/assets/images/disabled_restart.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/disabled_setting.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/assets/images/moon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/restart.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/setting.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/assets/images/tiles/tile0.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/tiles/tile1.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/tiles/tile10.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/tiles/tile11.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/tiles/tile12.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/tiles/tile13.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/tiles/tile14.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/tiles/tile15.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/tiles/tile16.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/tiles/tile17.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/tiles/tile18.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/tiles/tile19.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/tiles/tile2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/tiles/tile20.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/tiles/tile21.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/tiles/tile3.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/tiles/tile4.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/tiles/tile5.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/tiles/tile6.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/tiles/tile7.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/tiles/tile8.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/tiles/tile9.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/rive/bird.riv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/assets/rive/bird.riv
--------------------------------------------------------------------------------
/firebase.json:
--------------------------------------------------------------------------------
1 | {
2 | "hosting": {
3 | "public": "build/web",
4 | "ignore": [
5 | "firebase.json",
6 | "**/.*",
7 | "**/node_modules/**"
8 | ],
9 | "rewrites": [
10 | {
11 | "source": "**",
12 | "destination": "/index.html"
13 | }
14 | ]
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/fonts/Cairo/Cairo-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/fonts/Cairo/Cairo-Regular.ttf
--------------------------------------------------------------------------------
/fonts/Shizuru/Shizuru-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/fonts/Shizuru/Shizuru-Regular.ttf
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | **/dgph
2 | *.mode1v3
3 | *.mode2v3
4 | *.moved-aside
5 | *.pbxuser
6 | *.perspectivev3
7 | **/*sync/
8 | .sconsign.dblite
9 | .tags*
10 | **/.vagrant/
11 | **/DerivedData/
12 | Icon?
13 | **/Pods/
14 | **/.symlinks/
15 | profile
16 | xcuserdata
17 | **/.generated/
18 | Flutter/App.framework
19 | Flutter/Flutter.framework
20 | Flutter/Flutter.podspec
21 | Flutter/Generated.xcconfig
22 | Flutter/ephemeral/
23 | Flutter/app.flx
24 | Flutter/app.zip
25 | Flutter/flutter_assets/
26 | Flutter/flutter_export_environment.sh
27 | ServiceDefinitions.json
28 | Runner/GeneratedPluginRegistrant.*
29 |
30 | # Exceptions to above rules.
31 | !default.mode1v3
32 | !default.mode2v3
33 | !default.pbxuser
34 | !default.perspectivev3
35 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 9.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def flutter_root
14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15 | unless File.exist?(generated_xcode_build_settings_path)
16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17 | end
18 |
19 | File.foreach(generated_xcode_build_settings_path) do |line|
20 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
21 | return matches[1].strip if matches
22 | end
23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24 | end
25 |
26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27 |
28 | flutter_ios_podfile_setup
29 |
30 | target 'Runner' do
31 | use_frameworks!
32 | use_modular_headers!
33 |
34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
35 | end
36 |
37 | post_install do |installer|
38 | installer.pods_project.targets.each do |target|
39 | flutter_additional_ios_build_settings(target)
40 | end
41 | end
42 |
--------------------------------------------------------------------------------
/ios/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - audioplayers (0.0.1):
3 | - Flutter
4 | - Flutter (1.0.0)
5 | - path_provider_ios (0.0.1):
6 | - Flutter
7 | - shared_preferences_ios (0.0.1):
8 | - Flutter
9 | - url_launcher_ios (0.0.1):
10 | - Flutter
11 |
12 | DEPENDENCIES:
13 | - audioplayers (from `.symlinks/plugins/audioplayers/ios`)
14 | - Flutter (from `Flutter`)
15 | - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
16 | - shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`)
17 | - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
18 |
19 | EXTERNAL SOURCES:
20 | audioplayers:
21 | :path: ".symlinks/plugins/audioplayers/ios"
22 | Flutter:
23 | :path: Flutter
24 | path_provider_ios:
25 | :path: ".symlinks/plugins/path_provider_ios/ios"
26 | shared_preferences_ios:
27 | :path: ".symlinks/plugins/shared_preferences_ios/ios"
28 | url_launcher_ios:
29 | :path: ".symlinks/plugins/url_launcher_ios/ios"
30 |
31 | SPEC CHECKSUMS:
32 | audioplayers: 455322b54050b30ea4b1af7cd9e9d105f74efa8c
33 | Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
34 | path_provider_ios: 7d7ce634493af4477d156294792024ec3485acd5
35 | shared_preferences_ios: aef470a42dc4675a1cdd50e3158b42e3d1232b32
36 | url_launcher_ios: 02f1989d4e14e998335b02b67a7590fa34f971af
37 |
38 | PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
39 |
40 | COCOAPODS: 1.11.2
41 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
41 |
42 |
52 |
54 |
60 |
61 |
62 |
63 |
69 |
71 |
77 |
78 |
79 |
80 |
82 |
83 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | Roll The Ball
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | way_for_ball
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(FLUTTER_BUILD_NUMBER)
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 | UIViewControllerBasedStatusBarAppearance
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/lib/layout/breakpoints.dart:
--------------------------------------------------------------------------------
1 | abstract class Breakpoints {
2 | static const double small = 576;
3 | static const double medium = 1200;
4 | static const double large = 1440;
5 | }
6 |
--------------------------------------------------------------------------------
/lib/layout/layout.dart:
--------------------------------------------------------------------------------
1 | export 'breakpoints.dart';
2 | export 'responsive_gap.dart';
3 | export 'responsive_layout_builder.dart';
4 |
--------------------------------------------------------------------------------
/lib/layout/responsive_gap.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:gap/gap.dart';
3 |
4 | import 'layout.dart';
5 |
6 | class ResponsiveGap extends StatelessWidget {
7 | const ResponsiveGap({
8 | Key? key,
9 | this.small = 0,
10 | this.medium = 0,
11 | this.large = 0,
12 | }) : super(key: key);
13 |
14 | final double small;
15 | final double medium;
16 | final double large;
17 |
18 | @override
19 | Widget build(BuildContext context) {
20 | return ResponsiveLayoutBuilder(
21 | small: (_, __) => Gap(small),
22 | medium: (_, __) => Gap(medium),
23 | large: (_, __) => Gap(large),
24 | child: (_) => const SizedBox.shrink(),
25 | );
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/lib/layout/responsive_layout_builder.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart';
2 | import 'breakpoints.dart';
3 |
4 | enum ResponsiveLayoutSize { small, medium, large }
5 |
6 | typedef ResponsiveLayoutWidgetBuilder = Widget Function(BuildContext, Widget);
7 |
8 | class ResponsiveLayoutBuilder extends StatelessWidget {
9 | const ResponsiveLayoutBuilder({
10 | Key? key,
11 | required this.small,
12 | required this.medium,
13 | required this.large,
14 | required this.child,
15 | }) : super(key: key);
16 |
17 | final ResponsiveLayoutWidgetBuilder small;
18 | final ResponsiveLayoutWidgetBuilder medium;
19 | final ResponsiveLayoutWidgetBuilder large;
20 | final Widget Function(ResponsiveLayoutSize currentSize) child;
21 |
22 | @override
23 | Widget build(BuildContext context) {
24 | return LayoutBuilder(
25 | builder: (context, constraints) {
26 | final screenWidth = MediaQuery.of(context).size.width;
27 |
28 | if (screenWidth <= Breakpoints.small) {
29 | return small(context, child.call(ResponsiveLayoutSize.small));
30 | }
31 | if (screenWidth <= Breakpoints.medium) {
32 | return medium(context, child.call(ResponsiveLayoutSize.medium));
33 | }
34 | if (screenWidth <= Breakpoints.large) {
35 | return large(context, child.call(ResponsiveLayoutSize.large));
36 | }
37 |
38 | return large(context, child.call(ResponsiveLayoutSize.large));
39 | },
40 | );
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 | import 'dart:developer';
3 |
4 | import 'package:flutter/material.dart';
5 | import 'package:way_for_ball/utils/router.dart';
6 | import 'package:url_strategy/url_strategy.dart';
7 |
8 | import 'utils/shared_prefs.dart';
9 |
10 | void main() async {
11 | WidgetsFlutterBinding.ensureInitialized();
12 | await SharedPrefUtils.init();
13 | setPathUrlStrategy();
14 | runApp(const MyApp());
15 | }
16 |
17 | class MyApp extends StatefulWidget {
18 | const MyApp({Key? key}) : super(key: key);
19 |
20 | @override
21 | State createState() => _MyAppState();
22 | }
23 |
24 | final navigatorKey = GlobalKey();
25 |
26 | class _MyAppState extends State {
27 | AppRouter router = AppRouter();
28 |
29 | @override
30 | void initState() {
31 | super.initState();
32 | SharedPrefUtils.volume = "66";
33 | SharedPrefUtils.playerLevel = "0";
34 |
35 | final userPrefs = SharedPrefUtils.getAllUserPrefs();
36 | log(jsonEncode(userPrefs));
37 | }
38 |
39 | @override
40 | Widget build(BuildContext context) {
41 | return MaterialApp(
42 | debugShowCheckedModeBanner: false,
43 | theme: ThemeData(primarySwatch: Colors.blue),
44 | navigatorKey: navigatorKey,
45 | onGenerateRoute: router.generateRoute,
46 | onGenerateTitle: (_) => 'Way For Ball',
47 | initialRoute: '',
48 | );
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/lib/screens/puzzle/blocs/ball/ball_event.dart:
--------------------------------------------------------------------------------
1 | part of 'ball_bloc.dart';
2 |
3 | abstract class BallEvent {
4 | const BallEvent();
5 | }
6 |
7 | class InitalizeBall extends BallEvent {
8 | final BuildContext context;
9 | InitalizeBall(this.context);
10 | }
11 |
12 | class UpdateBall extends BallEvent {}
13 |
14 | class UpdateLinearState extends BallEvent {}
15 |
16 | class UpdateCurveState extends BallEvent {}
17 |
18 | class RollBall extends BallEvent {}
19 |
20 | class BallInitalize extends BallEvent {}
21 |
--------------------------------------------------------------------------------
/lib/screens/puzzle/blocs/ball/ball_state.dart:
--------------------------------------------------------------------------------
1 | part of 'ball_bloc.dart';
2 |
3 | abstract class BallState {
4 | const BallState();
5 | }
6 |
7 | class BallInitial extends BallState {}
8 |
9 | class BallRolling extends BallState {
10 | final double ballX;
11 | final double ballY;
12 | final double ballSize;
13 | BallRolling(this.ballX, this.ballY, this.ballSize);
14 | }
15 |
16 | class BallRollComplete extends BallState {}
17 |
--------------------------------------------------------------------------------
/lib/screens/puzzle/blocs/puzzle/puzzle_bloc.dart:
--------------------------------------------------------------------------------
1 | import 'package:audioplayers/audioplayers.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter_bloc/flutter_bloc.dart';
4 | import 'package:way_for_ball/screens/puzzle/blocs/ball/ball_bloc.dart';
5 | import 'package:way_for_ball/utils/levels_data.dart';
6 | import 'package:way_for_ball/utils/shared_prefs.dart';
7 |
8 | import '../timer/timer_bloc.dart';
9 |
10 | part 'puzzle_event.dart';
11 | part 'puzzle_state.dart';
12 |
13 | class PuzzleBloc extends Bloc {
14 | PuzzleBloc() : super(PuzzleInitial()) {
15 | on(_initPuzzle);
16 | on(_swipe);
17 | }
18 |
19 | List> initialState = [];
20 | List> playingState = [];
21 | List>> winningStates = [];
22 | int numBlocks = 0;
23 | List flow = [];
24 | StagePoint? stageStartPoint;
25 | StagePoint? stageEndPoint;
26 | String level = "1";
27 | bool isFirstMove = false;
28 | int moveCounter = 0;
29 | double volume = 1;
30 |
31 | final sound = AudioCache();
32 |
33 | _initPuzzle(InitPuzzle event, Emitter emit) {
34 | level = event.level.toString();
35 |
36 | volume = double.parse(SharedPrefUtils.volume) / 100;
37 |
38 | Level player = levelData.firstWhere((e) => '${e.levelNum}' == level);
39 |
40 | List> arr = [];
41 |
42 | for (var i = 0; i < player.initialState.length; i++) {
43 | List temp = [];
44 |
45 | for (var j = 0; j < player.initialState[i].length; j++) {
46 | temp.add(player.initialState[i][j]);
47 | }
48 |
49 | arr.add(temp);
50 | }
51 |
52 | initialState = [...player.initialState];
53 | playingState = arr;
54 | winningStates = player.winningStates;
55 | numBlocks = player.initialState[0].length;
56 | stageStartPoint = player.stageStartPoint;
57 | stageEndPoint = player.stageEndPoint;
58 | flow = [...player.flows[0]];
59 |
60 | emit(PuzzleInitial());
61 | }
62 |
63 | _swipe(Swipe event, Emitter emit) {
64 | var ctx = event.context;
65 | if (!isFirstMove) {
66 | isFirstMove = true;
67 | // BlocProvider.of(event.context).add(TimerStarted());
68 | }
69 |
70 | Direction direction = event.direction;
71 | int i = event.row;
72 | int j = event.column;
73 | if (!(playingState[i][j] > 14)) {
74 | sound.play('audio/immutableTile.mp3', volume: volume);
75 | return false;
76 | }
77 |
78 | bool toMove = false;
79 |
80 | moveCounter++;
81 | switch (direction) {
82 | case Direction.up:
83 | if (playingState[i - 1][j] == 0) {
84 | toMove = true;
85 | playingState[i - 1][j] = playingState[i][j];
86 | }
87 | break;
88 | case Direction.down:
89 | if (playingState[i + 1][j] == 0) {
90 | toMove = true;
91 | playingState[i + 1][j] = playingState[i][j];
92 | }
93 | break;
94 | case Direction.left:
95 | if (playingState[i][j - 1] == 0) {
96 | toMove = true;
97 | playingState[i][j - 1] = playingState[i][j];
98 | }
99 | break;
100 | case Direction.right:
101 | if (playingState[i][j + 1] == 0) {
102 | toMove = true;
103 | playingState[i][j + 1] = playingState[i][j];
104 | }
105 | break;
106 | }
107 |
108 | if (toMove) {
109 | playingState[i][j] = 0;
110 | } else {
111 | sound.play('audio/immutableTile.mp3', volume: volume);
112 | return false;
113 | }
114 |
115 | sound.play('audio/ballTap.mp3', volume: volume);
116 | emit(TileMoved());
117 |
118 | bool hasCompleted = false;
119 | int pathWay = 0;
120 |
121 | if (winningStates.length > 1) {
122 | for (int i = 1; i < winningStates.length; i++) {
123 | if (checkWin(i)) {
124 | pathWay = i;
125 | }
126 | }
127 |
128 | bool otherPath = checkWin(pathWay);
129 | if (otherPath) {
130 | Level player = levelData.firstWhere((e) => '${e.levelNum}' == level);
131 | flow = [...player.flows[pathWay]];
132 | BlocProvider.of(ctx).add(InitalizeBall(ctx));
133 | }
134 | hasCompleted = checkWin(0) || otherPath;
135 | } else {
136 | hasCompleted = checkWin(0);
137 | }
138 |
139 | if (hasCompleted) {
140 | SharedPrefUtils.playerLevel = level;
141 | BlocProvider.of(event.context).add(
142 | TimerReset(moveCounter: moveCounter),
143 | );
144 | moveCounter = 0;
145 | BlocProvider.of(event.context).add(RollBall());
146 | }
147 | }
148 |
149 | checkWin(int index) {
150 | for (int i = 0; i < playingState.length; i++) {
151 | for (int j = 0; j < playingState[i].length; j++) {
152 | if (winningStates[index][i][j] != 0 &&
153 | playingState[i][j] != winningStates[index][i][j]) {
154 | return false;
155 | }
156 | }
157 | }
158 | return true;
159 | }
160 |
161 | static getBoardSize(BuildContext context) {
162 | final double _width = MediaQuery.of(context).size.width * 0.90;
163 | final double _height = MediaQuery.of(context).size.height * 0.90;
164 |
165 | final double boardSize = _width > _height ? _height : _width;
166 |
167 | return boardSize;
168 | }
169 | }
170 |
171 | enum Direction {
172 | up,
173 | down,
174 | left,
175 | right,
176 | }
177 |
178 | enum Position {
179 | up,
180 | down,
181 | left,
182 | right,
183 | }
184 |
--------------------------------------------------------------------------------
/lib/screens/puzzle/blocs/puzzle/puzzle_event.dart:
--------------------------------------------------------------------------------
1 | part of 'puzzle_bloc.dart';
2 |
3 | abstract class PuzzleEvent {
4 | const PuzzleEvent();
5 | }
6 |
7 | class InitPuzzle extends PuzzleEvent {
8 | final int level;
9 |
10 | InitPuzzle(this.level);
11 | }
12 |
13 | class Swipe extends PuzzleEvent {
14 | final BuildContext context;
15 | final Direction direction;
16 | final int row;
17 | final int column;
18 |
19 | Swipe(this.context, this.direction, this.row, this.column);
20 | }
21 |
--------------------------------------------------------------------------------
/lib/screens/puzzle/blocs/puzzle/puzzle_state.dart:
--------------------------------------------------------------------------------
1 | part of 'puzzle_bloc.dart';
2 |
3 | abstract class PuzzleState {
4 | const PuzzleState();
5 | }
6 |
7 | class PuzzleInitial extends PuzzleState {}
8 |
9 | class TileMoved extends PuzzleState {}
10 |
--------------------------------------------------------------------------------
/lib/screens/puzzle/blocs/timer/timer_bloc.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:convert';
3 | import 'package:bloc/bloc.dart';
4 | import 'package:flutter_bloc/flutter_bloc.dart';
5 | import 'package:way_for_ball/utils/shared_prefs.dart';
6 | part 'timer_event.dart';
7 | part 'timer_state.dart';
8 |
9 | class TimerBloc extends Bloc {
10 | static var duration = const Duration(seconds: 1);
11 | Timer timer = Timer(duration, () {});
12 | int playTime = 0;
13 | String time = "";
14 |
15 | TimerBloc() : super(const TimerInitial()) {
16 | on(_onStarted);
17 | on(_onReset);
18 | on(_onTicked);
19 | on(_onStop);
20 | }
21 |
22 | @override
23 | Future close() {
24 | timer.cancel();
25 | return super.close();
26 | }
27 |
28 | void _onStarted(TimerStarted event, Emitter emit) {
29 | add(TimerTicked());
30 | playTime = 0;
31 | timer = Timer.periodic(duration, (_) {
32 | playTime = playTime + 1;
33 | add(TimerTicked());
34 | });
35 | }
36 |
37 | void _onReset(TimerReset event, Emitter emit) {
38 | var dataMap = {
39 | "moves": event.moveCounter,
40 | "time": time,
41 | };
42 |
43 | String data = jsonEncode(dataMap);
44 |
45 | SharedPrefUtils.setUserStringValue(
46 | "level${SharedPrefUtils.playerLevel}", data);
47 |
48 | timer.cancel();
49 |
50 | emit(const TimerInitial());
51 | }
52 |
53 | _onStop(TimerStop event, Emitter emit) {
54 | timer.cancel();
55 |
56 | emit(const ResetTimer());
57 | }
58 |
59 | void _onTicked(TimerTicked event, Emitter emit) {
60 | // int hours = playTime ~/ (60 * 60) % 24;
61 | int minutes = (playTime ~/ 60) % 60;
62 | int seconds = playTime % 60;
63 |
64 | // String strHours = hours == 0 ? '' : '${format(hours)}:';
65 | String strHours = '';
66 | String strMinutes = format(minutes);
67 | String strSeconds = format(seconds);
68 |
69 | time = "$strHours$strMinutes:$strSeconds";
70 |
71 | emit(TimerRunInProgress(time: time));
72 | }
73 |
74 | static format(int str) {
75 | return str.toString().padLeft(2, '0');
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/lib/screens/puzzle/blocs/timer/timer_event.dart:
--------------------------------------------------------------------------------
1 | part of 'timer_bloc.dart';
2 |
3 | abstract class TimerEvent {
4 | const TimerEvent();
5 | }
6 |
7 | class TimerStarted extends TimerEvent {}
8 |
9 | class TimerReset extends TimerEvent {
10 | final int moveCounter;
11 |
12 | const TimerReset({required this.moveCounter});
13 | }
14 |
15 | class TimerStop extends TimerEvent {}
16 |
17 | class TimerTicked extends TimerEvent {}
18 |
--------------------------------------------------------------------------------
/lib/screens/puzzle/blocs/timer/timer_state.dart:
--------------------------------------------------------------------------------
1 | part of 'timer_bloc.dart';
2 |
3 | abstract class TimerState {
4 | const TimerState();
5 | }
6 |
7 | class TimerInitial extends TimerState {
8 | const TimerInitial() : super();
9 | }
10 |
11 | class TimerRunInProgress extends TimerState {
12 | final String time;
13 | const TimerRunInProgress({
14 | required this.time,
15 | });
16 | }
17 |
18 | class TimerRunComplete extends TimerState {
19 | const TimerRunComplete();
20 | }
21 |
22 | class ResetTimer extends TimerState {
23 | const ResetTimer();
24 | }
25 |
--------------------------------------------------------------------------------
/lib/screens/puzzle/puzzle_screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:animated_text_kit/animated_text_kit.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter_bloc/flutter_bloc.dart';
4 | import 'package:way_for_ball/screens/puzzle/blocs/ball/ball_bloc.dart';
5 | import 'package:way_for_ball/utils/shared_prefs.dart';
6 |
7 | import 'blocs/puzzle/puzzle_bloc.dart';
8 | import 'blocs/timer/timer_bloc.dart';
9 | import 'puzzle_widgets/widgets.dart';
10 |
11 | class PuzzleScreen extends StatefulWidget {
12 | final int? level;
13 | const PuzzleScreen({Key? key, this.level}) : super(key: key);
14 |
15 | @override
16 | _PuzzleScreenState createState() => _PuzzleScreenState();
17 | }
18 |
19 | class _PuzzleScreenState extends State {
20 | int playerLevel = int.parse(SharedPrefUtils.playerLevel);
21 | var disableTiles = true;
22 |
23 | @override
24 | void initState() {
25 | super.initState();
26 | context.read().add(InitPuzzle(widget.level ?? playerLevel));
27 | }
28 |
29 | @override
30 | Widget build(BuildContext context) {
31 | final double _width = MediaQuery.of(context).size.width;
32 | final double _height = MediaQuery.of(context).size.height;
33 |
34 | final bool widthLarger = _width > _height;
35 | final double _boardSize = PuzzleBloc.getBoardSize(context);
36 |
37 | return Scaffold(
38 | body: Stack(
39 | alignment: Alignment.center,
40 | children: [
41 | Background(
42 | child: SingleChildScrollView(
43 | child: Column(
44 | mainAxisAlignment: MainAxisAlignment.center,
45 | children: [
46 | const PuzzleTopView(),
47 | Row(
48 | mainAxisAlignment: MainAxisAlignment.center,
49 | crossAxisAlignment: CrossAxisAlignment.start,
50 | children: [
51 | Board(
52 | child: Stack(
53 | children: const [
54 | PuzzleView(),
55 | BallView(),
56 | ],
57 | ),
58 | ),
59 | widthLarger
60 | ? PuzzleBottomView(level: widget.level ?? playerLevel)
61 | : Container(),
62 | ],
63 | ),
64 | widthLarger
65 | ? Container()
66 | : PuzzleBottomView(level: widget.level ?? playerLevel),
67 | ],
68 | ),
69 | ),
70 | ),
71 | BlocBuilder(
72 | builder: (context, state) {
73 | if (state is BallInitial) {
74 | disableTiles = false;
75 | }
76 | if (state is BallRolling) {
77 | disableTiles = true;
78 | }
79 | if (state is BallRollComplete) {
80 | disableTiles = true;
81 | }
82 | return Stack(
83 | children: [
84 | AnimatedTextKit(
85 | totalRepeatCount: 1,
86 | onFinished: () {
87 | BlocProvider.of(context).add(TimerStarted());
88 | setState(() {
89 | disableTiles = false;
90 | });
91 | },
92 | pause: const Duration(milliseconds: 4),
93 | animatedTexts: [
94 | ScaleAnimatedText(
95 | 'Ready?',
96 | textStyle: const TextStyle(
97 | fontSize: 70.0,
98 | color: Colors.white,
99 | ),
100 | duration: const Duration(seconds: 1),
101 | ),
102 | ScaleAnimatedText(
103 | 'GO!!',
104 | textStyle: const TextStyle(
105 | fontSize: 70.0,
106 | color: Colors.white,
107 | ),
108 | duration: const Duration(seconds: 1),
109 | ),
110 | ],
111 | ),
112 | disableTiles
113 | ? Container(
114 | width: _boardSize,
115 | height: _boardSize,
116 | color: Colors.transparent,
117 | )
118 | : const SizedBox.shrink()
119 | ],
120 | );
121 | },
122 | )
123 | ],
124 | ),
125 | );
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/lib/screens/puzzle/puzzle_widgets/background.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_svg/svg.dart';
3 |
4 | class Background extends StatelessWidget {
5 | final Widget child;
6 | const Background({Key? key, required this.child}) : super(key: key);
7 |
8 | @override
9 | Widget build(BuildContext context) {
10 | double width = MediaQuery.of(context).size.width;
11 | double height = MediaQuery.of(context).size.height;
12 | final bool widthLarger = width > height;
13 | return Center(
14 | child: SizedBox(
15 | height: height,
16 | width: width,
17 | child: Stack(
18 | alignment: Alignment.center,
19 | children: [
20 | SizedBox(
21 | height: height,
22 | width: width,
23 | child: SvgPicture.asset(
24 | 'assets/images/board-background.svg',
25 | fit: BoxFit.cover,
26 | ),
27 | ),
28 | Positioned(
29 | top: widthLarger ? width * 0.05 : width * 0.12,
30 | left: widthLarger ? width * 0.80 : width * .70,
31 | child: SvgPicture.asset(
32 | 'assets/images/moon.svg',
33 | width: widthLarger ? width * .15 : width * 0.25,
34 | height: widthLarger ? width * .15 : width * 0.25,
35 | ),
36 | ),
37 | Container(
38 | alignment: Alignment.center,
39 | width: double.infinity,
40 | height: double.infinity,
41 | child: child,
42 | ),
43 | ],
44 | ),
45 | ),
46 | );
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/lib/screens/puzzle/puzzle_widgets/ball.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class Ball extends StatelessWidget {
4 | final double x;
5 | final double y;
6 | final double ballSize;
7 |
8 | const Ball(
9 | {Key? key, required this.x, required this.y, required this.ballSize})
10 | : super(key: key);
11 |
12 | @override
13 | Widget build(BuildContext context) {
14 | return Positioned(
15 | top: y,
16 | left: x,
17 | child: Container(
18 | width: ballSize,
19 | height: ballSize,
20 | decoration: const BoxDecoration(
21 | shape: BoxShape.circle,
22 | color: Colors.white,
23 | ),
24 | ),
25 | );
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/lib/screens/puzzle/puzzle_widgets/ball_view.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_bloc/flutter_bloc.dart';
3 | import 'package:way_for_ball/screens/puzzle/blocs/ball/ball_bloc.dart';
4 | import 'ball.dart';
5 |
6 | class BallView extends StatefulWidget {
7 | const BallView({Key? key}) : super(key: key);
8 |
9 | @override
10 | _BallViewState createState() => _BallViewState();
11 | }
12 |
13 | class _BallViewState extends State {
14 | @override
15 | Widget build(BuildContext context) {
16 | BlocProvider.of(context).add(InitalizeBall(context));
17 | return BlocBuilder(
18 | builder: (context, state) {
19 | final ballBloc = context.read();
20 | double ballX = ballBloc.ballX;
21 | double ballY = ballBloc.ballY;
22 | double ballSize = ballBloc.ballSize;
23 | if (state is BallRolling) {
24 | ballX = state.ballX;
25 | ballY = state.ballY;
26 | }
27 |
28 | // else {
29 | // BlocProvider.of(context).add(InitalizeBall(context));
30 | // }
31 | return Ball(x: ballX, y: ballY, ballSize: ballSize);
32 | },
33 | );
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/lib/screens/puzzle/puzzle_widgets/board.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class Board extends StatelessWidget {
4 | final Widget child;
5 | const Board({Key? key, required this.child}) : super(key: key);
6 |
7 | @override
8 | Widget build(BuildContext context) {
9 | final double _width = MediaQuery.of(context).size.width * 0.90;
10 | final double _height = MediaQuery.of(context).size.height * 0.90;
11 |
12 | final double _boardSize = _width > _height ? _height : _width;
13 |
14 | return Center(
15 | child: SizedBox(
16 | height: _boardSize,
17 | width: _boardSize,
18 | child: Stack(
19 | alignment: Alignment.center,
20 | children: [
21 | Container(
22 | height: MediaQuery.of(context).size.height * 0.90,
23 | width: MediaQuery.of(context).size.width * 0.90,
24 | clipBehavior: Clip.hardEdge,
25 | decoration: BoxDecoration(
26 | color: Colors.blue[300],
27 | borderRadius: BorderRadius.circular(8),
28 | boxShadow: const [
29 | BoxShadow(
30 | color: Colors.black87,
31 | blurRadius: 10,
32 | spreadRadius: 0,
33 | offset: Offset(0, 2.0),
34 | )
35 | ],
36 | ),
37 | ),
38 | child,
39 | ],
40 | ),
41 | ),
42 | );
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/lib/screens/puzzle/puzzle_widgets/puzzle_bottom_view.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_bloc/flutter_bloc.dart';
3 | import 'package:flutter_svg/svg.dart';
4 | import 'package:way_for_ball/screens/puzzle/blocs/ball/ball_bloc.dart';
5 | import 'package:way_for_ball/utils/popup/settings/volume.dart';
6 | import '../blocs/puzzle/puzzle_bloc.dart';
7 | import '../blocs/timer/timer_bloc.dart';
8 |
9 | class PuzzleBottomView extends StatefulWidget {
10 | final int level;
11 | const PuzzleBottomView({
12 | Key? key,
13 | required this.level,
14 | }) : super(key: key);
15 |
16 | @override
17 | _PuzzleBottomViewState createState() => _PuzzleBottomViewState();
18 | }
19 |
20 | class _PuzzleBottomViewState extends State {
21 | @override
22 | Widget build(BuildContext context) {
23 | final double _width = MediaQuery.of(context).size.width;
24 | final double _height = MediaQuery.of(context).size.height;
25 |
26 | final bool widthLarger = _width > _height;
27 |
28 | List buttons = [
29 | GameButton(
30 | "back",
31 | "Back",
32 | widthLarger: widthLarger,
33 | onTap: () {
34 | Navigator.of(context).pop();
35 | },
36 | ),
37 | const SizedBox(width: 8),
38 | GameButton(
39 | "restart",
40 | "Restart",
41 | widthLarger: widthLarger,
42 | onTap: () {
43 | context.read().add(InitPuzzle(widget.level));
44 | context.read().add(BallInitalize());
45 | context.read().add(InitalizeBall(context));
46 | context.read().add(TimerStop());
47 | context.read().add(TimerStarted());
48 | },
49 | ),
50 | const SizedBox(width: 8),
51 | GameButton(
52 | "setting",
53 | "Setting",
54 | onTap: () {
55 | Volume.show(context);
56 | },
57 | widthLarger: widthLarger,
58 | ),
59 | ];
60 |
61 | return Container(
62 | alignment: Alignment.center,
63 | child: widthLarger
64 | ? Column(
65 | mainAxisAlignment: MainAxisAlignment.center,
66 | children: buttons,
67 | )
68 | : Row(
69 | mainAxisAlignment: MainAxisAlignment.center,
70 | children: buttons,
71 | ),
72 | );
73 | }
74 | }
75 |
76 | class GameButton extends StatefulWidget {
77 | final String name;
78 | final String text;
79 | final VoidCallback onTap;
80 | final bool widthLarger;
81 | const GameButton(
82 | this.name,
83 | this.text, {
84 | Key? key,
85 | required this.onTap,
86 | required this.widthLarger,
87 | }) : super(key: key);
88 |
89 | @override
90 | State createState() => _GameButtonState();
91 | }
92 |
93 | class _GameButtonState extends State {
94 | bool disableButton = false;
95 |
96 | @override
97 | Widget build(BuildContext context) {
98 | return BlocBuilder(
99 | builder: (context, state) {
100 | if (state is BallRolling) {
101 | disableButton = true;
102 | } else {
103 | disableButton = false;
104 | }
105 | return Material(
106 | color: Colors.transparent,
107 | child: InkWell(
108 | onTap: disableButton ? null : widget.onTap,
109 | child: Column(
110 | children: [
111 | const SizedBox(height: 20),
112 | SizedBox(
113 | height: MediaQuery.of(context).size.height * 0.1,
114 | width: MediaQuery.of(context).size.width * 0.1,
115 | child: disableButton
116 | ? SvgPicture.asset(
117 | 'assets/images/disabled_${widget.name}.svg',
118 | )
119 | : SvgPicture.asset('assets/images/${widget.name}.svg'),
120 | ),
121 | ],
122 | ),
123 | ),
124 | );
125 | },
126 | );
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/lib/screens/puzzle/puzzle_widgets/puzzle_top_view.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_bloc/flutter_bloc.dart';
3 | import 'package:way_for_ball/screens/puzzle/blocs/timer/timer_bloc.dart';
4 |
5 | class PuzzleTopView extends StatefulWidget {
6 | const PuzzleTopView({Key? key}) : super(key: key);
7 |
8 | @override
9 | _PuzzleTopViewState createState() => _PuzzleTopViewState();
10 | }
11 |
12 | class _PuzzleTopViewState extends State {
13 | String time = '--';
14 | @override
15 | Widget build(BuildContext context) {
16 | return BlocBuilder(
17 | builder: (context, state) {
18 | if (state is TimerRunInProgress) {
19 | time = state.time;
20 | }
21 |
22 | if (state is ResetTimer) {
23 | time = '00:00';
24 | }
25 |
26 | return Padding(
27 | padding: const EdgeInsets.symmetric(vertical: 12),
28 | child: Text(
29 | time,
30 | style: const TextStyle(
31 | color: Colors.yellowAccent,
32 | fontWeight: FontWeight.bold,
33 | fontSize: 18,
34 | ),
35 | ),
36 | );
37 | },
38 | );
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/lib/screens/puzzle/puzzle_widgets/puzzle_view.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_bloc/flutter_bloc.dart';
3 | import 'package:flutter_svg/flutter_svg.dart';
4 | import 'package:way_for_ball/screens/puzzle/blocs/puzzle/puzzle_bloc.dart';
5 | import 'package:way_for_ball/widgets/slide_animation.dart';
6 | import 'package:way_for_ball/widgets/swipe_detector.dart';
7 |
8 | class PuzzleView extends StatefulWidget {
9 | const PuzzleView({
10 | Key? key,
11 | }) : super(key: key);
12 |
13 | @override
14 | _PuzzleViewState createState() => _PuzzleViewState();
15 | }
16 |
17 | class _PuzzleViewState extends State {
18 | List> level = [];
19 |
20 | int levelLength = 0;
21 | late PuzzleBloc puzzleBloc;
22 |
23 | @override
24 | void initState() {
25 | super.initState();
26 |
27 | puzzleBloc = context.read();
28 | }
29 |
30 | @override
31 | Widget build(BuildContext context) {
32 | final double _boardSize = PuzzleBloc.getBoardSize(context);
33 | return BlocBuilder(
34 | builder: (context, state) {
35 | if (state is PuzzleInitial) {
36 | level = puzzleBloc.playingState;
37 | levelLength = level.length;
38 | }
39 |
40 | return level.isEmpty
41 | ? const SizedBox()
42 | : GridView.builder(
43 | shrinkWrap: true,
44 | padding: EdgeInsets.zero,
45 | physics: const NeverScrollableScrollPhysics(),
46 | gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
47 | crossAxisCount: levelLength,
48 | ),
49 | itemCount: levelLength * levelLength,
50 | itemBuilder: (context, index) {
51 | int i, j = 0;
52 | i = (index / levelLength).floor();
53 | j = (index % levelLength);
54 | return SwipeDetector(
55 | onSwipeUp: () {
56 | puzzleBloc.add(Swipe(context, Direction.up, i, j));
57 | },
58 | onSwipeRight: () {
59 | puzzleBloc.add(Swipe(context, Direction.right, i, j));
60 | },
61 | onSwipeDown: () {
62 | puzzleBloc.add(Swipe(context, Direction.down, i, j));
63 | },
64 | onSwipeLeft: () {
65 | puzzleBloc.add(Swipe(context, Direction.left, i, j));
66 | },
67 | child: SlidingAnimation(
68 | index: j,
69 | child: SizedBox(
70 | width: _boardSize / puzzleBloc.numBlocks,
71 | height: _boardSize / puzzleBloc.numBlocks,
72 | child: SvgPicture.asset(
73 | 'assets/images/tiles/tile${level[i][j]}.svg',
74 | ),
75 | ),
76 | ),
77 | );
78 | },
79 | );
80 | },
81 | );
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/lib/screens/puzzle/puzzle_widgets/widgets.dart:
--------------------------------------------------------------------------------
1 | export 'background.dart';
2 | export 'ball.dart';
3 | export 'ball_view.dart';
4 | export 'board.dart';
5 | export 'puzzle_bottom_view.dart';
6 | export 'puzzle_top_view.dart';
7 | export 'puzzle_view.dart';
8 | export 'widgets.dart';
9 |
--------------------------------------------------------------------------------
/lib/screens/start/bloc/bird_bloc.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:bloc/bloc.dart';
4 | import 'package:flutter/material.dart';
5 |
6 | part 'bird_event.dart';
7 | part 'bird_state.dart';
8 |
9 | class BirdBloc extends Bloc {
10 | BirdBloc() : super(BirdInitial()) {
11 | on(_initializeBird);
12 | on(_moveBird);
13 | }
14 |
15 | double x = 0;
16 | double y = 0;
17 |
18 | _initializeBird(InitializeBird event, Emitter emit) {
19 | double width = MediaQuery.of(event.context).size.width;
20 | y = width * 0.15;
21 |
22 | Timer.periodic(const Duration(milliseconds: 20), (_) {
23 | if (x > width) {
24 | x = 0;
25 | } else {
26 | x += 4;
27 | }
28 |
29 | add(MoveBird());
30 | });
31 | }
32 |
33 | _moveBird(MoveBird event, Emitter emit) {
34 | emit(BirdMoving(x: x, y: y));
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/lib/screens/start/bloc/bird_event.dart:
--------------------------------------------------------------------------------
1 | part of 'bird_bloc.dart';
2 |
3 | abstract class BirdEvent {}
4 |
5 | class InitializeBird extends BirdEvent {
6 | final BuildContext context;
7 |
8 | InitializeBird(this.context);
9 | }
10 |
11 | class MoveBird extends BirdEvent {}
12 |
--------------------------------------------------------------------------------
/lib/screens/start/bloc/bird_state.dart:
--------------------------------------------------------------------------------
1 | part of 'bird_bloc.dart';
2 |
3 | abstract class BirdState {}
4 |
5 | class BirdInitial extends BirdState {}
6 |
7 | class BirdMoving extends BirdState {
8 | final double x;
9 | final double y;
10 |
11 | BirdMoving({
12 | required this.x,
13 | required this.y,
14 | });
15 | }
16 |
--------------------------------------------------------------------------------
/lib/screens/start/start_screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:way_for_ball/screens/start/start_widgets/background.dart';
3 | import 'package:way_for_ball/screens/start/start_widgets/button_play.dart';
4 | import 'package:way_for_ball/screens/start/start_widgets/logo.dart';
5 |
6 | import 'start_widgets/button_setting.dart';
7 |
8 | class StartScreen extends StatefulWidget {
9 | const StartScreen({Key? key}) : super(key: key);
10 |
11 | @override
12 | _StartScreenState createState() => _StartScreenState();
13 | }
14 |
15 | class _StartScreenState extends State {
16 | bool isSettingHovered = false;
17 | @override
18 | Widget build(BuildContext context) {
19 | return Background(
20 | child: Column(
21 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
22 | children: const [
23 | Logo(),
24 | ButtonPlay(),
25 | ButtonSetting(),
26 | ],
27 | ),
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/screens/start/start_widgets/background.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_bloc/flutter_bloc.dart';
3 | import 'package:flutter_svg/svg.dart';
4 | import 'package:way_for_ball/screens/start/bloc/bird_bloc.dart';
5 |
6 | import 'bird_container.dart';
7 |
8 | class Background extends StatefulWidget {
9 | final Widget child;
10 | const Background({Key? key, required this.child}) : super(key: key);
11 |
12 | @override
13 | State createState() => _BackgroundState();
14 | }
15 |
16 | class _BackgroundState extends State {
17 | double width = 0;
18 | double height = 0;
19 | bool widthLarger = false;
20 | double x = 0;
21 | double y = 0;
22 |
23 | @override
24 | void initState() {
25 | super.initState();
26 |
27 | WidgetsBinding.instance.addPostFrameCallback((_) {
28 | BlocProvider.of(context).add(InitializeBird(context));
29 | });
30 | }
31 |
32 | @override
33 | Widget build(BuildContext context) {
34 | width = MediaQuery.of(context).size.width;
35 | height = MediaQuery.of(context).size.height;
36 | widthLarger = width > height;
37 | return SizedBox(
38 | height: height,
39 | width: width,
40 | child: Stack(
41 | children: [
42 | SizedBox(
43 | height: height,
44 | width: width,
45 | child: SvgPicture.asset(
46 | 'assets/images/board-background.svg',
47 | height: height,
48 | width: width,
49 | fit: BoxFit.cover,
50 | // alignment: Alignment.center,
51 | ),
52 | ),
53 | Positioned(
54 | top: widthLarger ? width * 0.05 : width * 0.12,
55 | left: widthLarger ? width * 0.80 : width * .70,
56 | child: SvgPicture.asset(
57 | 'assets/images/moon.svg',
58 | width: widthLarger ? width * .15 : width * 0.25,
59 | height: widthLarger ? width * .15 : width * 0.25,
60 | ),
61 | ),
62 | Container(
63 | alignment: Alignment.center,
64 | width: double.infinity,
65 | height: double.infinity,
66 | child: widget.child,
67 | ),
68 | BlocBuilder(
69 | builder: (context, state) {
70 | if (state is BirdMoving) {
71 | x = state.x;
72 | y = state.y;
73 | }
74 | return BirdContainer(x: x, y: y);
75 | },
76 | ),
77 | ],
78 | ),
79 | );
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/lib/screens/start/start_widgets/bird.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:rive/rive.dart';
3 |
4 | class Bird extends StatelessWidget {
5 | final double x;
6 | final double y;
7 |
8 | const Bird({
9 | Key? key,
10 | required this.x,
11 | required this.y,
12 | }) : super(key: key);
13 |
14 | @override
15 | Widget build(BuildContext context) {
16 | double width = MediaQuery.of(context).size.width;
17 | double height = MediaQuery.of(context).size.height;
18 | final bool widthLarger = width > height;
19 |
20 | return Positioned(
21 | top: y,
22 | left: x,
23 | child: SizedBox(
24 | height: width * (widthLarger ? 0.05 : 0.2),
25 | width: width * (widthLarger ? 0.05 : 0.2),
26 | child: const RiveAnimation.asset('assets/rive/bird.riv'),
27 | ),
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/screens/start/start_widgets/bird_container.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:way_for_ball/screens/start/start_widgets/bird.dart';
5 |
6 | class BirdContainer extends StatefulWidget {
7 | final double x;
8 | final double y;
9 | const BirdContainer({Key? key, required this.x, required this.y})
10 | : super(key: key);
11 |
12 | @override
13 | State createState() => _BirdContainerState();
14 | }
15 |
16 | class _BirdContainerState extends State {
17 | @override
18 | Widget build(BuildContext context) {
19 | return getBirds(context);
20 | }
21 |
22 | getBirds(context) {
23 | double width = MediaQuery.of(context).size.width;
24 | double height = MediaQuery.of(context).size.height;
25 | final bool widthLarger = width > height;
26 |
27 | List birds = [];
28 | for (var i in List.generate(4, (_) => _)) {
29 | final random = Random(i);
30 |
31 | birds.add(
32 | Bird(
33 | x: widget.x * (i + 1),
34 | y: widget.y * ((widthLarger ? 0.2 : 0.5) + random.nextDouble()),
35 | ),
36 | );
37 | }
38 |
39 | return Stack(children: birds);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/lib/screens/start/start_widgets/button_play.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_svg/flutter_svg.dart';
3 | import 'package:way_for_ball/utils/popup/levels/levels_popup.dart';
4 |
5 | class ButtonPlay extends StatefulWidget {
6 | const ButtonPlay({Key? key}) : super(key: key);
7 |
8 | @override
9 | _ButtonPlayState createState() => _ButtonPlayState();
10 | }
11 |
12 | class _ButtonPlayState extends State {
13 | bool isHovered = false;
14 |
15 | static getRatioSize(BuildContext context) {
16 | final double _width = MediaQuery.of(context).size.width * 0.90;
17 | final double _height = MediaQuery.of(context).size.height * 0.90;
18 |
19 | final double ratioSize = _width > _height ? _height : _width;
20 |
21 | return ratioSize;
22 | }
23 |
24 | @override
25 | Widget build(BuildContext context) {
26 | double ratioSize = getRatioSize(context);
27 | return Material(
28 | color: Colors.transparent,
29 | shape: const CircleBorder(),
30 | clipBehavior: Clip.hardEdge,
31 | child: InkWell(
32 | onTap: () {
33 | LevelPopup.show(context);
34 | },
35 | onHover: (value) {
36 | setState(() {
37 | isHovered = value;
38 | });
39 | },
40 | child: SizedBox(
41 | width: ratioSize * 0.20,
42 | height: ratioSize * 0.20,
43 | child: isHovered
44 | ? SvgPicture.asset(
45 | 'assets/images/btn_play.svg',
46 | fit: BoxFit.cover,
47 | )
48 | : SvgPicture.asset(
49 | 'assets/images/btn_play.svg',
50 | fit: BoxFit.cover,
51 | ),
52 | ),
53 | ),
54 | );
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/lib/screens/start/start_widgets/button_setting.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_svg/flutter_svg.dart';
3 | import 'package:way_for_ball/utils/popup/settings/volume.dart';
4 |
5 | class ButtonSetting extends StatefulWidget {
6 | const ButtonSetting({Key? key}) : super(key: key);
7 |
8 | @override
9 | _ButtonSettingState createState() => _ButtonSettingState();
10 | }
11 |
12 | class _ButtonSettingState extends State {
13 | bool isHovered = false;
14 |
15 | static getRatioSize(BuildContext context) {
16 | final double _width = MediaQuery.of(context).size.width * 0.90;
17 | final double _height = MediaQuery.of(context).size.height * 0.90;
18 |
19 | final double ratioSize = _width > _height ? _height : _width;
20 |
21 | return ratioSize;
22 | }
23 |
24 | @override
25 | Widget build(BuildContext context) {
26 | double ratioSize = getRatioSize(context);
27 | return Material(
28 | color: Colors.transparent,
29 | shape: const CircleBorder(),
30 | clipBehavior: Clip.hardEdge,
31 | child: InkWell(
32 | onTap: () {
33 | Volume.show(context);
34 | },
35 | onHover: (value) {
36 | setState(() {
37 | isHovered = value;
38 | });
39 | },
40 | child: SizedBox(
41 | width: ratioSize * 0.20,
42 | height: ratioSize * 0.20,
43 | child: isHovered
44 | ? SvgPicture.asset(
45 | 'assets/images/btn_setting.svg',
46 | fit: BoxFit.cover,
47 | )
48 | : SvgPicture.asset(
49 | 'assets/images/btn_setting.svg',
50 | fit: BoxFit.cover,
51 | ),
52 | ),
53 | ),
54 | );
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/lib/screens/start/start_widgets/logo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_svg/flutter_svg.dart';
3 |
4 | class Logo extends StatefulWidget {
5 | const Logo({Key? key}) : super(key: key);
6 |
7 | @override
8 | _ButtonPlayState createState() => _ButtonPlayState();
9 | }
10 |
11 | class _ButtonPlayState extends State {
12 | @override
13 | Widget build(BuildContext context) {
14 | return Material(
15 | color: Colors.transparent,
16 | clipBehavior: Clip.hardEdge,
17 | child: SizedBox(
18 | width: MediaQuery.of(context).size.width * 0.90,
19 | child: SvgPicture.asset(
20 | 'assets/images/way_for_ball.svg',
21 | fit: BoxFit.contain,
22 | ),
23 | ),
24 | );
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/lib/utils/arc_map.dart:
--------------------------------------------------------------------------------
1 | class Arc {
2 | static Map arcMap = {
3 | "C_LU": {"direction": -1, "start": 90, "end": 0, "operator": ">"},
4 | "C_RU": {"direction": 1, "start": 90, "end": 180, "operator": "<"},
5 | "C_RB": {"direction": -1, "start": 270, "end": 180, "operator": ">"},
6 | "C_UL": {"direction": 1, "start": 0, "end": 90, "operator": "<"},
7 | "C_BL": {"direction": -1, "start": 0, "end": -90, "operator": ">"},
8 | "C_UR": {"direction": -1, "start": 180, "end": 90, "operator": ">"},
9 | "C_BR": {"direction": 1, "start": 180, "end": 270, "operator": "<"},
10 | "C_LB": {"direction": 1, "start": 270, "end": 360, "operator": "<"},
11 | "L_LR": {"direction": 1, "type": "H", "end": null, "operator": "<"},
12 | "L_RL": {"direction": -1, "type": "H", "end": null, "operator": ">"},
13 | "L_UD": {"direction": 1, "type": "V", "end": null, "operator": "<"},
14 | "L_DU": {"direction": -1, "type": "V", "end": null, "operator": ">"},
15 | };
16 | }
17 |
--------------------------------------------------------------------------------
/lib/utils/popup/levels/levels_popup.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/foundation.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
4 |
5 | import 'widgets/level_tile.dart';
6 |
7 | class LevelPopup {
8 | static show(BuildContext context) {
9 | var width = MediaQuery.of(context).size.width;
10 | showDialog(
11 | context: context,
12 | barrierDismissible: true,
13 | builder: (BuildContext context) {
14 | return AlertDialog(
15 | backgroundColor: Colors.transparent,
16 | content: Container(
17 | width: kIsWeb
18 | ? width < 576
19 | ? width * 0.90
20 | : 400
21 | : width * 0.90,
22 | padding: const EdgeInsets.all(10),
23 | decoration: BoxDecoration(
24 | color: const Color(0xff1e3266),
25 | borderRadius: BorderRadius.circular(20),
26 | ),
27 | child: Wrap(
28 | alignment: WrapAlignment.center,
29 | children: [
30 | const Text(
31 | "Select a Level",
32 | style: TextStyle(
33 | color: Colors.white,
34 | fontWeight: FontWeight.bold,
35 | ),
36 | ),
37 | const SizedBox(height: 20),
38 | StaggeredGrid.count(
39 | crossAxisCount: 4,
40 | crossAxisSpacing: width * 0.001,
41 | mainAxisSpacing: width * 0.001,
42 | children: List.generate(12, (index) {
43 | return LevelTile('${index + 1}');
44 | }),
45 | ),
46 | ],
47 | ),
48 | ),
49 | );
50 | },
51 | );
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/lib/utils/popup/levels/widgets/level_tile.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | import 'package:flutter/foundation.dart';
4 | import 'package:flutter/material.dart';
5 | import 'package:way_for_ball/utils/screens.dart';
6 | import 'package:way_for_ball/utils/shared_prefs.dart';
7 |
8 | class LevelTile extends StatelessWidget {
9 | final String level;
10 | const LevelTile(
11 | this.level, {
12 | Key? key,
13 | }) : super(key: key);
14 |
15 | @override
16 | Widget build(BuildContext context) {
17 | bool isNextLevel =
18 | int.parse(SharedPrefUtils.playerLevel) + 1 == int.parse(level);
19 | bool isUnlocked =
20 | SharedPrefUtils.getUserStringValue("level$level") != "" || isNextLevel;
21 | return InkWell(
22 | onTap: isUnlocked
23 | ? () {
24 | Navigator.pop(context);
25 | Navigator.pushNamed(
26 | context,
27 | Screens.puzzle_screen,
28 | arguments: int.parse(level),
29 | );
30 | }
31 | : null,
32 | child: Container(
33 | margin: kIsWeb ? const EdgeInsets.all(10) : null,
34 | decoration: BoxDecoration(
35 | color: const Color(0xff356cb1),
36 | borderRadius: BorderRadius.circular(10),
37 | boxShadow: [
38 | BoxShadow(
39 | color: Colors.black.withOpacity(0.5),
40 | blurRadius: 10,
41 | offset: const Offset(0, 10),
42 | ),
43 | ],
44 | ),
45 | child: Column(
46 | mainAxisAlignment: MainAxisAlignment.center,
47 | children: [
48 | isUnlocked
49 | ? Column(
50 | children: [
51 | Text(
52 | level,
53 | style: const TextStyle(
54 | color: Colors.white,
55 | fontWeight: FontWeight.w700,
56 | fontSize: 28,
57 | fontFamily: 'Shizuru',
58 | ),
59 | ),
60 | isNextLevel
61 | ? const Text(
62 | "0",
63 | style: TextStyle(
64 | color: Colors.transparent,
65 | fontWeight: FontWeight.w700,
66 | fontSize: 14,
67 | ),
68 | )
69 | : Text(
70 | getTime(level),
71 | style: const TextStyle(
72 | color: Colors.white,
73 | fontWeight: FontWeight.w700,
74 | fontSize: 14,
75 | ),
76 | ),
77 | ],
78 | )
79 | : Stack(
80 | alignment: Alignment.center,
81 | children: [
82 | Column(
83 | children: [
84 | Text(
85 | level,
86 | style: const TextStyle(
87 | color: Colors.transparent,
88 | fontWeight: FontWeight.w700,
89 | fontSize: 28,
90 | fontFamily: 'Shizuru',
91 | ),
92 | ),
93 | isNextLevel
94 | ? Container()
95 | : const Text(
96 | "0",
97 | style: TextStyle(
98 | color: Colors.transparent,
99 | fontWeight: FontWeight.w700,
100 | fontSize: 14,
101 | ),
102 | ),
103 | ],
104 | ),
105 | const Icon(Icons.lock, color: Colors.white),
106 | ],
107 | )
108 | ],
109 | ),
110 | ),
111 | );
112 | }
113 |
114 | static getData(String level) {
115 | var data = jsonDecode(
116 | SharedPrefUtils.getUserStringValue('level$level'),
117 | );
118 | return data;
119 | }
120 |
121 | static getTime(String level) {
122 | return getData(level)['time'].toString();
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/lib/utils/popup/settings/volume.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:way_for_ball/utils/shared_prefs.dart';
3 |
4 | class Volume {
5 | static show(BuildContext context) {
6 | double _currentSliderValue = 100;
7 | return showDialog(
8 | context: context,
9 | builder: (context) => AlertDialog(
10 | backgroundColor: const Color(0xff1e3266),
11 | content: SizedBox(
12 | width: 100,
13 | child: Wrap(
14 | alignment: WrapAlignment.center,
15 | children: [
16 | const Text(
17 | "Volume",
18 | style: TextStyle(
19 | color: Colors.white,
20 | fontWeight: FontWeight.bold,
21 | ),
22 | ),
23 | SoundSlider(
24 | onChanged: (value) {
25 | _currentSliderValue = value;
26 | },
27 | ),
28 | const SizedBox(height: 20),
29 | ElevatedButton(
30 | onPressed: () {
31 | SharedPrefUtils.volume = _currentSliderValue.toString();
32 | Navigator.pop(context);
33 | },
34 | style: ElevatedButton.styleFrom(
35 | primary: const Color(0xff356cb1),
36 | ),
37 | child: const Text("OK"),
38 | )
39 | ],
40 | ),
41 | ),
42 | ),
43 | );
44 | }
45 | }
46 |
47 | class SoundSlider extends StatefulWidget {
48 | final void Function(double) onChanged;
49 |
50 | const SoundSlider({Key? key, required this.onChanged}) : super(key: key);
51 |
52 | @override
53 | State createState() => _SoundSliderState();
54 | }
55 |
56 | class _SoundSliderState extends State {
57 | double _currentSliderValue = double.parse(SharedPrefUtils.volume);
58 |
59 | @override
60 | Widget build(BuildContext context) {
61 | return Slider(
62 | value: _currentSliderValue,
63 | max: 100,
64 | divisions: 5,
65 | activeColor: const Color(0xff356cb1),
66 | label: _currentSliderValue.round().toString(),
67 | onChanged: (double value) {
68 | setState(() {
69 | _currentSliderValue = value;
70 | widget.onChanged(value);
71 | });
72 | },
73 | );
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/lib/utils/popup/winning/widgets/win_button.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_svg/flutter_svg.dart';
3 |
4 | class WinButton extends StatelessWidget {
5 | final String name;
6 | final String text;
7 | final VoidCallback onTap;
8 |
9 | const WinButton({
10 | Key? key,
11 | required this.name,
12 | required this.text,
13 | required this.onTap,
14 | }) : super(key: key);
15 |
16 | @override
17 | Widget build(BuildContext context) {
18 | double width = MediaQuery.of(context).size.width;
19 | double height = MediaQuery.of(context).size.height;
20 | final bool widthLarger = width > height;
21 |
22 | return Material(
23 | color: Colors.transparent,
24 | child: InkWell(
25 | onTap: onTap,
26 | child: Column(
27 | children: [
28 | Container(
29 | clipBehavior: Clip.hardEdge,
30 | decoration: BoxDecoration(
31 | shape: BoxShape.circle,
32 | boxShadow: [
33 | BoxShadow(
34 | color: const Color(0xff444542),
35 | blurRadius: height * 0.010,
36 | spreadRadius: 0,
37 | offset: const Offset(0, 0),
38 | )
39 | ],
40 | ),
41 | child: SizedBox(
42 | height: widthLarger ? width * 0.04 : width * 0.1,
43 | width: widthLarger ? width * 0.04 : width * 0.1,
44 | child: SvgPicture.asset(
45 | 'assets/images/buttons/$name.svg',
46 | fit: BoxFit.cover,
47 | ),
48 | ),
49 | ),
50 | Material(
51 | color: Colors.transparent,
52 | child: Text(
53 | text,
54 | style: TextStyle(
55 | fontSize: height * 0.014,
56 | color: const Color(0xfffff0f5),
57 | fontWeight: FontWeight.w900,
58 | ),
59 | ),
60 | ),
61 | ],
62 | ),
63 | ),
64 | );
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/lib/utils/router.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_bloc/flutter_bloc.dart';
3 | import 'package:way_for_ball/screens/puzzle/blocs/ball/ball_bloc.dart';
4 | import 'package:way_for_ball/screens/puzzle/blocs/puzzle/puzzle_bloc.dart';
5 | import 'package:way_for_ball/screens/puzzle/blocs/timer/timer_bloc.dart';
6 | import 'package:way_for_ball/screens/puzzle/puzzle_screen.dart';
7 | import 'package:way_for_ball/screens/start/bloc/bird_bloc.dart';
8 | import 'package:way_for_ball/screens/start/start_screen.dart';
9 | import 'package:way_for_ball/utils/screens.dart';
10 |
11 | class AppRouter {
12 | Route generateRoute(RouteSettings settings) {
13 | switch (settings.name) {
14 | case '/':
15 | return MaterialPageRoute(
16 | builder: (context) => MultiBlocProvider(
17 | providers: [
18 | BlocProvider(
19 | create: (context) => PuzzleBloc(),
20 | ),
21 | BlocProvider(
22 | create: (context) => BallBloc(),
23 | ),
24 | BlocProvider(
25 | create: (context) => BirdBloc(),
26 | ),
27 | ],
28 | child: const StartScreen(),
29 | ),
30 | settings: settings,
31 | );
32 | case Screens.puzzle_screen:
33 | int? level = settings.arguments as int?;
34 | return MaterialPageRoute(
35 | builder: (context) => MultiBlocProvider(
36 | providers: [
37 | BlocProvider(
38 | create: (context) => PuzzleBloc(),
39 | ),
40 | BlocProvider(
41 | create: (context) => BallBloc(),
42 | ),
43 | BlocProvider(
44 | create: (context) => TimerBloc(),
45 | ),
46 | ],
47 | child: PuzzleScreen(level: level),
48 | ),
49 | settings: settings,
50 | );
51 |
52 | default:
53 | return MaterialPageRoute(
54 | builder: (context) => MultiBlocProvider(
55 | providers: [
56 | BlocProvider(
57 | create: (context) => PuzzleBloc(),
58 | ),
59 | BlocProvider(
60 | create: (context) => BallBloc(),
61 | ),
62 | BlocProvider(
63 | create: (context) => BirdBloc(),
64 | ),
65 | ],
66 | child: const StartScreen(),
67 | ),
68 | settings: settings,
69 | );
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/lib/utils/screens.dart:
--------------------------------------------------------------------------------
1 | class Screens {
2 | static const String puzzle_screen = 'puzzle_screen';
3 | }
4 |
--------------------------------------------------------------------------------
/lib/utils/shared_prefs.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 | import 'package:shared_preferences/shared_preferences.dart';
3 |
4 | class SharedPrefUtils {
5 | static const _APP_PREF = "APP_PREF";
6 | static const _USER_PREF = "USER_PREF";
7 |
8 | static const _PLAYER_LEVEL = "playerLevel";
9 | static const _PLAYER_COMPLETED_LEVEL = "playerCompletedLevel";
10 | static const _VOLUME = "volume";
11 |
12 | static final SharedPrefUtils _instance = SharedPrefUtils._ctor();
13 |
14 | factory SharedPrefUtils() {
15 | return _instance;
16 | }
17 |
18 | SharedPrefUtils._ctor();
19 |
20 | static late SharedPreferences _prefs;
21 |
22 | static init() async {
23 | _prefs = await SharedPreferences.getInstance();
24 | }
25 |
26 | // APP_DATA functions
27 |
28 | static setAppStringValue(String key, String value) {
29 | final String? storedData =
30 | _prefs.containsKey(_APP_PREF) ? _prefs.getString(_APP_PREF)! : null;
31 | Map newData = {key: value};
32 | Map newDataMap = {};
33 |
34 | if (storedData != null) {
35 | newDataMap.addAll(jsonDecode(storedData));
36 | newDataMap.addAll(newData);
37 | } else {
38 | newDataMap = newData;
39 | }
40 |
41 | _prefs.setString(_APP_PREF, jsonEncode(newDataMap));
42 | }
43 |
44 | static String getAppStringValue(String key) {
45 | Map allPrefs =
46 | jsonDecode(_prefs.getString(_APP_PREF) ?? '');
47 |
48 | return allPrefs[key] ?? "";
49 | }
50 |
51 | static Map getAllAppPrefs() {
52 | Map allPrefs = _prefs.containsKey(_APP_PREF)
53 | ? jsonDecode(_prefs.getString(_APP_PREF)!)
54 | : {};
55 | return allPrefs;
56 | }
57 |
58 | // USER_DATA functions
59 |
60 | static setUserStringValue(String key, String value) {
61 | final String? storedData =
62 | _prefs.containsKey(_USER_PREF) ? _prefs.getString(_USER_PREF) : null;
63 | Map newData = {key: value};
64 | Map newDataMap = {};
65 |
66 | if (storedData != null) {
67 | newDataMap.addAll(jsonDecode(storedData));
68 | newDataMap.addAll(newData);
69 | } else {
70 | newDataMap = newData;
71 | }
72 |
73 | _prefs.setString(_USER_PREF, jsonEncode(newDataMap));
74 | }
75 |
76 | static String getUserStringValue(String key) {
77 | Map allPrefs = _prefs.getString(_USER_PREF) != null
78 | ? jsonDecode(_prefs.getString(_USER_PREF) ?? '')
79 | : {};
80 | return allPrefs[key] ?? '';
81 | }
82 |
83 | static Map getAllUserPrefs() {
84 | Map allPrefs = _prefs.containsKey(_USER_PREF)
85 | ? jsonDecode(_prefs.getString(_USER_PREF)!)
86 | : {};
87 | return allPrefs;
88 | }
89 |
90 | static removeValue(String key) {
91 | return _prefs.remove(key);
92 | }
93 |
94 | static String get playerLevel => getUserStringValue(_PLAYER_LEVEL);
95 | static String get playerCompletedLevel =>
96 | getUserStringValue(_PLAYER_COMPLETED_LEVEL);
97 | static String get volume => getUserStringValue(_VOLUME);
98 |
99 | static set playerLevel(String value) =>
100 | setUserStringValue(_PLAYER_LEVEL, value);
101 |
102 | static set volume(String value) => setUserStringValue(_VOLUME, value);
103 | }
104 |
105 | enum PrefType { APP_PREF, USER_PREF }
106 |
107 | extension PrefExtension on PrefType {
108 | String get value {
109 | switch (this) {
110 | case PrefType.APP_PREF:
111 | return SharedPrefUtils._APP_PREF;
112 | case PrefType.USER_PREF:
113 | return SharedPrefUtils._USER_PREF;
114 | }
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/lib/widgets/slide_animation.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
3 |
4 | class SlidingAnimation extends StatelessWidget {
5 | final Widget child;
6 | final int index;
7 | const SlidingAnimation({
8 | Key? key,
9 | required this.child,
10 | required this.index,
11 | }) : super(key: key);
12 |
13 | @override
14 | Widget build(BuildContext context) {
15 | return AnimationConfiguration.staggeredList(
16 | position: index,
17 | duration: const Duration(milliseconds: 375),
18 | child: SlideAnimation(
19 | horizontalOffset: -50.0,
20 | child: FadeInAnimation(
21 | child: child,
22 | ),
23 | ),
24 | );
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/lib/widgets/swipe_detector.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class SwipeDetector extends StatelessWidget {
4 | static const double minMainDisplacement = 25;
5 | static const double maxCrossRatio = 0.75;
6 | static const double minVelocity = 30;
7 |
8 | final Widget child;
9 |
10 | final VoidCallback? onSwipeUp;
11 | final VoidCallback? onSwipeDown;
12 | final VoidCallback? onSwipeLeft;
13 | final VoidCallback? onSwipeRight;
14 |
15 | const SwipeDetector({
16 | Key? key,
17 | required this.child,
18 | this.onSwipeUp,
19 | this.onSwipeDown,
20 | this.onSwipeLeft,
21 | this.onSwipeRight,
22 | }) : super(key: key);
23 |
24 | @override
25 | Widget build(BuildContext context) {
26 | DragStartDetails? panStartDetails;
27 | DragUpdateDetails? panUpdateDetails;
28 |
29 | return GestureDetector(
30 | onTapDown: (_) => panUpdateDetails =
31 | null, // This prevents two fingers quick taps from being detected as a swipe
32 | behavior: HitTestBehavior
33 | .opaque, // This allows swipe above other clickable widgets
34 | child: child,
35 | onPanStart: (startDetails) => panStartDetails = startDetails,
36 | onPanUpdate: (updateDetails) => panUpdateDetails = updateDetails,
37 | onPanEnd: (endDetails) {
38 | if (panStartDetails == null || panUpdateDetails == null) return;
39 |
40 | double dx = panUpdateDetails!.globalPosition.dx -
41 | panStartDetails!.globalPosition.dx;
42 | double dy = panUpdateDetails!.globalPosition.dy -
43 | panStartDetails!.globalPosition.dy;
44 |
45 | int panDurationMiliseconds =
46 | panUpdateDetails!.sourceTimeStamp!.inMilliseconds -
47 | panStartDetails!.sourceTimeStamp!.inMilliseconds;
48 |
49 | double mainDis, crossDis, mainVel;
50 | bool isHorizontalMainAxis = dx.abs() > dy.abs();
51 |
52 | if (isHorizontalMainAxis) {
53 | mainDis = dx.abs();
54 | crossDis = dy.abs();
55 | } else {
56 | mainDis = dy.abs();
57 | crossDis = dx.abs();
58 | }
59 |
60 | mainVel = 1000 * mainDis / panDurationMiliseconds;
61 |
62 | if (mainDis < minMainDisplacement) {
63 | debugPrint(
64 | "SWIPE DEBUG | Displacement too short. Real: $mainDis - Min: $minMainDisplacement");
65 | return;
66 | }
67 | if (crossDis > maxCrossRatio * mainDis) {
68 | debugPrint(
69 | "SWIPE DEBUG | Cross axis displacemnt bigger than limit. Real: $crossDis - Limit: ${mainDis * maxCrossRatio}");
70 | return;
71 | }
72 | if (mainVel < minVelocity) {
73 | debugPrint(
74 | "SWIPE DEBUG | Swipe velocity too slow. Real: $mainVel - Min: $minVelocity");
75 | return;
76 | }
77 |
78 | // dy < 0 => UP -- dx > 0 => RIGHT
79 | if (isHorizontalMainAxis) {
80 | if (dx > 0) {
81 | onSwipeRight?.call();
82 | } else {
83 | onSwipeLeft?.call();
84 | }
85 | } else {
86 | if (dy < 0) {
87 | onSwipeUp?.call();
88 | } else {
89 | onSwipeDown?.call();
90 | }
91 | }
92 | },
93 | );
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: way_for_ball
2 | description: A new Flutter project.
3 | publish_to: none
4 | version: 1.0.0+1
5 |
6 | environment:
7 | sdk: ">=2.15.0 <3.0.0"
8 |
9 | dependencies:
10 | flutter:
11 | sdk: flutter
12 | bloc: ^8.0.2
13 | flutter_bloc: ^8.0.0
14 | url_launcher: ^6.0.17
15 | audioplayers: ^0.20.1
16 | gap: ^2.0.0
17 | flutter_svg: ^1.0.3
18 | shared_preferences: ^2.0.6
19 | lottie: ^1.2.1
20 | flutter_staggered_animations: ^1.0.0
21 | animated_text_kit: ^4.2.1
22 | flutter_staggered_grid_view: ^0.6.1
23 | url_strategy: ^0.2.0
24 | rive: ^0.8.4
25 |
26 | dev_dependencies:
27 | flutter_test:
28 | sdk: flutter
29 | flutter_lints: ^1.0.0
30 |
31 | flutter:
32 | uses-material-design: true
33 | assets:
34 | - assets/audio/
35 | - assets/lottie/
36 | - assets/rive/
37 | - assets/images/
38 | - assets/images/tiles/
39 | - assets/images/buttons/
40 | fonts:
41 | - family: Shizuru
42 | fonts:
43 | - asset: fonts/Shizuru/Shizuru-Regular.ttf
44 | - family: Cairo
45 | fonts:
46 | - asset: fonts/Cairo/Cairo-Regular.ttf
47 |
--------------------------------------------------------------------------------
/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | // This is a basic Flutter widget test.
2 | //
3 | // To perform an interaction with a widget in your test, use the WidgetTester
4 | // utility that Flutter provides. For example, you can send tap and scroll
5 | // gestures. You can also use WidgetTester to find child widgets in the widget
6 | // tree, read text, and verify that the values of widget properties are correct.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 |
11 | import 'package:way_for_ball/main.dart';
12 |
13 | void main() {
14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async {
15 | // Build our app and trigger a frame.
16 | await tester.pumpWidget(const MyApp());
17 |
18 | // Verify that our counter starts at 0.
19 | expect(find.text('0'), findsOneWidget);
20 | expect(find.text('1'), findsNothing);
21 |
22 | // Tap the '+' icon and trigger a frame.
23 | await tester.tap(find.byIcon(Icons.add));
24 | await tester.pump();
25 |
26 | // Verify that our counter has incremented.
27 | expect(find.text('0'), findsNothing);
28 | expect(find.text('1'), findsOneWidget);
29 | });
30 | }
31 |
--------------------------------------------------------------------------------
/web/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/web/favicon.png
--------------------------------------------------------------------------------
/web/icons/Icon-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/web/icons/Icon-192.png
--------------------------------------------------------------------------------
/web/icons/Icon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/web/icons/Icon-512.png
--------------------------------------------------------------------------------
/web/icons/Icon-maskable-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/web/icons/Icon-maskable-192.png
--------------------------------------------------------------------------------
/web/icons/Icon-maskable-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/web/icons/Icon-maskable-512.png
--------------------------------------------------------------------------------
/web/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | Way For Ball
38 |
39 |
40 |
41 |
44 |
108 |
109 |
110 |
--------------------------------------------------------------------------------
/web/main-background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nehal076/flutter-puzzle-hack/a8be1fad8576007d05b5d14005ef7e8e32d1c910/web/main-background.png
--------------------------------------------------------------------------------
/web/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "way_for_ball",
3 | "short_name": "way_for_ball",
4 | "start_url": ".",
5 | "display": "standalone",
6 | "background_color": "#0175C2",
7 | "theme_color": "#0175C2",
8 | "description": "A new Flutter project.",
9 | "orientation": "portrait-primary",
10 | "prefer_related_applications": false,
11 | "icons": [
12 | {
13 | "src": "icons/Icon-192.png",
14 | "sizes": "192x192",
15 | "type": "image/png"
16 | },
17 | {
18 | "src": "icons/Icon-512.png",
19 | "sizes": "512x512",
20 | "type": "image/png"
21 | },
22 | {
23 | "src": "icons/Icon-maskable-192.png",
24 | "sizes": "192x192",
25 | "type": "image/png",
26 | "purpose": "maskable"
27 | },
28 | {
29 | "src": "icons/Icon-maskable-512.png",
30 | "sizes": "512x512",
31 | "type": "image/png",
32 | "purpose": "maskable"
33 | }
34 | ]
35 | }
36 |
--------------------------------------------------------------------------------