├── .gitignore ├── .idea ├── .gitignore ├── .name ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── compiler.xml ├── gradle.xml ├── jarRepositories.xml └── misc.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ ├── cat_above.json │ ├── celebrate.json │ ├── coin.json │ ├── fire.json │ ├── plant.json │ ├── small_fire.json │ └── sparks.json │ ├── ic_launcher-playstore.png │ ├── java │ └── com │ │ └── thana │ │ └── simplegame │ │ ├── GameApplication.kt │ │ ├── data │ │ ├── common │ │ │ └── SharedPreferences.kt │ │ ├── model │ │ │ ├── GameInfo.kt │ │ │ └── LevelList.kt │ │ └── repository │ │ │ ├── sharedrepositoy │ │ │ ├── SharedRepository.kt │ │ │ └── SharedRepositoryImpl.kt │ │ │ └── soundrepository │ │ │ ├── SoundRepository.kt │ │ │ └── SoundRepositoryImpl.kt │ │ ├── di │ │ └── RepositoryModule.kt │ │ ├── ui │ │ ├── MainActivity.kt │ │ ├── SharedViewModel.kt │ │ ├── common │ │ │ ├── BaseFragment.kt │ │ │ └── FragmentViewBindingDelegate.kt │ │ ├── home │ │ │ ├── GameLevelsAdapter.kt │ │ │ ├── HomeFragment.kt │ │ │ └── LevelClickListeners.kt │ │ ├── level1 │ │ │ └── LevelOneFragment.kt │ │ ├── level10 │ │ │ └── LevelTenFragment.kt │ │ ├── level11 │ │ │ └── LevelElevenFragment.kt │ │ ├── level12 │ │ │ └── LevelTwelveFragment.kt │ │ ├── level13 │ │ │ └── LevelThirteenFragment.kt │ │ ├── level14 │ │ │ └── LevelFourteenFragment.kt │ │ ├── level15 │ │ │ └── LevelFifteenFragment.kt │ │ ├── level2 │ │ │ └── LevelTwoFragment.kt │ │ ├── level3 │ │ │ └── LevelThreeFragment.kt │ │ ├── level4 │ │ │ └── LevelFourFragment.kt │ │ ├── level5 │ │ │ └── LevelFiveFragment.kt │ │ ├── level6 │ │ │ └── LevelSixFragment.kt │ │ ├── level7 │ │ │ └── LevelSevenFragment.kt │ │ ├── level8 │ │ │ └── LevelEightFragment.kt │ │ ├── level9 │ │ │ └── LevelNineFragment.kt │ │ ├── profile │ │ │ └── ProfileFragment.kt │ │ └── settings │ │ │ └── SettingsFragment.kt │ │ └── util │ │ └── ViewExtensions.kt │ └── res │ ├── drawable-v24 │ └── ic_launcher_foreground.xml │ ├── drawable │ ├── bee.png │ ├── burger.png │ ├── button_3d.png │ ├── button_3d_image.xml │ ├── button_3d_image_yellow.xml │ ├── button_3d_yellow.png │ ├── cake.png │ ├── cake_2.png │ ├── circle.xml │ ├── controller.png │ ├── corn.png │ ├── cow.png │ ├── earth.png │ ├── eggs.png │ ├── elephant.png │ ├── fab_color.xml │ ├── flour.png │ ├── gem.png │ ├── gradient.xml │ ├── home_fab.xml │ ├── ic_about.xml │ ├── ic_add.xml │ ├── ic_check.xml │ ├── ic_collapse_arrow.xml │ ├── ic_contact.xml │ ├── ic_email.xml │ ├── ic_expand_arrow.xml │ ├── ic_help.xml │ ├── ic_home.xml │ ├── ic_minus.xml │ ├── ic_more.xml │ ├── ic_next.xml │ ├── ic_profile.xml │ ├── ic_settings.xml │ ├── ic_share.xml │ ├── ic_share_dark.xml │ ├── ic_star.xml │ ├── ic_wrong.xml │ ├── idea.png │ ├── lighter.png │ ├── line.png │ ├── lion.png │ ├── matches.png │ ├── medal.png │ ├── monitor.png │ ├── pancake.png │ ├── panda.png │ ├── pizza.png │ ├── popcorn.png │ ├── screw.png │ ├── screwdriver.png │ ├── tv.png │ ├── water.png │ ├── woman.png │ └── yellow_panda.png │ ├── font │ ├── bebas.ttf │ ├── inconsol.ttf │ └── pixel_font.ttf │ ├── layout │ ├── activity_main.xml │ ├── fragment_home.xml │ ├── fragment_level_eight.xml │ ├── fragment_level_eleven.xml │ ├── fragment_level_fifteen.xml │ ├── fragment_level_five.xml │ ├── fragment_level_four.xml │ ├── fragment_level_fourteen.xml │ ├── fragment_level_nine.xml │ ├── fragment_level_one.xml │ ├── fragment_level_seven.xml │ ├── fragment_level_six.xml │ ├── fragment_level_ten.xml │ ├── fragment_level_thirteen.xml │ ├── fragment_level_three.xml │ ├── fragment_level_twelve.xml │ ├── fragment_level_two.xml │ ├── fragment_profile.xml │ ├── fragment_settings.xml │ └── level_item.xml │ ├── menu │ └── button_menu.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ └── ic_launcher_foreground.png │ ├── mipmap-mdpi │ └── ic_launcher_foreground.png │ ├── mipmap-xhdpi │ └── ic_launcher_foreground.png │ ├── mipmap-xxhdpi │ └── ic_launcher_foreground.png │ ├── mipmap-xxxhdpi │ └── ic_launcher_foreground.png │ ├── navigation │ └── nav_graph.xml │ ├── raw │ ├── lose.wav │ └── win.wav │ ├── values-ar-rSA │ └── strings.xml │ └── values │ ├── arrays.xml │ ├── colors.xml │ ├── dimens.xml │ ├── ic_launcher_background.xml │ ├── strings.xml │ └── themes.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | Simple Game -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 119 | 120 | 122 | 123 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | 29 | 30 | 34 | 35 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 40 | 41 | 42 | 43 | 44 | 45 | 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Puzz 2 | 3 | Puzz is a puzzle game made with kotlin with more than 10 levels.
4 | 5 | ## Preview 6 | 7 | 8 |

9 | Get it on Google Play 11 |

12 | 13 | ## License 14 | 15 | ``` 16 | Copyright (C) 2021 Thana Abdullah 17 | 18 | This program is free software: you can redistribute it and/or modify 19 | it under the terms of the GNU General Public License as published by 20 | the Free Software Foundation, either version 3 of the License, or 21 | (at your option) any later version. 22 | 23 | This program is distributed in the hope that it will be useful, 24 | but WITHOUT ANY WARRANTY; without even the implied warranty of 25 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26 | GNU General Public License for more details. 27 | 28 | You should have received a copy of the GNU General Public License 29 | along with this program. If not, see https://www.gnu.org/licenses. 30 | ``` 31 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'kotlin-android' 4 | id 'kotlin-kapt' 5 | id 'dagger.hilt.android.plugin' 6 | id 'androidx.navigation.safeargs.kotlin' 7 | id 'kotlin-parcelize' 8 | } 9 | 10 | android { 11 | compileSdkVersion 31 12 | buildToolsVersion "30.0.3" 13 | 14 | defaultConfig { 15 | applicationId "com.thana.simplegame" 16 | minSdkVersion 25 17 | targetSdkVersion 31 18 | versionCode 1 19 | versionName "1.0" 20 | 21 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 22 | } 23 | 24 | buildTypes { 25 | release { 26 | minifyEnabled false 27 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 28 | } 29 | } 30 | compileOptions { 31 | sourceCompatibility JavaVersion.VERSION_1_8 32 | targetCompatibility JavaVersion.VERSION_1_8 33 | } 34 | kotlinOptions { 35 | jvmTarget = '1.8' 36 | } 37 | 38 | viewBinding { 39 | enabled = true 40 | } 41 | } 42 | 43 | dependencies { 44 | 45 | implementation 'androidx.constraintlayout:constraintlayout:2.1.1' 46 | implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5' 47 | implementation 'androidx.navigation:navigation-ui-ktx:2.3.5' 48 | implementation 'androidx.legacy:legacy-support-v4:1.0.0' 49 | implementation "com.google.dagger:hilt-android:$hilt_version" 50 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 51 | implementation 'androidx.recyclerview:recyclerview:1.2.1' 52 | implementation 'androidx.preference:preference:1.1.1' 53 | kapt "com.google.dagger:hilt-android-compiler:$hilt_version" 54 | implementation "com.squareup.retrofit2:retrofit:2.9.0" 55 | implementation "com.squareup.retrofit2:converter-scalars:2.6.0" 56 | implementation 'com.jakewharton.timber:timber:4.7.1' 57 | implementation "androidx.security:security-crypto:1.1.0-alpha03" 58 | implementation "com.squareup.okhttp3:logging-interceptor:4.9.0" 59 | implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1' 60 | implementation 'com.squareup.retrofit2:converter-gson:2.9.0' 61 | implementation "androidx.lifecycle:lifecycle-common-java8:2.3.1" 62 | implementation "com.google.android.material:material:1.4.0" 63 | implementation 'androidx.core:core-ktx:1.6.0' 64 | implementation 'androidx.appcompat:appcompat:1.3.1' 65 | implementation 'androidx.constraintlayout:constraintlayout:2.1.1' 66 | implementation "com.airbnb.android:lottie:4.2.0" 67 | implementation 'com.github.SMehranB:GlowNeonButton:2.0.1' 68 | implementation 'com.google.android.exoplayer:exoplayer:2.16.0' 69 | implementation 'com.google.android.play:core:1.10.2' 70 | implementation 'com.google.android.play:core-ktx:1.8.1' 71 | 72 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 14 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/GameApplication.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame 2 | 3 | import android.app.Application 4 | import dagger.hilt.android.HiltAndroidApp 5 | 6 | @HiltAndroidApp 7 | class GameApplication : Application() -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/data/common/SharedPreferences.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.data.common 2 | 3 | import android.app.Application 4 | import android.content.Context 5 | import android.content.SharedPreferences 6 | import javax.inject.Inject 7 | import javax.inject.Singleton 8 | 9 | @Singleton 10 | class SharedPreferences @Inject constructor(private val application: Application) { 11 | 12 | var sharedPreferences: SharedPreferences = 13 | application.getSharedPreferences(PREFERENCES, Context.MODE_PRIVATE) 14 | 15 | fun addScore() { 16 | setScore(getScore() + 1) 17 | } 18 | 19 | fun setScore(value: Int) { 20 | sharedPreferences.edit().putInt(SCORE, value).apply() 21 | } 22 | 23 | fun getScore(default: Int = 0) = sharedPreferences.getInt(SCORE, default) 24 | 25 | 26 | 27 | fun deletePref(key: String) { 28 | sharedPreferences.edit().remove(key).apply() 29 | } 30 | 31 | 32 | companion object { 33 | private const val SCORE = "score" 34 | private const val PREFERENCES = "My_PREFERENCES" 35 | } 36 | } -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/data/model/GameInfo.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.data.model 2 | 3 | data class GameInfo( 4 | val level: Int, 5 | val fragmentID: Int? = null 6 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/data/model/LevelList.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.data.model 2 | 3 | import com.thana.simplegame.R 4 | 5 | 6 | val levelList: List = listOf( 7 | GameInfo( 8 | level = 1, 9 | fragmentID = R.id.levelOneFragment 10 | ), 11 | GameInfo( 12 | level = 2, 13 | fragmentID = R.id.levelTwoFragment 14 | ), 15 | GameInfo( 16 | level = 3, 17 | fragmentID = R.id.levelThreeFragment 18 | ), 19 | GameInfo( 20 | level = 4, 21 | fragmentID = R.id.levelFourFragment 22 | ), 23 | GameInfo( 24 | level = 5, 25 | fragmentID = R.id.levelFiveFragment 26 | ), 27 | GameInfo( 28 | level = 6, 29 | fragmentID = R.id.levelSixFragment 30 | ), 31 | GameInfo( 32 | level = 7, 33 | fragmentID = R.id.levelSevenFragment 34 | ), 35 | GameInfo( 36 | level = 8, 37 | fragmentID = R.id.levelEightFragment 38 | ), 39 | GameInfo( 40 | level = 9, 41 | fragmentID = R.id.levelNineFragment 42 | ), 43 | GameInfo( 44 | level = 10, 45 | fragmentID = R.id.levelTenFragment 46 | ), 47 | GameInfo( 48 | level = 11, 49 | fragmentID = R.id.levelElevenFragment 50 | ), 51 | GameInfo( 52 | level = 12, 53 | fragmentID = R.id.levelTwelveFragment 54 | ), 55 | GameInfo( 56 | level = 13, 57 | fragmentID = R.id.levelThirteenFragment 58 | ), 59 | GameInfo( 60 | level = 14, 61 | fragmentID = R.id.levelFourteenFragment 62 | ), 63 | GameInfo( 64 | level = 15, 65 | fragmentID = R.id.levelFifteenFragment 66 | ) 67 | ) 68 | -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/data/repository/sharedrepositoy/SharedRepository.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.data.repository.sharedrepositoy 2 | 3 | interface SharedRepository { 4 | 5 | fun addScore() 6 | 7 | fun setScore(value: Int) 8 | 9 | fun getScore(): Int 10 | 11 | fun deletePref(key: String) 12 | } -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/data/repository/sharedrepositoy/SharedRepositoryImpl.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.data.repository.sharedrepositoy 2 | 3 | import com.thana.simplegame.data.common.SharedPreferences 4 | import com.thana.simplegame.data.repository.sharedrepositoy.SharedRepository 5 | import javax.inject.Inject 6 | 7 | class SharedRepositoryImpl @Inject constructor(private val sharedPreferences: SharedPreferences) : 8 | SharedRepository { 9 | 10 | override fun addScore() { 11 | sharedPreferences.addScore() 12 | } 13 | 14 | override fun setScore(value: Int) { 15 | sharedPreferences.setScore(value) 16 | } 17 | 18 | override fun getScore() = sharedPreferences.getScore() 19 | 20 | override fun deletePref(key: String) { 21 | sharedPreferences.deletePref(key) 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/data/repository/soundrepository/SoundRepository.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.data.repository.soundrepository 2 | 3 | interface SoundRepository { 4 | 5 | fun playWin() 6 | 7 | fun playLose() 8 | } -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/data/repository/soundrepository/SoundRepositoryImpl.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.data.repository.soundrepository 2 | 3 | import android.app.Application 4 | import com.google.android.exoplayer2.ExoPlayer 5 | import com.google.android.exoplayer2.MediaItem 6 | import com.google.android.exoplayer2.upstream.RawResourceDataSource 7 | import com.thana.simplegame.R 8 | import javax.inject.Inject 9 | 10 | class SoundRepositoryImpl @Inject constructor( application: Application) : 11 | SoundRepository { 12 | 13 | private var winAudio: ExoPlayer = ExoPlayer.Builder(application).build() 14 | private var loseAudio: ExoPlayer = ExoPlayer.Builder(application).build() 15 | 16 | 17 | override fun playWin() { 18 | val winUri = RawResourceDataSource.buildRawResourceUri(R.raw.win) 19 | 20 | winAudio.apply { 21 | setMediaItem(MediaItem.fromUri(winUri)) 22 | prepare() 23 | 24 | } 25 | 26 | winAudio.play() 27 | } 28 | 29 | override fun playLose() { 30 | val loseUri = RawResourceDataSource.buildRawResourceUri(R.raw.lose) 31 | 32 | 33 | loseAudio.apply { 34 | setMediaItem(MediaItem.fromUri(loseUri)) 35 | prepare() 36 | } 37 | loseAudio.play() 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/di/RepositoryModule.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.di 2 | 3 | import com.thana.simplegame.data.repository.sharedrepositoy.SharedRepository 4 | import com.thana.simplegame.data.repository.sharedrepositoy.SharedRepositoryImpl 5 | import com.thana.simplegame.data.repository.soundrepository.SoundRepository 6 | import com.thana.simplegame.data.repository.soundrepository.SoundRepositoryImpl 7 | import dagger.Binds 8 | import dagger.Module 9 | import dagger.hilt.InstallIn 10 | import dagger.hilt.components.SingletonComponent 11 | 12 | @Module 13 | @InstallIn(SingletonComponent::class) 14 | abstract class RepositoryModule { 15 | 16 | @Binds 17 | abstract fun provideSharedRepository( 18 | sharedRepositoryImpl: SharedRepositoryImpl 19 | ): SharedRepository 20 | 21 | @Binds 22 | abstract fun provideSoundRepository( 23 | soundRepositoryImpl: SoundRepositoryImpl 24 | ): SoundRepository 25 | } -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import androidx.navigation.NavController 6 | import androidx.navigation.findNavController 7 | import androidx.navigation.ui.NavigationUI 8 | import com.thana.simplegame.ui.common.viewBinding 9 | import com.thana.simplegame.R 10 | import com.thana.simplegame.databinding.ActivityMainBinding 11 | import dagger.hilt.android.AndroidEntryPoint 12 | 13 | @AndroidEntryPoint 14 | class MainActivity : AppCompatActivity() { 15 | 16 | private val binding by viewBinding(ActivityMainBinding::inflate) 17 | 18 | private lateinit var navController: NavController 19 | 20 | override fun onCreate(savedInstanceState: Bundle?) { 21 | super.onCreate(savedInstanceState) 22 | setContentView(binding.root) 23 | 24 | binding.fab.setOnClickListener { 25 | navController.navigate(R.id.homeFragment) 26 | } 27 | binding.bottomNavigationView.background = null 28 | 29 | 30 | binding.bottomNavigationView.menu.getItem(2).isEnabled = false 31 | 32 | binding.bottomNavigationView.menu.getItem(1).isEnabled = false 33 | 34 | navController = findNavController(R.id.nav_host_fragment) 35 | 36 | NavigationUI.setupWithNavController(binding.bottomNavigationView, navController) 37 | 38 | } 39 | 40 | override fun onSupportNavigateUp(): Boolean { 41 | return navController.navigateUp() || super.onSupportNavigateUp() 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/SharedViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui 2 | 3 | import androidx.lifecycle.ViewModel 4 | import com.thana.simplegame.data.repository.sharedrepositoy.SharedRepository 5 | import com.thana.simplegame.data.repository.soundrepository.SoundRepository 6 | import dagger.hilt.android.lifecycle.HiltViewModel 7 | import javax.inject.Inject 8 | import com.thana.simplegame.data.model.levelList 9 | 10 | @HiltViewModel 11 | class SharedViewModel @Inject constructor( 12 | private val sharedRepository: SharedRepository, 13 | private val soundRepository: SoundRepository 14 | ) : ViewModel() { 15 | 16 | var isExpanded = false 17 | 18 | fun getScore() = sharedRepository.getScore() 19 | 20 | fun addScore(levelNumber: Int) = 21 | if (sharedRepository.getScore() < levelNumber) sharedRepository.addScore() else Unit 22 | 23 | fun playWin() { 24 | soundRepository.playWin() 25 | } 26 | 27 | fun playLose() { 28 | soundRepository.playLose() 29 | } 30 | 31 | fun isLevelLocked(level: Int) = level > getScore() + 1 32 | 33 | fun getCoins() = getScore() / 2 34 | 35 | fun getGems() = getScore() * 13 36 | 37 | fun getProgress() = getScore() * 100 / levelList.last().level 38 | } -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/common/BaseFragment.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui.common 2 | 3 | import androidx.annotation.LayoutRes 4 | import androidx.fragment.app.Fragment 5 | 6 | abstract class BaseFragment(@LayoutRes contentLayoutId: Int) : Fragment(contentLayoutId) { 7 | 8 | } -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/common/FragmentViewBindingDelegate.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui.common 2 | 3 | import android.view.LayoutInflater 4 | import android.view.View 5 | import androidx.appcompat.app.AppCompatActivity 6 | import androidx.fragment.app.Fragment 7 | import androidx.lifecycle.DefaultLifecycleObserver 8 | import androidx.lifecycle.Lifecycle 9 | import androidx.lifecycle.LifecycleOwner 10 | import androidx.lifecycle.Observer 11 | import androidx.viewbinding.ViewBinding 12 | import com.google.android.material.bottomsheet.BottomSheetDialogFragment 13 | import kotlin.properties.ReadOnlyProperty 14 | import kotlin.reflect.KProperty 15 | 16 | class FragmentViewBindingDelegate( 17 | val fragment: Fragment, 18 | val viewBindingFactory: (View) -> T 19 | ) : ReadOnlyProperty { 20 | private var binding: T? = null 21 | 22 | init { 23 | fragment.lifecycle.addObserver(object : DefaultLifecycleObserver { 24 | val viewLifecycleOwnerLiveDataObserver = 25 | Observer { 26 | val viewLifecycleOwner = it ?: return@Observer 27 | 28 | viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver { 29 | override fun onDestroy(owner: LifecycleOwner) { 30 | binding = null 31 | } 32 | }) 33 | } 34 | 35 | override fun onCreate(owner: LifecycleOwner) { 36 | fragment.viewLifecycleOwnerLiveData.observeForever( 37 | viewLifecycleOwnerLiveDataObserver 38 | ) 39 | } 40 | 41 | override fun onDestroy(owner: LifecycleOwner) { 42 | fragment.viewLifecycleOwnerLiveData.removeObserver( 43 | viewLifecycleOwnerLiveDataObserver 44 | ) 45 | } 46 | }) 47 | } 48 | 49 | override fun getValue(thisRef: Fragment, property: KProperty<*>): T { 50 | val binding = binding 51 | if (binding != null) { 52 | return binding 53 | } 54 | 55 | val lifecycle = fragment.viewLifecycleOwner.lifecycle 56 | if (!lifecycle.currentState.isAtLeast(Lifecycle.State.INITIALIZED)) { 57 | throw IllegalStateException("Should not attempt to get bindings when Fragment views are destroyed.") 58 | } 59 | 60 | return viewBindingFactory(thisRef.requireView()).also { this.binding = it } 61 | } 62 | } 63 | 64 | fun Fragment.viewBinding(viewBindingFactory: (View) -> T) = 65 | FragmentViewBindingDelegate(this, viewBindingFactory) 66 | 67 | inline fun AppCompatActivity.viewBinding( 68 | crossinline bindingInflater: (LayoutInflater) -> T 69 | ) = 70 | lazy(LazyThreadSafetyMode.NONE) { 71 | bindingInflater.invoke(layoutInflater) 72 | } 73 | 74 | inline fun BottomSheetDialogFragment.viewBinding( 75 | crossinline bindingInflater: (LayoutInflater) -> T 76 | ) = 77 | lazy(LazyThreadSafetyMode.NONE) { 78 | bindingInflater.invoke(layoutInflater) 79 | } -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/home/GameLevelsAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui.home 2 | 3 | import android.view.LayoutInflater 4 | import android.view.ViewGroup 5 | import androidx.recyclerview.widget.AsyncListDiffer 6 | import androidx.recyclerview.widget.DiffUtil 7 | import androidx.recyclerview.widget.RecyclerView 8 | import com.thana.simplegame.R 9 | import com.thana.simplegame.data.model.GameInfo 10 | import com.thana.simplegame.databinding.LevelItemBinding 11 | 12 | class GameLevelsAdapter(private val clickListener: LevelClickListeners) : 13 | RecyclerView.Adapter() { 14 | 15 | val differ = AsyncListDiffer(this, object : DiffUtil.ItemCallback() { 16 | override fun areItemsTheSame(oldItem: GameInfo, newItem: GameInfo): Boolean { 17 | return oldItem.level == newItem.level 18 | } 19 | 20 | override fun areContentsTheSame(oldItem: GameInfo, newItem: GameInfo): Boolean { 21 | return oldItem == newItem 22 | } 23 | }) 24 | 25 | inner class LevelViewHolder(private val binding: LevelItemBinding) : 26 | RecyclerView.ViewHolder(binding.root) { 27 | fun bind(gameInfo: GameInfo) { 28 | 29 | binding.apply { 30 | 31 | levelName.text = 32 | "${binding.root.context.getString(R.string.level)} ${gameInfo.level}" 33 | 34 | if (clickListener.isLevelLocked(gameInfo.level)) { 35 | levelIcon.setColorFilter(R.color.gray) 36 | } else { 37 | root.setOnClickListener { 38 | if (gameInfo.fragmentID != null) 39 | clickListener.navigate(gameInfo.fragmentID) 40 | } 41 | } 42 | } 43 | } 44 | } 45 | 46 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LevelViewHolder { 47 | val binding = LevelItemBinding 48 | .inflate(LayoutInflater.from(parent.context), parent, false) 49 | return LevelViewHolder(binding) 50 | } 51 | 52 | override fun onBindViewHolder(holder: LevelViewHolder, position: Int) { 53 | val order = differ.currentList[position] 54 | holder.bind(order) 55 | } 56 | 57 | override fun getItemCount() = differ.currentList.size 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/home/HomeFragment.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui.home 2 | 3 | import android.os.Bundle 4 | import android.view.View 5 | import androidx.fragment.app.viewModels 6 | import androidx.navigation.fragment.findNavController 7 | import androidx.recyclerview.widget.GridLayoutManager 8 | import com.thana.simplegame.R 9 | import com.thana.simplegame.data.model.levelList 10 | import com.thana.simplegame.databinding.FragmentHomeBinding 11 | import com.thana.simplegame.ui.SharedViewModel 12 | import com.thana.simplegame.ui.common.BaseFragment 13 | import com.thana.simplegame.ui.common.viewBinding 14 | import dagger.hilt.android.AndroidEntryPoint 15 | 16 | 17 | @AndroidEntryPoint 18 | class HomeFragment : BaseFragment(R.layout.fragment_home) { 19 | 20 | private val binding by viewBinding(FragmentHomeBinding::bind) 21 | private lateinit var adapter: GameLevelsAdapter 22 | private val viewModel: SharedViewModel by viewModels() 23 | 24 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 25 | initAdapter() 26 | setScore() 27 | setGems() 28 | } 29 | 30 | private fun initAdapter() { 31 | 32 | binding.recyclerview.layoutManager = GridLayoutManager(requireActivity(), 3) 33 | 34 | adapter = GameLevelsAdapter(object : LevelClickListeners { 35 | override fun navigate(fragmentID: Int) { 36 | findNavController().navigate(fragmentID) 37 | } 38 | 39 | override fun isLevelLocked(level: Int): Boolean { 40 | return viewModel.isLevelLocked(level) 41 | } 42 | }) 43 | adapter.differ.submitList(levelList) 44 | binding.recyclerview.adapter = adapter 45 | } 46 | 47 | private fun setScore() { 48 | val coins = viewModel.getCoins() 49 | binding.score.text = coins.toString() 50 | } 51 | 52 | private fun setGems() { 53 | binding.gems.text = viewModel.getGems().toString() 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/home/LevelClickListeners.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui.home 2 | 3 | interface LevelClickListeners { 4 | 5 | fun navigate(fragmentID: Int) 6 | 7 | fun isLevelLocked(level:Int):Boolean 8 | } -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/level1/LevelOneFragment.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui.level1 2 | 3 | import android.annotation.SuppressLint 4 | import android.os.Bundle 5 | import android.view.DragEvent 6 | import android.view.MotionEvent 7 | import android.view.View 8 | import androidx.constraintlayout.widget.ConstraintLayout 9 | import androidx.fragment.app.viewModels 10 | import androidx.navigation.fragment.findNavController 11 | import com.google.android.exoplayer2.upstream.* 12 | import com.thana.simplegame.R 13 | import com.thana.simplegame.databinding.FragmentLevelOneBinding 14 | import com.thana.simplegame.ui.SharedViewModel 15 | import com.thana.simplegame.ui.common.BaseFragment 16 | import com.thana.simplegame.ui.common.viewBinding 17 | import com.thana.simplegame.util.hideKeyboard 18 | import dagger.hilt.android.AndroidEntryPoint 19 | 20 | @AndroidEntryPoint 21 | class LevelOneFragment : BaseFragment(R.layout.fragment_level_one), View.OnTouchListener, 22 | View.OnDragListener { 23 | 24 | private val binding by viewBinding(FragmentLevelOneBinding::bind) 25 | private val viewModel: SharedViewModel by viewModels() 26 | 27 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 28 | super.onViewCreated(view, savedInstanceState) 29 | 30 | binding.next.setOnClickListener { 31 | nextLevel() 32 | } 33 | 34 | setListeners() 35 | showHint() 36 | validateAnswer() 37 | 38 | } 39 | 40 | private fun showHint() = if (viewModel.isExpanded) { 41 | binding.hint.visibility = View.VISIBLE 42 | binding.expand.setIconResource(R.drawable.ic_collapse_arrow) 43 | } else { 44 | binding.hint.visibility = View.GONE 45 | binding.expand.setIconResource(R.drawable.ic_expand_arrow) 46 | } 47 | 48 | 49 | private fun nextLevel() { 50 | val action = LevelOneFragmentDirections.actionLevelOneFragmentToLevelTwoFragment() 51 | findNavController().navigate(action) 52 | } 53 | 54 | @SuppressLint("ClickableViewAccessibility") 55 | private fun setListeners() { 56 | binding.bee1.setOnTouchListener(this) 57 | binding.bee2.setOnTouchListener(this) 58 | binding.bee3.setOnTouchListener(this) 59 | binding.bee4.setOnTouchListener(this) 60 | binding.bee5.setOnTouchListener(this) 61 | binding.bee6.setOnTouchListener(this) 62 | binding.bee7.setOnTouchListener(this) 63 | binding.area.setOnDragListener(this) 64 | binding.input.setOnDragListener { _, _ -> 65 | 66 | return@setOnDragListener true 67 | } 68 | binding.editText.setOnDragListener { _, _ -> 69 | 70 | return@setOnDragListener true 71 | } 72 | binding.hintRoot.setOnClickListener { 73 | viewModel.isExpanded = !viewModel.isExpanded 74 | showHint() 75 | } 76 | binding.expand.setOnClickListener { 77 | viewModel.isExpanded = !viewModel.isExpanded 78 | showHint() 79 | } 80 | } 81 | 82 | private fun validateAnswer() { 83 | 84 | binding.submit.setOnClickListener { 85 | val input = binding.editText.text.toString().trim() 86 | if (input == "7") { 87 | binding.right.visibility = View.VISIBLE 88 | binding.wrong.visibility = View.GONE 89 | binding.celebrate.visibility = View.VISIBLE 90 | binding.celebrate.playAnimation() 91 | binding.submit.isEnabled = false 92 | binding.next.visibility = View.VISIBLE 93 | 94 | viewModel.playWin() 95 | 96 | viewModel.addScore(levelNumber = 1) 97 | 98 | } else { 99 | binding.wrong.visibility = View.VISIBLE 100 | binding.right.visibility = View.GONE 101 | 102 | viewModel.playLose() 103 | } 104 | hideKeyboard() 105 | } 106 | } 107 | 108 | 109 | override fun onDrag(layoutview: View, dragevent: DragEvent): Boolean { 110 | 111 | val view = dragevent.localState as View 112 | 113 | when (dragevent.action) { 114 | 115 | DragEvent.ACTION_DRAG_ENTERED -> { 116 | view.alpha = 0.3f 117 | view.visibility = View.INVISIBLE 118 | } 119 | DragEvent.ACTION_DROP -> { 120 | view.alpha = 1.0f 121 | val owner = binding.area 122 | owner.removeView(view) 123 | 124 | val container = layoutview as ConstraintLayout 125 | 126 | view.x = dragevent.x - (view.width / 2) 127 | view.y = dragevent.y - (view.height / 2) 128 | 129 | container.addView(view) 130 | view.visibility = View.VISIBLE 131 | } 132 | DragEvent.ACTION_DRAG_EXITED -> { 133 | view.alpha = 1.0f 134 | view.visibility = View.VISIBLE 135 | 136 | } 137 | 138 | } 139 | return true 140 | } 141 | 142 | 143 | override fun onTouch(view: View, motionEvent: MotionEvent): Boolean { 144 | 145 | return if (motionEvent.action == MotionEvent.ACTION_DOWN) { 146 | 147 | view.performClick() 148 | val shadowBuilder = View.DragShadowBuilder(view) 149 | 150 | view.startDragAndDrop(null, shadowBuilder, view, 0) 151 | 152 | true 153 | } else { 154 | 155 | false 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/level10/LevelTenFragment.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui.level10 2 | 3 | import android.annotation.SuppressLint 4 | import android.os.Bundle 5 | import android.view.DragEvent 6 | import android.view.MotionEvent 7 | import android.view.View 8 | import androidx.constraintlayout.widget.ConstraintLayout 9 | import androidx.fragment.app.viewModels 10 | import androidx.navigation.fragment.findNavController 11 | import com.thana.simplegame.R 12 | import com.thana.simplegame.databinding.FragmentLevelTenBinding 13 | import com.thana.simplegame.ui.SharedViewModel 14 | import com.thana.simplegame.ui.common.BaseFragment 15 | import com.thana.simplegame.ui.common.viewBinding 16 | import dagger.hilt.android.AndroidEntryPoint 17 | 18 | @AndroidEntryPoint 19 | class LevelTenFragment : BaseFragment(R.layout.fragment_level_ten), View.OnTouchListener, 20 | View.OnDragListener { 21 | 22 | private val binding by viewBinding(FragmentLevelTenBinding::bind) 23 | private val viewModel: SharedViewModel by viewModels() 24 | 25 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 26 | super.onViewCreated(view, savedInstanceState) 27 | 28 | setListeners() 29 | showHint() 30 | binding.next.setOnClickListener { 31 | nextLevel() 32 | } 33 | 34 | } 35 | 36 | private fun nextLevel() { 37 | val action = LevelTenFragmentDirections.actionLevelTenFragmentToLevelElevenFragment() 38 | findNavController().navigate(action) 39 | } 40 | 41 | 42 | @SuppressLint("ClickableViewAccessibility") 43 | private fun setListeners() { 44 | 45 | binding.yellow.setOnTouchListener(this) 46 | binding.area.setOnDragListener(this) 47 | binding.hintRoot.setOnClickListener { 48 | viewModel.isExpanded = !viewModel.isExpanded 49 | showHint() 50 | } 51 | binding.expand.setOnClickListener { 52 | viewModel.isExpanded = !viewModel.isExpanded 53 | showHint() 54 | } 55 | 56 | } 57 | 58 | private fun checkIfMixed(dragEvent: DragEvent, view: View) { 59 | 60 | val whitePandaXStart = binding.whitePanda.x 61 | val whitePandaYStart = binding.whitePanda.y 62 | 63 | val whitePandaXEnd = whitePandaXStart + binding.whitePanda.width 64 | val whitePandaEnd = whitePandaYStart + binding.whitePanda.height 65 | 66 | val yellowXStart = binding.yellow.x 67 | val yellowYStart = binding.yellow.y 68 | 69 | val yellowXEnd = yellowXStart + binding.yellow.width 70 | val yellowYEnd = yellowYStart + binding.yellow.height 71 | 72 | 73 | if (view.id == binding.yellow.id || view.id == binding.whitePanda.id) { 74 | if ( 75 | dragEvent.x in whitePandaXStart..whitePandaXEnd 76 | && dragEvent.y in whitePandaYStart..whitePandaEnd 77 | && dragEvent.x in yellowXStart..yellowXEnd 78 | && dragEvent.y in yellowYStart..yellowYEnd 79 | ) { 80 | 81 | correctAnswer() 82 | 83 | } 84 | } 85 | } 86 | 87 | private fun showHint() = if (viewModel.isExpanded) { 88 | binding.hint.visibility = View.VISIBLE 89 | binding.expand.setIconResource(R.drawable.ic_collapse_arrow) 90 | } else { 91 | binding.hint.visibility = View.GONE 92 | binding.expand.setIconResource(R.drawable.ic_expand_arrow) 93 | } 94 | 95 | 96 | private fun correctAnswer() { 97 | 98 | binding.yellowPanda.visibility = View.VISIBLE 99 | binding.yellow.visibility = View.INVISIBLE 100 | binding.whitePanda.visibility = View.INVISIBLE 101 | binding.right.visibility = View.VISIBLE 102 | binding.next.visibility = View.VISIBLE 103 | binding.celebrate.visibility = View.VISIBLE 104 | binding.celebrate.playAnimation() 105 | viewModel.playWin() 106 | 107 | viewModel.addScore(levelNumber = 10) 108 | 109 | } 110 | 111 | override fun onDrag(layoutview: View, dragevent: DragEvent): Boolean { 112 | 113 | val view = dragevent.localState as View 114 | 115 | when (dragevent.action) { 116 | 117 | DragEvent.ACTION_DRAG_ENTERED -> { 118 | view.alpha = 0.3f 119 | view.visibility = View.INVISIBLE 120 | 121 | } 122 | DragEvent.ACTION_DROP -> { 123 | view.alpha = 1.0f 124 | val owner = binding.area 125 | owner.removeView(view) 126 | 127 | val container = layoutview as ConstraintLayout 128 | 129 | view.x = dragevent.x - (view.width / 2) 130 | view.y = dragevent.y - (view.height / 2) 131 | container.addView(view) 132 | view.visibility = View.VISIBLE 133 | checkIfMixed(dragevent, view) 134 | 135 | } 136 | DragEvent.ACTION_DRAG_EXITED -> { 137 | view.alpha = 1.0f 138 | view.visibility = View.VISIBLE 139 | 140 | } 141 | 142 | } 143 | return true 144 | } 145 | 146 | 147 | override fun onTouch(view: View, motionEvent: MotionEvent): Boolean { 148 | 149 | return if (motionEvent.action == MotionEvent.ACTION_DOWN) { 150 | 151 | view.performClick() 152 | val shadowBuilder = View.DragShadowBuilder(view) 153 | 154 | view.startDragAndDrop(null, shadowBuilder, view, 0) 155 | 156 | true 157 | } else { 158 | false 159 | } 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/level11/LevelElevenFragment.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui.level11 2 | 3 | import android.annotation.SuppressLint 4 | import android.os.Bundle 5 | import android.view.DragEvent 6 | import android.view.MotionEvent 7 | import android.view.View 8 | import androidx.constraintlayout.widget.ConstraintLayout 9 | import androidx.fragment.app.viewModels 10 | import androidx.navigation.fragment.findNavController 11 | import com.thana.simplegame.R 12 | import com.thana.simplegame.databinding.FragmentLevelElevenBinding 13 | import com.thana.simplegame.ui.SharedViewModel 14 | import com.thana.simplegame.ui.common.BaseFragment 15 | import com.thana.simplegame.ui.common.viewBinding 16 | import dagger.hilt.android.AndroidEntryPoint 17 | 18 | @AndroidEntryPoint 19 | class LevelElevenFragment : BaseFragment(R.layout.fragment_level_eleven), View.OnTouchListener, 20 | View.OnDragListener { 21 | 22 | private val binding by viewBinding(FragmentLevelElevenBinding::bind) 23 | private val viewModel: SharedViewModel by viewModels() 24 | 25 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 26 | super.onViewCreated(view, savedInstanceState) 27 | 28 | setListeners() 29 | showHint() 30 | binding.next.setOnClickListener { 31 | nextLevel() 32 | } 33 | } 34 | 35 | private fun showHint() = if (viewModel.isExpanded) { 36 | binding.hint.visibility = View.VISIBLE 37 | binding.expand.setIconResource(R.drawable.ic_collapse_arrow) 38 | } else { 39 | binding.hint.visibility = View.GONE 40 | binding.expand.setIconResource(R.drawable.ic_expand_arrow) 41 | } 42 | 43 | private fun nextLevel() { 44 | val action = LevelElevenFragmentDirections.actionLevelElevenFragmentToLevelTwelveFragment() 45 | findNavController().navigate(action) 46 | } 47 | 48 | 49 | @SuppressLint("ClickableViewAccessibility") 50 | private fun setListeners() { 51 | 52 | binding.baby.setOnTouchListener(this) 53 | binding.lion.setOnTouchListener(this) 54 | binding.area.setOnDragListener(this) 55 | binding.hintRoot.setOnClickListener { 56 | viewModel.isExpanded = !viewModel.isExpanded 57 | showHint() 58 | } 59 | binding.expand.setOnClickListener { 60 | viewModel.isExpanded = !viewModel.isExpanded 61 | showHint() 62 | } 63 | } 64 | 65 | private fun checkIfTogether(dragEvent: DragEvent, view: View) { 66 | 67 | val babyXStart = binding.baby.x 68 | val babyYStart = binding.baby.y 69 | 70 | val babyXEnd = babyXStart + binding.baby.width 71 | val babyYEnd = babyYStart + binding.baby.height 72 | 73 | val elephantXStart = binding.elephant.x 74 | val elephantYStart = binding.elephant.y 75 | 76 | val elephantXEnd = elephantXStart + binding.elephant.width 77 | val elephantYEnd = elephantYStart + binding.elephant.height 78 | 79 | 80 | if (view.id == binding.baby.id || view.id == binding.elephant.id) { 81 | if (dragEvent.x in babyXStart..babyXEnd 82 | && dragEvent.y in babyYStart..babyYEnd 83 | && dragEvent.x in elephantXStart..elephantXEnd 84 | && dragEvent.y in elephantYStart..elephantYEnd 85 | 86 | ) { 87 | correctAnswer() 88 | } 89 | } 90 | } 91 | 92 | 93 | private fun correctAnswer() { 94 | 95 | binding.right.visibility = View.VISIBLE 96 | binding.next.visibility = View.VISIBLE 97 | binding.celebrate.visibility = View.VISIBLE 98 | binding.celebrate.playAnimation() 99 | viewModel.playWin() 100 | 101 | viewModel.addScore(levelNumber = 11) 102 | 103 | } 104 | 105 | override fun onDrag(layoutview: View, dragevent: DragEvent): Boolean { 106 | 107 | val view = dragevent.localState as View 108 | 109 | when (dragevent.action) { 110 | 111 | DragEvent.ACTION_DRAG_ENTERED -> { 112 | view.alpha = 0.3f 113 | view.visibility = View.INVISIBLE 114 | 115 | } 116 | DragEvent.ACTION_DROP -> { 117 | view.alpha = 1.0f 118 | val owner = binding.area 119 | owner.removeView(view) 120 | 121 | val container = layoutview as ConstraintLayout 122 | 123 | view.x = dragevent.x - (view.width / 2) 124 | view.y = dragevent.y - (view.height / 2) 125 | container.addView(view) 126 | view.visibility = View.VISIBLE 127 | checkIfTogether(dragevent, view) 128 | 129 | } 130 | DragEvent.ACTION_DRAG_EXITED -> { 131 | view.alpha = 1.0f 132 | view.visibility = View.VISIBLE 133 | 134 | } 135 | 136 | } 137 | return true 138 | } 139 | 140 | 141 | override fun onTouch(view: View, motionEvent: MotionEvent): Boolean { 142 | 143 | return if (motionEvent.action == MotionEvent.ACTION_DOWN) { 144 | 145 | view.performClick() 146 | val shadowBuilder = View.DragShadowBuilder(view) 147 | 148 | view.startDragAndDrop(null, shadowBuilder, view, 0) 149 | 150 | true 151 | } else { 152 | false 153 | } 154 | } 155 | } -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/level12/LevelTwelveFragment.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui.level12 2 | 3 | import android.annotation.SuppressLint 4 | import android.os.Bundle 5 | import android.view.DragEvent 6 | import android.view.MotionEvent 7 | import android.view.View 8 | import androidx.constraintlayout.widget.ConstraintLayout 9 | import androidx.fragment.app.viewModels 10 | import androidx.navigation.fragment.findNavController 11 | import com.thana.simplegame.R 12 | import com.thana.simplegame.databinding.FragmentLevelTwelveBinding 13 | import com.thana.simplegame.ui.SharedViewModel 14 | import com.thana.simplegame.ui.common.BaseFragment 15 | import com.thana.simplegame.ui.common.viewBinding 16 | import dagger.hilt.android.AndroidEntryPoint 17 | 18 | @AndroidEntryPoint 19 | class LevelTwelveFragment : BaseFragment(R.layout.fragment_level_twelve), View.OnTouchListener, 20 | View.OnDragListener { 21 | 22 | private val binding by viewBinding(FragmentLevelTwelveBinding::bind) 23 | private val viewModel: SharedViewModel by viewModels() 24 | 25 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 26 | super.onViewCreated(view, savedInstanceState) 27 | 28 | setListeners() 29 | showHint() 30 | binding.next.setOnClickListener { 31 | nextLevel() 32 | } 33 | 34 | } 35 | 36 | private fun showHint() = if (viewModel.isExpanded) { 37 | binding.hint.visibility = View.VISIBLE 38 | binding.expand.setIconResource(R.drawable.ic_collapse_arrow) 39 | } else { 40 | binding.hint.visibility = View.GONE 41 | binding.expand.setIconResource(R.drawable.ic_expand_arrow) 42 | } 43 | 44 | 45 | private fun nextLevel() { 46 | val action = 47 | LevelTwelveFragmentDirections.actionLevelTwelveFragmentToLevelThirteenFragment() 48 | findNavController().navigate(action) 49 | } 50 | 51 | @SuppressLint("ClickableViewAccessibility") 52 | private fun setListeners() { 53 | binding.swipeText.setOnTouchListener(this) 54 | binding.area.setOnDragListener(this) 55 | binding.hintRoot.setOnClickListener { 56 | viewModel.isExpanded = !viewModel.isExpanded 57 | showHint() 58 | } 59 | binding.expand.setOnClickListener { 60 | viewModel.isExpanded = !viewModel.isExpanded 61 | showHint() 62 | } 63 | } 64 | 65 | private fun checkIfMixed(dragEvent: DragEvent, view: View) { 66 | 67 | val correctAreaXStart = binding.correctArea.x 68 | val correctAreaYStart = binding.correctArea.y 69 | 70 | val correctAreaXEnd = correctAreaXStart + binding.correctArea.width 71 | val correctAreaYEnd = correctAreaYStart + binding.correctArea.height 72 | 73 | val textBallXStart = binding.swipeText.x 74 | val textBallYStart = binding.swipeText.y 75 | 76 | val textBallXEnd = textBallXStart + binding.swipeText.width 77 | val textBallYEnd = textBallYStart + binding.swipeText.height 78 | 79 | 80 | if (view.id == binding.correctArea.id || 81 | view.id == binding.swipeText.id 82 | ) { 83 | if (dragEvent.x in correctAreaXStart..correctAreaXEnd 84 | && dragEvent.y in correctAreaYStart..correctAreaYEnd 85 | && dragEvent.x in textBallXStart..textBallXEnd 86 | && dragEvent.y in textBallYStart..textBallYEnd 87 | 88 | ) { 89 | 90 | correctAnswer() 91 | 92 | } 93 | } 94 | } 95 | 96 | private fun correctAnswer() { 97 | 98 | binding.next.visibility = View.VISIBLE 99 | binding.celebrate.visibility = View.VISIBLE 100 | binding.right.visibility = View.VISIBLE 101 | binding.celebrate.playAnimation() 102 | viewModel.playWin() 103 | 104 | viewModel.addScore(levelNumber = 12) 105 | 106 | } 107 | 108 | override fun onDrag(layoutview: View, dragevent: DragEvent): Boolean { 109 | 110 | val view = dragevent.localState as View 111 | 112 | when (dragevent.action) { 113 | 114 | DragEvent.ACTION_DRAG_ENTERED -> { 115 | view.alpha = 0.3f 116 | view.visibility = View.INVISIBLE 117 | 118 | } 119 | DragEvent.ACTION_DROP -> { 120 | view.alpha = 1.0f 121 | val owner = binding.area 122 | owner.removeView(view) 123 | 124 | val container = layoutview as ConstraintLayout 125 | 126 | view.x = dragevent.x - (view.width / 2) 127 | view.y = dragevent.y - (view.height / 2) 128 | 129 | container.addView(view) 130 | view.visibility = View.VISIBLE 131 | checkIfMixed(dragevent, view) 132 | 133 | } 134 | DragEvent.ACTION_DRAG_EXITED -> { 135 | view.alpha = 1.0f 136 | view.visibility = View.VISIBLE 137 | 138 | } 139 | 140 | } 141 | return true 142 | } 143 | 144 | 145 | override fun onTouch(view: View, motionEvent: MotionEvent): Boolean { 146 | 147 | return if (motionEvent.action == MotionEvent.ACTION_DOWN) { 148 | 149 | view.performClick() 150 | val shadowBuilder = View.DragShadowBuilder(view) 151 | 152 | view.startDragAndDrop(null, shadowBuilder, view, 0) 153 | 154 | true 155 | } else { 156 | false 157 | } 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/level13/LevelThirteenFragment.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui.level13 2 | 3 | import android.annotation.SuppressLint 4 | import android.os.Bundle 5 | import android.util.Log 6 | import android.view.DragEvent 7 | import android.view.MotionEvent 8 | import android.view.View 9 | import android.view.ViewGroup 10 | import androidx.constraintlayout.widget.ConstraintLayout 11 | import androidx.fragment.app.viewModels 12 | import androidx.navigation.fragment.findNavController 13 | import com.thana.simplegame.R 14 | import com.thana.simplegame.databinding.FragmentLevelThirteenBinding 15 | import com.thana.simplegame.ui.SharedViewModel 16 | import com.thana.simplegame.ui.common.BaseFragment 17 | import com.thana.simplegame.ui.common.viewBinding 18 | import dagger.hilt.android.AndroidEntryPoint 19 | 20 | @AndroidEntryPoint 21 | class LevelThirteenFragment : BaseFragment(R.layout.fragment_level_thirteen), View.OnTouchListener, 22 | View.OnDragListener { 23 | 24 | private val binding by viewBinding(FragmentLevelThirteenBinding::bind) 25 | 26 | private val viewModel: SharedViewModel by viewModels() 27 | 28 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 29 | super.onViewCreated(view, savedInstanceState) 30 | 31 | setListeners() 32 | 33 | binding.next.setOnClickListener { 34 | nextLevel() 35 | } 36 | 37 | showHint() 38 | } 39 | 40 | private fun showHint() = if (viewModel.isExpanded) { 41 | binding.hint.visibility = View.VISIBLE 42 | binding.expand.setIconResource(R.drawable.ic_collapse_arrow) 43 | } else { 44 | binding.hint.visibility = View.GONE 45 | binding.expand.setIconResource(R.drawable.ic_expand_arrow) 46 | } 47 | 48 | private fun nextLevel() { 49 | 50 | val action = LevelThirteenFragmentDirections.actionLevelThirteenFragmentToLevelFourteenFragment() 51 | findNavController().navigate(action) 52 | } 53 | 54 | @SuppressLint("ClickableViewAccessibility") 55 | private fun setListeners() { 56 | binding.smallFire.setOnTouchListener(this) 57 | binding.area.setOnDragListener(this) 58 | binding.hintRoot.setOnClickListener { 59 | viewModel.isExpanded = !viewModel.isExpanded 60 | showHint() 61 | } 62 | binding.expand.setOnClickListener { 63 | viewModel.isExpanded = !viewModel.isExpanded 64 | showHint() 65 | } 66 | } 67 | 68 | 69 | override fun onDrag(layoutview: View, dragevent: DragEvent): Boolean { 70 | 71 | val view = dragevent.localState as View 72 | 73 | when (dragevent.action) { 74 | 75 | DragEvent.ACTION_DRAG_ENTERED -> { 76 | view.visibility = View.INVISIBLE 77 | } 78 | 79 | DragEvent.ACTION_DROP -> { 80 | view.alpha = 1.0f 81 | 82 | validateAnswer(dragevent) 83 | 84 | try { 85 | if (!wrongArea(dragevent)) { 86 | val owner = view.parent as ViewGroup 87 | owner.removeView(view) 88 | val container = layoutview as ConstraintLayout 89 | view.x = dragevent.x - (view.width / 2) 90 | view.y = dragevent.y - (view.height / 2) 91 | container.addView(view) 92 | } 93 | } catch (e: Exception) { 94 | Log.d("Draging", "Something went wrong") 95 | } 96 | 97 | view.visibility = View.VISIBLE 98 | } 99 | DragEvent.ACTION_DRAG_EXITED -> { 100 | view.alpha = 1.0f 101 | view.visibility = View.VISIBLE 102 | } 103 | 104 | } 105 | return true 106 | } 107 | 108 | 109 | private fun validateAnswer(dragEvent: DragEvent) { 110 | 111 | val fireXStart = binding.fireText.x 112 | val fireYStart = binding.fireText.y 113 | 114 | val faceXEnd = fireXStart + binding.fireText.width 115 | val faceYEnd = fireYStart + binding.fireText.height 116 | 117 | if (dragEvent.x in fireXStart..faceXEnd && dragEvent.y in fireYStart..faceYEnd) { 118 | binding.right.visibility = View.VISIBLE 119 | binding.next.visibility = View.VISIBLE 120 | binding.celebrate.visibility = View.VISIBLE 121 | binding.celebrate.playAnimation() 122 | binding.fire.visibility = View.VISIBLE 123 | viewModel.playWin() 124 | 125 | viewModel.addScore(levelNumber = 13) 126 | } 127 | 128 | } 129 | 130 | private fun wrongArea(dragEvent: DragEvent): Boolean { 131 | val areaXStart = binding.untouchable.x 132 | val areaYStart = binding.untouchable.y 133 | 134 | val areaXEnd = areaXStart + binding.untouchable.width 135 | val areaYEnd = areaYStart + binding.untouchable.height 136 | 137 | if (dragEvent.x in areaXStart..areaXEnd && dragEvent.y in areaYStart..areaYEnd) { 138 | return true 139 | } 140 | 141 | return false 142 | } 143 | 144 | 145 | override fun onTouch(view: View, motionEvent: MotionEvent): Boolean { 146 | 147 | return if (motionEvent.action == MotionEvent.ACTION_DOWN) { 148 | 149 | view.performClick() 150 | val shadowBuilder = View.DragShadowBuilder(view) 151 | view.startDragAndDrop(null, shadowBuilder, view, 0) 152 | 153 | true 154 | } else { 155 | 156 | false 157 | } 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/level14/LevelFourteenFragment.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui.level14 2 | 3 | import android.annotation.SuppressLint 4 | import android.os.Bundle 5 | import android.view.DragEvent 6 | import android.view.MotionEvent 7 | import android.view.View 8 | import androidx.constraintlayout.widget.ConstraintLayout 9 | import androidx.fragment.app.viewModels 10 | import androidx.navigation.fragment.findNavController 11 | import com.thana.simplegame.R 12 | import com.thana.simplegame.databinding.FragmentLevelFourteenBinding 13 | import com.thana.simplegame.ui.SharedViewModel 14 | import com.thana.simplegame.ui.common.BaseFragment 15 | import com.thana.simplegame.ui.common.viewBinding 16 | import com.thana.simplegame.ui.level4.LevelFourFragmentDirections 17 | import dagger.hilt.android.AndroidEntryPoint 18 | 19 | @AndroidEntryPoint 20 | class LevelFourteenFragment : BaseFragment(R.layout.fragment_level_fourteen), View.OnTouchListener, 21 | View.OnDragListener { 22 | 23 | private val binding by viewBinding(FragmentLevelFourteenBinding::bind) 24 | private val viewModel: SharedViewModel by viewModels() 25 | 26 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 27 | super.onViewCreated(view, savedInstanceState) 28 | 29 | setListeners() 30 | showHint() 31 | binding.next.setOnClickListener { 32 | nextLevel() 33 | } 34 | } 35 | 36 | private fun showHint() = if (viewModel.isExpanded) { 37 | binding.hint.visibility = View.VISIBLE 38 | binding.expand.setIconResource(R.drawable.ic_collapse_arrow) 39 | } else { 40 | binding.hint.visibility = View.GONE 41 | binding.expand.setIconResource(R.drawable.ic_expand_arrow) 42 | } 43 | 44 | private fun nextLevel() { 45 | val action = 46 | LevelFourteenFragmentDirections.actionLevelFourteenFragmentToLevelFifteenFragment() 47 | findNavController().navigate(action) 48 | } 49 | 50 | @SuppressLint("ClickableViewAccessibility") 51 | private fun setListeners() { 52 | binding.screw.setOnTouchListener(this) 53 | binding.screw2.setOnTouchListener(this) 54 | binding.screw3.setOnTouchListener(this) 55 | binding.screwDriver.setOnTouchListener(this) 56 | binding.wire.setOnTouchListener(this) 57 | binding.area.setOnDragListener(this) 58 | binding.hintRoot.setOnClickListener { 59 | viewModel.isExpanded = !viewModel.isExpanded 60 | showHint() 61 | } 62 | binding.expand.setOnClickListener { 63 | viewModel.isExpanded = !viewModel.isExpanded 64 | showHint() 65 | } 66 | } 67 | 68 | private fun checkIfPlugged(dragEvent: DragEvent, view: View) { 69 | 70 | val wireXStart = binding.wire.x 71 | val wireYStart = binding.wire.y 72 | 73 | val wireXEnd = wireXStart + binding.wire.width 74 | val wireYEnd = wireYStart + binding.wire.height 75 | 76 | val correctAreaXStart = binding.correctArea.x 77 | val correctAreaYStart = binding.correctArea.y 78 | 79 | val correctAreaXEnd = correctAreaXStart + binding.correctArea.width 80 | val correctAreaYEnd = correctAreaYStart + binding.correctArea.height 81 | 82 | 83 | if (view.id == binding.wire.id || view.id == binding.correctArea.id) { 84 | if (dragEvent.x in wireXStart..wireXEnd 85 | && dragEvent.y in wireYStart..wireYEnd 86 | && dragEvent.x in correctAreaXStart..correctAreaXEnd 87 | && dragEvent.y in correctAreaYStart..correctAreaYEnd 88 | ) { 89 | correctAnswer() 90 | } 91 | } 92 | } 93 | 94 | 95 | private fun correctAnswer() { 96 | binding.right.visibility = View.VISIBLE 97 | binding.next.visibility = View.VISIBLE 98 | binding.celebrate.visibility = View.VISIBLE 99 | binding.plug.visibility = View.VISIBLE 100 | binding.wire.visibility = View.GONE 101 | binding.celebrate.playAnimation() 102 | viewModel.playWin() 103 | 104 | viewModel.addScore(levelNumber = 14) 105 | 106 | } 107 | 108 | override fun onDrag(layoutview: View, dragevent: DragEvent): Boolean { 109 | 110 | val view = dragevent.localState as View 111 | 112 | when (dragevent.action) { 113 | 114 | DragEvent.ACTION_DRAG_ENTERED -> { 115 | view.alpha = 0.3f 116 | view.visibility = View.INVISIBLE 117 | 118 | } 119 | DragEvent.ACTION_DRAG_STARTED -> { 120 | view.rotation = 90f 121 | } 122 | 123 | DragEvent.ACTION_DROP -> { 124 | view.alpha = 1.0f 125 | val owner = binding.area 126 | owner.removeView(view) 127 | 128 | val container = layoutview as ConstraintLayout 129 | 130 | view.x = dragevent.x - (view.width / 2) 131 | view.y = dragevent.y - (view.height / 2) 132 | container.addView(view) 133 | view.visibility = View.VISIBLE 134 | checkIfPlugged(dragevent, view) 135 | 136 | } 137 | DragEvent.ACTION_DRAG_EXITED -> { 138 | view.alpha = 1.0f 139 | view.visibility = View.VISIBLE 140 | 141 | } 142 | 143 | } 144 | return true 145 | } 146 | 147 | 148 | override fun onTouch(view: View, motionEvent: MotionEvent): Boolean { 149 | 150 | return if (motionEvent.action == MotionEvent.ACTION_DOWN) { 151 | 152 | view.performClick() 153 | val shadowBuilder = View.DragShadowBuilder(view) 154 | 155 | view.startDragAndDrop(null, shadowBuilder, view, 0) 156 | 157 | true 158 | } else { 159 | false 160 | } 161 | } 162 | } -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/level15/LevelFifteenFragment.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui.level15 2 | 3 | import android.annotation.SuppressLint 4 | import android.os.Bundle 5 | import android.view.DragEvent 6 | import android.view.MotionEvent 7 | import android.view.View 8 | import androidx.constraintlayout.widget.ConstraintLayout 9 | import androidx.fragment.app.viewModels 10 | import com.thana.simplegame.R 11 | import com.thana.simplegame.databinding.FragmentLevelFifteenBinding 12 | import com.thana.simplegame.ui.SharedViewModel 13 | import com.thana.simplegame.ui.common.BaseFragment 14 | import com.thana.simplegame.ui.common.viewBinding 15 | import dagger.hilt.android.AndroidEntryPoint 16 | 17 | @AndroidEntryPoint 18 | class LevelFifteenFragment : BaseFragment(R.layout.fragment_level_fifteen), View.OnTouchListener, 19 | View.OnDragListener { 20 | 21 | private val binding by viewBinding(FragmentLevelFifteenBinding::bind) 22 | private val viewModel: SharedViewModel by viewModels() 23 | 24 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 25 | super.onViewCreated(view, savedInstanceState) 26 | 27 | setListeners() 28 | showHint() 29 | 30 | } 31 | 32 | private fun showHint() = if (viewModel.isExpanded) { 33 | binding.hint.visibility = View.VISIBLE 34 | binding.expand.setIconResource(R.drawable.ic_collapse_arrow) 35 | } else { 36 | binding.hint.visibility = View.GONE 37 | binding.expand.setIconResource(R.drawable.ic_expand_arrow) 38 | } 39 | 40 | 41 | @SuppressLint("ClickableViewAccessibility") 42 | private fun setListeners() { 43 | binding.lighter.setOnTouchListener(this) 44 | binding.tv.setOnTouchListener(this) 45 | binding.smallFire.setOnTouchListener(this) 46 | binding.area.setOnDragListener(this) 47 | binding.hintRoot.setOnClickListener { 48 | viewModel.isExpanded = !viewModel.isExpanded 49 | showHint() 50 | } 51 | binding.expand.setOnClickListener { 52 | viewModel.isExpanded = !viewModel.isExpanded 53 | showHint() 54 | } 55 | } 56 | 57 | private fun lightUp(dragEvent: DragEvent, view: View) { 58 | 59 | val lighterAreaXStart = binding.lighter.x 60 | val lighterAreaYStart = binding.lighter.y 61 | 62 | val lighterAreaXEnd = lighterAreaXStart + binding.lighter.width 63 | val lighterAreaYEnd = lighterAreaYStart + binding.lighter.height 64 | 65 | val matchesAreaXStart = binding.matches.x 66 | val matchesAreaYStart = binding.matches.y 67 | 68 | val matchesAreaXEnd = lighterAreaXStart + binding.matches.width 69 | val matchesAreaYEnd = lighterAreaYStart + binding.matches.height 70 | 71 | if (view.id == binding.lighter.id || 72 | view.id == binding.matches.id 73 | ) { 74 | if (dragEvent.x in lighterAreaXStart..lighterAreaXEnd 75 | && dragEvent.y in lighterAreaYStart..lighterAreaYEnd 76 | && dragEvent.x in matchesAreaXStart..matchesAreaXEnd 77 | && dragEvent.y in matchesAreaYStart..matchesAreaYEnd 78 | 79 | ) { 80 | binding.matches.visibility = View.GONE 81 | binding.smallFire.visibility = View.VISIBLE 82 | 83 | } 84 | } 85 | } 86 | 87 | private fun makePopcorn(dragEvent: DragEvent, view: View) { 88 | 89 | val smallFireAreaXStart = binding.smallFire.x 90 | val smallFireAreaYStart = binding.smallFire.y 91 | 92 | val smallFireAreaXEnd = smallFireAreaXStart + binding.smallFire.width 93 | val smallFireAreaYEnd = smallFireAreaYStart + binding.smallFire.height 94 | 95 | val cornAreaXStart = binding.corn.x 96 | val cornAreaYStart = binding.corn.y 97 | 98 | val cornAreaXEnd = cornAreaXStart + binding.corn.width 99 | val cornAreaYEnd = cornAreaYStart + binding.corn.height 100 | 101 | 102 | 103 | if (view.id == binding.smallFire.id || 104 | view.id == binding.corn.id 105 | ) { 106 | if (dragEvent.x in smallFireAreaXStart..smallFireAreaXEnd 107 | && dragEvent.y in smallFireAreaYStart..smallFireAreaYEnd 108 | && dragEvent.x in cornAreaXStart..cornAreaXEnd 109 | && dragEvent.y in cornAreaYStart..cornAreaYEnd 110 | 111 | ) { 112 | 113 | correctAnswer() 114 | 115 | } 116 | } 117 | } 118 | 119 | private fun correctAnswer() { 120 | 121 | binding.lighter.visibility = View.GONE 122 | binding.popcorn.visibility = View.VISIBLE 123 | binding.corn.visibility = View.GONE 124 | binding.celebrate.visibility = View.VISIBLE 125 | binding.right.visibility = View.VISIBLE 126 | binding.celebrate.playAnimation() 127 | viewModel.playWin() 128 | 129 | viewModel.addScore(levelNumber = 15) 130 | 131 | } 132 | 133 | override fun onDrag(layoutview: View, dragevent: DragEvent): Boolean { 134 | 135 | val view = dragevent.localState as View 136 | 137 | when (dragevent.action) { 138 | 139 | DragEvent.ACTION_DRAG_ENTERED -> { 140 | view.alpha = 0.3f 141 | view.visibility = View.INVISIBLE 142 | 143 | } 144 | DragEvent.ACTION_DROP -> { 145 | view.alpha = 1.0f 146 | val owner = binding.area 147 | owner.removeView(view) 148 | 149 | val container = layoutview as ConstraintLayout 150 | 151 | view.x = dragevent.x - (view.width / 2) 152 | view.y = dragevent.y - (view.height / 2) 153 | 154 | container.addView(view) 155 | view.visibility = View.VISIBLE 156 | lightUp(dragevent, view) 157 | makePopcorn(dragevent, view) 158 | } 159 | DragEvent.ACTION_DRAG_EXITED -> { 160 | view.alpha = 1.0f 161 | view.visibility = View.VISIBLE 162 | 163 | } 164 | 165 | } 166 | return true 167 | } 168 | 169 | override fun onTouch(view: View, motionEvent: MotionEvent): Boolean { 170 | 171 | return if (motionEvent.action == MotionEvent.ACTION_DOWN) { 172 | 173 | view.performClick() 174 | val shadowBuilder = View.DragShadowBuilder(view) 175 | 176 | view.startDragAndDrop(null, shadowBuilder, view, 0) 177 | 178 | true 179 | } else { 180 | false 181 | } 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/level2/LevelTwoFragment.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui.level2 2 | 3 | import android.os.Bundle 4 | import android.view.View 5 | import androidx.fragment.app.viewModels 6 | import androidx.navigation.fragment.findNavController 7 | import com.thana.simplegame.R 8 | import com.thana.simplegame.databinding.FragmentLevelTwoBinding 9 | import com.thana.simplegame.ui.SharedViewModel 10 | import com.thana.simplegame.ui.common.BaseFragment 11 | import com.thana.simplegame.ui.common.viewBinding 12 | import dagger.hilt.android.AndroidEntryPoint 13 | 14 | @AndroidEntryPoint 15 | class LevelTwoFragment : BaseFragment(R.layout.fragment_level_two) { 16 | 17 | private val binding by viewBinding(FragmentLevelTwoBinding::bind) 18 | private val viewModel: SharedViewModel by viewModels() 19 | 20 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 21 | super.onViewCreated(view, savedInstanceState) 22 | 23 | binding.next.setOnClickListener { 24 | nextLevel() 25 | } 26 | setListeners() 27 | showHint() 28 | validateAnswer() 29 | 30 | } 31 | 32 | private fun setListeners() { 33 | binding.hintRoot.setOnClickListener { 34 | viewModel.isExpanded = !viewModel.isExpanded 35 | showHint() 36 | } 37 | binding.expand.setOnClickListener { 38 | viewModel.isExpanded = !viewModel.isExpanded 39 | showHint() 40 | } 41 | } 42 | 43 | private fun showHint() = if (viewModel.isExpanded) { 44 | binding.hint.visibility = View.VISIBLE 45 | binding.expand.setIconResource(R.drawable.ic_collapse_arrow) 46 | } else { 47 | binding.hint.visibility = View.GONE 48 | binding.expand.setIconResource(R.drawable.ic_expand_arrow) 49 | } 50 | 51 | private fun nextLevel() { 52 | val action = LevelTwoFragmentDirections.actionLevelTwoFragmentToLevelThreeFragment() 53 | findNavController().navigate(action) 54 | } 55 | 56 | private fun validateAnswer() { 57 | 58 | 59 | binding.slider.addOnChangeListener { slider, value, _ -> 60 | if (value < 10.0) { 61 | 62 | binding.right.visibility = View.VISIBLE 63 | binding.wrong.visibility = View.INVISIBLE 64 | binding.next.visibility = View.VISIBLE 65 | binding.celebrate.visibility = View.VISIBLE 66 | binding.celebrate.playAnimation() 67 | 68 | slider.value = 0.0f 69 | slider.isEnabled = false 70 | viewModel.playWin() 71 | 72 | viewModel.addScore(levelNumber = 2) 73 | 74 | } else if (value > 50.0) { 75 | 76 | binding.right.visibility = View.GONE 77 | binding.wrong.visibility = View.VISIBLE 78 | viewModel.playLose() 79 | } 80 | 81 | } 82 | } 83 | } 84 | 85 | -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/level3/LevelThreeFragment.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui.level3 2 | 3 | import android.annotation.SuppressLint 4 | import android.os.Bundle 5 | import android.view.DragEvent 6 | import android.view.MotionEvent 7 | import android.view.View 8 | import androidx.constraintlayout.widget.ConstraintLayout 9 | import androidx.fragment.app.viewModels 10 | import androidx.navigation.fragment.findNavController 11 | import com.thana.simplegame.R 12 | import com.thana.simplegame.databinding.FragmentLevelThreeBinding 13 | import com.thana.simplegame.ui.SharedViewModel 14 | import com.thana.simplegame.ui.common.BaseFragment 15 | import com.thana.simplegame.ui.common.viewBinding 16 | import com.thana.simplegame.util.hideKeyboard 17 | import dagger.hilt.android.AndroidEntryPoint 18 | 19 | @AndroidEntryPoint 20 | class LevelThreeFragment : BaseFragment(R.layout.fragment_level_three), View.OnTouchListener, 21 | View.OnDragListener { 22 | 23 | private val binding by viewBinding(FragmentLevelThreeBinding::bind) 24 | private val viewModel: SharedViewModel by viewModels() 25 | 26 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 27 | super.onViewCreated(view, savedInstanceState) 28 | 29 | binding.next.setOnClickListener { 30 | nextLevel() 31 | } 32 | 33 | setListeners() 34 | showHint() 35 | validateAnswer() 36 | 37 | } 38 | 39 | private fun showHint() = if (viewModel.isExpanded) { 40 | binding.hint.visibility = View.VISIBLE 41 | binding.expand.setIconResource(R.drawable.ic_collapse_arrow) 42 | } else { 43 | binding.hint.visibility = View.GONE 44 | binding.expand.setIconResource(R.drawable.ic_expand_arrow) 45 | } 46 | 47 | private fun nextLevel() { 48 | val action = LevelThreeFragmentDirections.actionLevelThreeFragmentToLevelFourFragment() 49 | findNavController().navigate(action) 50 | } 51 | 52 | @SuppressLint("ClickableViewAccessibility") 53 | private fun setListeners() { 54 | binding.cake1.setOnTouchListener(this) 55 | binding.cake2.setOnTouchListener(this) 56 | binding.cake3.setOnTouchListener(this) 57 | binding.area.setOnDragListener(this) 58 | binding.dinosaur.setOnDragListener(this) 59 | binding.input.setOnDragListener { _, _ -> 60 | 61 | return@setOnDragListener true 62 | } 63 | binding.editText.setOnDragListener { _, _ -> 64 | 65 | return@setOnDragListener true 66 | } 67 | binding.area2.setOnClickListener { 68 | viewModel.isExpanded = !viewModel.isExpanded 69 | showHint() 70 | } 71 | binding.expand.setOnClickListener { 72 | viewModel.isExpanded = !viewModel.isExpanded 73 | showHint() 74 | } 75 | } 76 | 77 | private fun validateAnswer() { 78 | 79 | binding.submit.setOnClickListener { 80 | 81 | val input = binding.editText.text.toString().trim() 82 | if (input == "1") { 83 | binding.right.visibility = View.VISIBLE 84 | binding.wrong.visibility = View.GONE 85 | binding.celebrate.visibility = View.VISIBLE 86 | binding.celebrate.playAnimation() 87 | binding.submit.isEnabled = false 88 | binding.next.visibility = View.VISIBLE 89 | 90 | viewModel.playWin() 91 | viewModel.addScore(levelNumber = 3) 92 | 93 | } else { 94 | binding.wrong.visibility = View.VISIBLE 95 | binding.right.visibility = View.GONE 96 | 97 | viewModel.playLose() 98 | } 99 | hideKeyboard() 100 | } 101 | } 102 | 103 | override fun onDrag(layoutview: View, dragevent: DragEvent): Boolean { 104 | 105 | val view = dragevent.localState as View 106 | 107 | when (dragevent.action) { 108 | 109 | DragEvent.ACTION_DRAG_ENTERED -> { 110 | view.alpha = 0.3f 111 | view.visibility = View.INVISIBLE 112 | } 113 | DragEvent.ACTION_DROP -> { 114 | view.alpha = 1.0f 115 | val owner = binding.area 116 | owner.removeView(view) 117 | 118 | if (layoutview.id != binding.dinosaur.id) { 119 | val container = layoutview as ConstraintLayout 120 | 121 | view.x = dragevent.x - (view.width / 2) 122 | view.y = dragevent.y - (view.height / 2) 123 | 124 | container.addView(view) 125 | view.visibility = View.VISIBLE 126 | } 127 | } 128 | DragEvent.ACTION_DRAG_EXITED -> { 129 | view.alpha = 1.0f 130 | view.visibility = View.VISIBLE 131 | 132 | } 133 | 134 | } 135 | return true 136 | } 137 | 138 | 139 | override fun onTouch(view: View, motionEvent: MotionEvent): Boolean { 140 | 141 | return if (motionEvent.action == MotionEvent.ACTION_DOWN) { 142 | 143 | view.performClick() 144 | val shadowBuilder = View.DragShadowBuilder(view) 145 | 146 | view.startDragAndDrop(null, shadowBuilder, view, 0) 147 | 148 | true 149 | } else { 150 | 151 | false 152 | } 153 | } 154 | } 155 | 156 | -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/level4/LevelFourFragment.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui.level4 2 | 3 | import android.annotation.SuppressLint 4 | import android.os.Bundle 5 | import android.util.Log 6 | import android.view.DragEvent 7 | import android.view.MotionEvent 8 | import android.view.View 9 | import android.view.ViewGroup 10 | import androidx.constraintlayout.widget.ConstraintLayout 11 | import androidx.fragment.app.viewModels 12 | import androidx.navigation.fragment.findNavController 13 | import com.thana.simplegame.R 14 | import com.thana.simplegame.databinding.FragmentLevelFourBinding 15 | import com.thana.simplegame.ui.SharedViewModel 16 | import com.thana.simplegame.ui.common.BaseFragment 17 | import com.thana.simplegame.ui.common.viewBinding 18 | import dagger.hilt.android.AndroidEntryPoint 19 | 20 | @AndroidEntryPoint 21 | class LevelFourFragment : BaseFragment(R.layout.fragment_level_four), View.OnTouchListener, 22 | View.OnDragListener { 23 | 24 | private val binding by viewBinding(FragmentLevelFourBinding::bind) 25 | 26 | private val viewModel: SharedViewModel by viewModels() 27 | 28 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 29 | super.onViewCreated(view, savedInstanceState) 30 | 31 | setListeners() 32 | 33 | binding.next.setOnClickListener { 34 | nextLevel() 35 | } 36 | 37 | showHint() 38 | } 39 | 40 | private fun showHint() = if (viewModel.isExpanded) { 41 | binding.hint.visibility = View.VISIBLE 42 | binding.expand.setIconResource(R.drawable.ic_collapse_arrow) 43 | } else { 44 | binding.hint.visibility = View.GONE 45 | binding.expand.setIconResource(R.drawable.ic_expand_arrow) 46 | } 47 | 48 | private fun nextLevel() { 49 | val action = LevelFourFragmentDirections.actionLevelFourFragmentToLevelFiveFragment() 50 | findNavController().navigate(action) 51 | } 52 | 53 | @SuppressLint("ClickableViewAccessibility") 54 | private fun setListeners() { 55 | binding.untouchable.isEnabled = false 56 | binding.water.setOnTouchListener(this) 57 | binding.area.setOnDragListener(this) 58 | binding.hintRoot.setOnClickListener { 59 | viewModel.isExpanded = !viewModel.isExpanded 60 | showHint() 61 | } 62 | binding.expand.setOnClickListener { 63 | viewModel.isExpanded = !viewModel.isExpanded 64 | showHint() 65 | } 66 | } 67 | 68 | 69 | override fun onDrag(layoutview: View, dragevent: DragEvent): Boolean { 70 | 71 | val view = dragevent.localState as View 72 | 73 | when (dragevent.action) { 74 | 75 | DragEvent.ACTION_DRAG_ENTERED -> { 76 | view.visibility = View.INVISIBLE 77 | } 78 | DragEvent.ACTION_DRAG_STARTED -> { 79 | view.rotation = -60f 80 | } 81 | 82 | DragEvent.ACTION_DROP -> { 83 | view.alpha = 1.0f 84 | 85 | validateAnswer(dragevent) 86 | 87 | try { 88 | if (!wrongArea(dragevent)) { 89 | val owner = view.parent as ViewGroup 90 | owner.removeView(view) 91 | val container = layoutview as ConstraintLayout 92 | view.x = dragevent.x - (view.width / 2) 93 | view.y = dragevent.y - (view.height / 2) 94 | container.addView(view) 95 | } 96 | } catch (e: Exception) { 97 | Log.d("Draging", "Something went wrong") 98 | } 99 | 100 | view.visibility = View.VISIBLE 101 | } 102 | DragEvent.ACTION_DRAG_EXITED -> { 103 | view.alpha = 1.0f 104 | view.visibility = View.VISIBLE 105 | } 106 | 107 | } 108 | return true 109 | } 110 | 111 | private fun wrongArea(dragEvent: DragEvent): Boolean { 112 | val areaXStart = binding.untouchable.x 113 | val areaYStart = binding.untouchable.y 114 | 115 | val areaXEnd = areaXStart + binding.untouchable.width 116 | val areaYEnd = areaYStart + binding.untouchable.height 117 | 118 | if (dragEvent.x in areaXStart..areaXEnd && dragEvent.y in areaYStart..areaYEnd) { 119 | return true 120 | } 121 | 122 | return false 123 | } 124 | 125 | private fun validateAnswer(dragEvent: DragEvent) { 126 | 127 | val faceXStart = binding.waterText.x 128 | val faceYStart = binding.waterText.y 129 | 130 | val faceXEnd = faceXStart + binding.waterText.width 131 | val faceYEnd = faceYStart + binding.waterText.height 132 | 133 | if (dragEvent.x in faceXStart..faceXEnd && dragEvent.y in faceYStart..faceYEnd) { 134 | binding.right.visibility = View.VISIBLE 135 | binding.next.visibility = View.VISIBLE 136 | binding.celebrate.visibility = View.VISIBLE 137 | binding.celebrate.playAnimation() 138 | 139 | viewModel.playWin() 140 | 141 | viewModel.addScore(levelNumber = 4) 142 | } 143 | 144 | } 145 | 146 | 147 | override fun onTouch(view: View, motionEvent: MotionEvent): Boolean { 148 | 149 | return if (motionEvent.action == MotionEvent.ACTION_DOWN) { 150 | 151 | view.performClick() 152 | val shadowBuilder = View.DragShadowBuilder(view) 153 | view.startDragAndDrop(null, shadowBuilder, view, 0) 154 | 155 | true 156 | } else { 157 | 158 | false 159 | } 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/level5/LevelFiveFragment.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui.level5 2 | 3 | import android.annotation.SuppressLint 4 | import android.os.Bundle 5 | import android.view.DragEvent 6 | import android.view.MotionEvent 7 | import android.view.View 8 | import androidx.constraintlayout.widget.ConstraintLayout 9 | import androidx.fragment.app.viewModels 10 | import androidx.navigation.fragment.findNavController 11 | import com.thana.simplegame.R 12 | import com.thana.simplegame.databinding.FragmentLevelFiveBinding 13 | import com.thana.simplegame.ui.SharedViewModel 14 | import com.thana.simplegame.ui.common.BaseFragment 15 | import com.thana.simplegame.ui.common.viewBinding 16 | import dagger.hilt.android.AndroidEntryPoint 17 | 18 | @AndroidEntryPoint 19 | class LevelFiveFragment : BaseFragment(R.layout.fragment_level_five), View.OnTouchListener, 20 | View.OnDragListener { 21 | 22 | private val binding by viewBinding(FragmentLevelFiveBinding::bind) 23 | private val viewModel: SharedViewModel by viewModels() 24 | 25 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 26 | super.onViewCreated(view, savedInstanceState) 27 | 28 | setListeners() 29 | showHint() 30 | binding.next.setOnClickListener { 31 | nextLevel() 32 | } 33 | } 34 | 35 | private fun showHint() = if (viewModel.isExpanded) { 36 | binding.hint.visibility = View.VISIBLE 37 | binding.expand.setIconResource(R.drawable.ic_collapse_arrow) 38 | } else { 39 | binding.hint.visibility = View.GONE 40 | binding.expand.setIconResource(R.drawable.ic_expand_arrow) 41 | } 42 | 43 | private fun nextLevel() { 44 | val action = LevelFiveFragmentDirections.actionLevelFiveFragmentToLevelSixFragment() 45 | findNavController().navigate(action) 46 | } 47 | 48 | 49 | @SuppressLint("ClickableViewAccessibility") 50 | private fun setListeners() { 51 | 52 | binding.cow.setOnTouchListener(this) 53 | binding.eggs.setOnTouchListener(this) 54 | binding.food1.setOnTouchListener(this) 55 | binding.food2.setOnTouchListener(this) 56 | binding.flour.setOnTouchListener(this) 57 | binding.area.setOnDragListener(this) 58 | binding.hintRoot.setOnClickListener { 59 | viewModel.isExpanded = !viewModel.isExpanded 60 | showHint() 61 | } 62 | binding.expand.setOnClickListener { 63 | viewModel.isExpanded = !viewModel.isExpanded 64 | showHint() 65 | } 66 | } 67 | 68 | private fun checkIfMixed(dragEvent: DragEvent, view: View) { 69 | 70 | val cowXStart = binding.cow.x 71 | val cowYStart = binding.cow.y 72 | 73 | val cowXEnd = cowXStart + binding.cow.width 74 | val cowYEnd = cowYStart + binding.cow.height 75 | 76 | val flourXStart = binding.flour.x 77 | val flourYStart = binding.flour.y 78 | 79 | val flourXEnd = flourXStart + binding.flour.width 80 | val flourYEnd = flourYStart + binding.flour.height 81 | 82 | val eggXStart = binding.eggs.x 83 | val eggYStart = binding.eggs.y 84 | 85 | val eggXEnd = eggXStart + binding.eggs.width 86 | val eggYEnd = eggYStart + binding.eggs.height 87 | 88 | 89 | if (view.id == binding.cow.id || view.id == binding.flour.id || view.id == binding.eggs.id) { 90 | if (dragEvent.x in cowXStart..cowXEnd 91 | && dragEvent.y in cowYStart..cowYEnd 92 | && dragEvent.x in flourXStart..flourXEnd 93 | && dragEvent.y in flourYStart..flourYEnd 94 | && dragEvent.x in flourXStart..eggXEnd 95 | && dragEvent.y in flourYStart..eggYEnd 96 | ) { 97 | 98 | correctAnswer() 99 | 100 | } 101 | } 102 | 103 | 104 | } 105 | 106 | 107 | private fun correctAnswer() { 108 | 109 | binding.pancake.visibility = View.VISIBLE 110 | binding.food1.visibility = View.INVISIBLE 111 | binding.food2.visibility = View.INVISIBLE 112 | binding.cow.visibility = View.INVISIBLE 113 | binding.eggs.visibility = View.INVISIBLE 114 | binding.flour.visibility = View.INVISIBLE 115 | binding.right.visibility = View.VISIBLE 116 | binding.next.visibility = View.VISIBLE 117 | binding.celebrate.visibility = View.VISIBLE 118 | binding.celebrate.playAnimation() 119 | viewModel.playWin() 120 | 121 | viewModel.addScore(levelNumber = 5) 122 | 123 | } 124 | 125 | override fun onDrag(layoutview: View, dragevent: DragEvent): Boolean { 126 | 127 | val view = dragevent.localState as View 128 | 129 | when (dragevent.action) { 130 | 131 | DragEvent.ACTION_DRAG_ENTERED -> { 132 | view.alpha = 0.3f 133 | view.visibility = View.INVISIBLE 134 | 135 | } 136 | DragEvent.ACTION_DROP -> { 137 | view.alpha = 1.0f 138 | val owner = binding.area 139 | owner.removeView(view) 140 | 141 | val container = layoutview as ConstraintLayout 142 | 143 | view.x = dragevent.x - (view.width / 2) 144 | view.y = dragevent.y - (view.height / 2) 145 | container.addView(view) 146 | view.visibility = View.VISIBLE 147 | checkIfMixed(dragevent, view) 148 | 149 | } 150 | DragEvent.ACTION_DRAG_EXITED -> { 151 | view.alpha = 1.0f 152 | view.visibility = View.VISIBLE 153 | 154 | } 155 | 156 | } 157 | return true 158 | } 159 | 160 | 161 | override fun onTouch(view: View, motionEvent: MotionEvent): Boolean { 162 | 163 | return if (motionEvent.action == MotionEvent.ACTION_DOWN) { 164 | 165 | view.performClick() 166 | val shadowBuilder = View.DragShadowBuilder(view) 167 | 168 | view.startDragAndDrop(null, shadowBuilder, view, 0) 169 | 170 | true 171 | } else { 172 | false 173 | } 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/level6/LevelSixFragment.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui.level6 2 | 3 | import android.annotation.SuppressLint 4 | import android.os.Bundle 5 | import android.view.DragEvent 6 | import android.view.MotionEvent 7 | import android.view.View 8 | import android.widget.ImageView 9 | import androidx.constraintlayout.widget.ConstraintLayout 10 | import androidx.core.content.ContextCompat 11 | import androidx.fragment.app.viewModels 12 | import androidx.navigation.fragment.findNavController 13 | import com.thana.simplegame.R 14 | import com.thana.simplegame.R.color 15 | import com.thana.simplegame.R.layout 16 | import com.thana.simplegame.databinding.FragmentLevelSixBinding 17 | import com.thana.simplegame.ui.SharedViewModel 18 | import com.thana.simplegame.ui.common.BaseFragment 19 | import com.thana.simplegame.ui.common.viewBinding 20 | import dagger.hilt.android.AndroidEntryPoint 21 | 22 | @AndroidEntryPoint 23 | class LevelSixFragment : BaseFragment(layout.fragment_level_six), View.OnTouchListener, 24 | View.OnDragListener { 25 | 26 | private val binding by viewBinding(FragmentLevelSixBinding::bind) 27 | private val viewModel: SharedViewModel by viewModels() 28 | 29 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 30 | super.onViewCreated(view, savedInstanceState) 31 | 32 | setListeners() 33 | showHint() 34 | binding.next.setOnClickListener { 35 | nextLevel() 36 | } 37 | 38 | } 39 | 40 | private fun nextLevel() { 41 | val action = LevelSixFragmentDirections.actionLevelSixFragmentToLevelSevenFragment() 42 | findNavController().navigate(action) 43 | } 44 | 45 | @SuppressLint("ClickableViewAccessibility") 46 | private fun setListeners() { 47 | 48 | binding.ball1.setOnTouchListener(this) 49 | binding.ball2.setOnTouchListener(this) 50 | binding.ball3.setOnTouchListener(this) 51 | binding.ball4.setOnTouchListener(this) 52 | binding.ball5.setOnTouchListener(this) 53 | binding.area.setOnDragListener(this) 54 | binding.hintRoot.setOnClickListener { 55 | viewModel.isExpanded = !viewModel.isExpanded 56 | showHint() 57 | } 58 | binding.expand.setOnClickListener { 59 | viewModel.isExpanded = !viewModel.isExpanded 60 | showHint() 61 | } 62 | 63 | } 64 | 65 | private fun checkIfMixed(dragEvent: DragEvent, view: View) { 66 | 67 | val ball1XStart = binding.ball1.x 68 | val ball1YStart = binding.ball1.y 69 | 70 | val ballXEnd = ball1XStart + binding.ball1.width 71 | val ballYEnd = ball1YStart + binding.ball1.height 72 | 73 | val ball2XStart = binding.ball2.x 74 | val ball2YStart = binding.ball2.y 75 | 76 | val ball2XEnd = ball2XStart + binding.ball2.width 77 | val ball2YEnd = ball2YStart + binding.ball2.height 78 | 79 | val ball3XStart = binding.ball3.x 80 | val ball3YStart = binding.ball3.y 81 | 82 | val ball3XEnd = ball3XStart + binding.ball3.width 83 | val ball3YEnd = ball3YStart + binding.ball3.height 84 | 85 | val ball4XStart = binding.ball4.x 86 | val ball4YStart = binding.ball4.y 87 | 88 | val ball4XEnd = ball4XStart + binding.ball4.width 89 | val ball4YEnd = ball4YStart + binding.ball4.height 90 | 91 | val ball5XStart = binding.ball5.x 92 | val ball5YStart = binding.ball5.y 93 | 94 | val ball5XEnd = ball5XStart + binding.ball5.width 95 | val ball5YEnd = ball5YStart + binding.ball5.height 96 | 97 | if (view.id == binding.ball1.id || 98 | view.id == binding.ball2.id || 99 | view.id == binding.ball3.id || 100 | view.id == binding.ball4.id || 101 | view.id == binding.ball5.id 102 | ) { 103 | if (dragEvent.x in ball1XStart..ballXEnd 104 | && dragEvent.y in ball1YStart..ballYEnd 105 | && dragEvent.x in ball2XStart..ball2XEnd 106 | && dragEvent.y in ball2YStart..ball2YEnd 107 | && dragEvent.x in ball3XStart..ball3XEnd 108 | && dragEvent.y in ball3YStart..ball3YEnd 109 | && dragEvent.y in ball4YStart..ball4YEnd 110 | && dragEvent.x in ball4XStart..ball4XEnd 111 | && dragEvent.y in ball5YStart..ball5YEnd 112 | && dragEvent.x in ball5XStart..ball5XEnd 113 | 114 | ) { 115 | 116 | correctAnswer(view as ImageView) 117 | 118 | } 119 | } 120 | 121 | 122 | } 123 | 124 | private fun showHint() = if (viewModel.isExpanded) { 125 | binding.hint.visibility = View.VISIBLE 126 | binding.expand.setIconResource(R.drawable.ic_collapse_arrow) 127 | } else { 128 | binding.hint.visibility = View.GONE 129 | binding.expand.setIconResource(R.drawable.ic_expand_arrow) 130 | } 131 | 132 | private fun correctAnswer(view: ImageView) { 133 | 134 | binding.ball1.visibility = View.INVISIBLE 135 | binding.ball1.visibility = View.INVISIBLE 136 | binding.ball2.visibility = View.INVISIBLE 137 | binding.ball3.visibility = View.INVISIBLE 138 | binding.ball4.visibility = View.INVISIBLE 139 | binding.ball5.visibility = View.INVISIBLE 140 | binding.right.visibility = View.VISIBLE 141 | binding.next.visibility = View.VISIBLE 142 | view.visibility = View.VISIBLE 143 | view.setColorFilter( 144 | ContextCompat.getColor(requireContext(), color.brown), 145 | android.graphics.PorterDuff.Mode.SRC_IN 146 | ) 147 | binding.celebrate.visibility = View.VISIBLE 148 | binding.celebrate.playAnimation() 149 | viewModel.playWin() 150 | 151 | viewModel.addScore(levelNumber = 6) 152 | 153 | } 154 | 155 | override fun onDrag(layoutview: View, dragevent: DragEvent): Boolean { 156 | 157 | val view = dragevent.localState as View 158 | 159 | when (dragevent.action) { 160 | 161 | DragEvent.ACTION_DRAG_ENTERED -> { 162 | view.alpha = 0.3f 163 | view.visibility = View.INVISIBLE 164 | 165 | } 166 | DragEvent.ACTION_DROP -> { 167 | view.alpha = 1.0f 168 | val owner = binding.area 169 | owner.removeView(view) 170 | 171 | val container = layoutview as ConstraintLayout 172 | 173 | view.x = dragevent.x - (view.width / 2) 174 | view.y = dragevent.y - (view.height / 2) 175 | 176 | container.addView(view) 177 | view.visibility = View.VISIBLE 178 | checkIfMixed(dragevent, view) 179 | 180 | } 181 | DragEvent.ACTION_DRAG_EXITED -> { 182 | view.alpha = 1.0f 183 | view.visibility = View.VISIBLE 184 | 185 | } 186 | 187 | } 188 | return true 189 | } 190 | 191 | 192 | override fun onTouch(view: View, motionEvent: MotionEvent): Boolean { 193 | 194 | return if (motionEvent.action == MotionEvent.ACTION_DOWN) { 195 | 196 | view.performClick() 197 | val shadowBuilder = View.DragShadowBuilder(view) 198 | 199 | view.startDragAndDrop(null, shadowBuilder, view, 0) 200 | 201 | true 202 | } else { 203 | false 204 | } 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/level7/LevelSevenFragment.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui.level7 2 | 3 | import android.annotation.SuppressLint 4 | import android.os.Bundle 5 | import android.view.DragEvent 6 | import android.view.MotionEvent 7 | import android.view.View 8 | import android.widget.ImageView 9 | import androidx.constraintlayout.widget.ConstraintLayout 10 | import androidx.core.content.ContextCompat 11 | import androidx.fragment.app.viewModels 12 | import androidx.navigation.fragment.findNavController 13 | import com.thana.simplegame.R 14 | import com.thana.simplegame.databinding.FragmentLevelSevenBinding 15 | import com.thana.simplegame.ui.SharedViewModel 16 | import com.thana.simplegame.ui.common.BaseFragment 17 | import com.thana.simplegame.ui.common.viewBinding 18 | import dagger.hilt.android.AndroidEntryPoint 19 | 20 | @AndroidEntryPoint 21 | class LevelSevenFragment : BaseFragment(R.layout.fragment_level_seven), View.OnTouchListener, 22 | View.OnDragListener { 23 | 24 | private val binding by viewBinding(FragmentLevelSevenBinding::bind) 25 | private val viewModel: SharedViewModel by viewModels() 26 | 27 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 28 | super.onViewCreated(view, savedInstanceState) 29 | 30 | setListeners() 31 | showHint() 32 | binding.next.setOnClickListener { 33 | nextLevel() 34 | } 35 | 36 | } 37 | private fun showHint() = if (viewModel.isExpanded) { 38 | binding.hint.visibility = View.VISIBLE 39 | binding.expand.setIconResource(R.drawable.ic_collapse_arrow) 40 | } else { 41 | binding.hint.visibility = View.GONE 42 | binding.expand.setIconResource(R.drawable.ic_expand_arrow) 43 | } 44 | 45 | 46 | private fun nextLevel() { 47 | val action = LevelSevenFragmentDirections.actionLevelSevenFragmentToLevelEightFragment() 48 | findNavController().navigate(action) 49 | } 50 | 51 | @SuppressLint("ClickableViewAccessibility") 52 | private fun setListeners() { 53 | binding.ball1.setOnTouchListener(this) 54 | binding.ball2.setOnTouchListener(this) 55 | binding.yellowBall.setOnTouchListener(this) 56 | binding.ball4.setOnTouchListener(this) 57 | binding.ball5.setOnTouchListener(this) 58 | binding.area.setOnDragListener(this) 59 | binding.hintRoot.setOnClickListener { 60 | viewModel.isExpanded = !viewModel.isExpanded 61 | showHint() 62 | } 63 | binding.expand.setOnClickListener { 64 | viewModel.isExpanded = !viewModel.isExpanded 65 | showHint() 66 | } 67 | } 68 | 69 | private fun checkIfMixed(dragEvent: DragEvent, view: View) { 70 | 71 | val correctAreaXStart = binding.correctArea.x 72 | val correctAreaYStart = binding.correctArea.y 73 | 74 | val correctAreaXEnd = correctAreaXStart + binding.correctArea.width 75 | val correctAreaYEnd = correctAreaYStart + binding.correctArea.height 76 | 77 | val yellowBallXStart = binding.yellowBall.x 78 | val yellowBallYStart = binding.yellowBall.y 79 | 80 | val yellowBallXEnd = yellowBallXStart + binding.yellowBall.width 81 | val yellowBallYEnd = yellowBallYStart + binding.yellowBall.height 82 | 83 | 84 | if (view.id == binding.correctArea.id || 85 | view.id == binding.yellowBall.id 86 | ) { 87 | if (dragEvent.x in correctAreaXStart..correctAreaXEnd 88 | && dragEvent.y in correctAreaYStart..correctAreaYEnd 89 | && dragEvent.x in yellowBallXStart..yellowBallXEnd 90 | && dragEvent.y in yellowBallYStart..yellowBallYEnd 91 | 92 | ) { 93 | 94 | correctAnswer(view as ImageView) 95 | 96 | } 97 | } 98 | 99 | 100 | } 101 | 102 | private fun correctAnswer(view: ImageView) { 103 | view.visibility = View.VISIBLE 104 | view.setColorFilter( 105 | ContextCompat.getColor(requireContext(), R.color.green), 106 | android.graphics.PorterDuff.Mode.SRC_IN 107 | ) 108 | binding.next.visibility = View.VISIBLE 109 | binding.celebrate.visibility = View.VISIBLE 110 | binding.right.visibility = View.VISIBLE 111 | binding.celebrate.playAnimation() 112 | viewModel.playWin() 113 | 114 | viewModel.addScore(levelNumber = 7) 115 | 116 | } 117 | 118 | override fun onDrag(layoutview: View, dragevent: DragEvent): Boolean { 119 | 120 | val view = dragevent.localState as View 121 | 122 | when (dragevent.action) { 123 | 124 | DragEvent.ACTION_DRAG_ENTERED -> { 125 | view.alpha = 0.3f 126 | view.visibility = View.INVISIBLE 127 | 128 | } 129 | DragEvent.ACTION_DROP -> { 130 | view.alpha = 1.0f 131 | val owner = binding.area 132 | owner.removeView(view) 133 | 134 | val container = layoutview as ConstraintLayout 135 | 136 | view.x = dragevent.x - (view.width / 2) 137 | view.y = dragevent.y - (view.height / 2) 138 | 139 | container.addView(view) 140 | view.visibility = View.VISIBLE 141 | checkIfMixed(dragevent, view) 142 | 143 | } 144 | DragEvent.ACTION_DRAG_EXITED -> { 145 | view.alpha = 1.0f 146 | view.visibility = View.VISIBLE 147 | 148 | } 149 | 150 | } 151 | return true 152 | } 153 | 154 | 155 | override fun onTouch(view: View, motionEvent: MotionEvent): Boolean { 156 | 157 | return if (motionEvent.action == MotionEvent.ACTION_DOWN) { 158 | 159 | view.performClick() 160 | val shadowBuilder = View.DragShadowBuilder(view) 161 | 162 | view.startDragAndDrop(null, shadowBuilder, view, 0) 163 | 164 | true 165 | } else { 166 | false 167 | } 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/level8/LevelEightFragment.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui.level8 2 | 3 | import android.annotation.SuppressLint 4 | import android.os.Bundle 5 | import android.view.DragEvent 6 | import android.view.MotionEvent 7 | import android.view.View 8 | import androidx.constraintlayout.widget.ConstraintLayout 9 | import androidx.fragment.app.viewModels 10 | import androidx.navigation.fragment.findNavController 11 | import com.thana.simplegame.R 12 | import com.thana.simplegame.databinding.FragmentLevelEightBinding 13 | import com.thana.simplegame.ui.SharedViewModel 14 | import com.thana.simplegame.ui.common.BaseFragment 15 | import com.thana.simplegame.ui.common.viewBinding 16 | import dagger.hilt.android.AndroidEntryPoint 17 | 18 | @AndroidEntryPoint 19 | class LevelEightFragment : BaseFragment(R.layout.fragment_level_eight), View.OnTouchListener, 20 | View.OnDragListener { 21 | 22 | private val binding by viewBinding(FragmentLevelEightBinding::bind) 23 | private val viewModel: SharedViewModel by viewModels() 24 | 25 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 26 | super.onViewCreated(view, savedInstanceState) 27 | 28 | setListeners() 29 | showHint() 30 | binding.title.setOnClickListener { 31 | correctAnswer() 32 | } 33 | binding.next.setOnClickListener { 34 | nextLevel() 35 | } 36 | 37 | } 38 | 39 | private fun nextLevel() { 40 | val action = LevelEightFragmentDirections.actionLevelEightFragmentToLevelNineFragment() 41 | findNavController().navigate(action) 42 | } 43 | 44 | @SuppressLint("ClickableViewAccessibility") 45 | private fun setListeners() { 46 | binding.blue.setOnTouchListener(this) 47 | binding.yellow.setOnTouchListener(this) 48 | binding.ball2.setOnTouchListener(this) 49 | binding.yellowBall.setOnTouchListener(this) 50 | binding.ball4.setOnTouchListener(this) 51 | binding.ball5.setOnTouchListener(this) 52 | binding.area.setOnDragListener(this) 53 | binding.hintRoot.setOnClickListener { 54 | viewModel.isExpanded = !viewModel.isExpanded 55 | showHint() 56 | } 57 | binding.expand.setOnClickListener { 58 | viewModel.isExpanded = !viewModel.isExpanded 59 | showHint() 60 | } 61 | 62 | } 63 | 64 | private fun showHint() = if (viewModel.isExpanded) { 65 | binding.hint.visibility = View.VISIBLE 66 | binding.expand.setIconResource(R.drawable.ic_collapse_arrow) 67 | } else { 68 | binding.hint.visibility = View.GONE 69 | binding.expand.setIconResource(R.drawable.ic_expand_arrow) 70 | } 71 | 72 | private fun correctAnswer() { 73 | 74 | binding.next.visibility = View.VISIBLE 75 | binding.right.visibility = View.VISIBLE 76 | binding.celebrate.visibility = View.VISIBLE 77 | binding.celebrate.playAnimation() 78 | viewModel.playWin() 79 | 80 | viewModel.addScore(levelNumber = 8) 81 | 82 | } 83 | 84 | override fun onDrag(layoutview: View, dragevent: DragEvent): Boolean { 85 | 86 | val view = dragevent.localState as View 87 | 88 | when (dragevent.action) { 89 | 90 | DragEvent.ACTION_DRAG_ENTERED -> { 91 | view.alpha = 0.3f 92 | view.visibility = View.INVISIBLE 93 | 94 | } 95 | DragEvent.ACTION_DROP -> { 96 | view.alpha = 1.0f 97 | val owner = binding.area 98 | owner.removeView(view) 99 | 100 | val container = layoutview as ConstraintLayout 101 | 102 | view.x = dragevent.x - (view.width / 2) 103 | view.y = dragevent.y - (view.height / 2) 104 | 105 | container.addView(view) 106 | view.visibility = View.VISIBLE 107 | 108 | } 109 | DragEvent.ACTION_DRAG_EXITED -> { 110 | view.alpha = 1.0f 111 | view.visibility = View.VISIBLE 112 | 113 | } 114 | 115 | } 116 | return true 117 | } 118 | 119 | 120 | override fun onTouch(view: View, motionEvent: MotionEvent): Boolean { 121 | 122 | return if (motionEvent.action == MotionEvent.ACTION_DOWN) { 123 | 124 | view.performClick() 125 | val shadowBuilder = View.DragShadowBuilder(view) 126 | 127 | view.startDragAndDrop(null, shadowBuilder, view, 0) 128 | 129 | true 130 | } else { 131 | false 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/level9/LevelNineFragment.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui.level9 2 | 3 | import android.os.Bundle 4 | import android.view.View 5 | import androidx.fragment.app.viewModels 6 | import androidx.navigation.fragment.findNavController 7 | import com.thana.simplegame.R 8 | import com.thana.simplegame.databinding.FragmentLevelNineBinding 9 | import com.thana.simplegame.ui.SharedViewModel 10 | import com.thana.simplegame.ui.common.BaseFragment 11 | import com.thana.simplegame.ui.common.viewBinding 12 | import com.thana.simplegame.util.hideKeyboard 13 | import dagger.hilt.android.AndroidEntryPoint 14 | 15 | @AndroidEntryPoint 16 | class LevelNineFragment : BaseFragment(R.layout.fragment_level_nine) { 17 | 18 | private val binding by viewBinding(FragmentLevelNineBinding::bind) 19 | private val viewModel: SharedViewModel by viewModels() 20 | 21 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 22 | super.onViewCreated(view, savedInstanceState) 23 | 24 | showHint() 25 | validateAnswer() 26 | setListeners() 27 | 28 | binding.next.setOnClickListener { 29 | nextLevel() 30 | } 31 | } 32 | 33 | private fun showHint() = if (viewModel.isExpanded) { 34 | binding.hint.visibility = View.VISIBLE 35 | binding.expand.setIconResource(R.drawable.ic_collapse_arrow) 36 | } else { 37 | binding.hint.visibility = View.GONE 38 | binding.expand.setIconResource(R.drawable.ic_expand_arrow) 39 | } 40 | 41 | private fun setListeners() { 42 | binding.hintRoot.setOnClickListener { 43 | viewModel.isExpanded = !viewModel.isExpanded 44 | showHint() 45 | } 46 | binding.expand.setOnClickListener { 47 | viewModel.isExpanded = !viewModel.isExpanded 48 | showHint() 49 | } 50 | 51 | } 52 | 53 | private fun nextLevel() { 54 | val action = LevelNineFragmentDirections.actionLevelNineFragmentToLevelTenFragment() 55 | findNavController().navigate(action) 56 | } 57 | 58 | private fun validateAnswer() { 59 | 60 | binding.submit.setOnClickListener { 61 | val input = binding.editText.text.toString().trim() 62 | if (input == "0") { 63 | binding.right.visibility = View.VISIBLE 64 | binding.wrong.visibility = View.GONE 65 | binding.celebrate.visibility = View.VISIBLE 66 | binding.celebrate.playAnimation() 67 | binding.submit.isEnabled = false 68 | binding.next.visibility = View.VISIBLE 69 | 70 | viewModel.playWin() 71 | 72 | viewModel.addScore(levelNumber = 9) 73 | 74 | } else { 75 | binding.wrong.visibility = View.VISIBLE 76 | binding.right.visibility = View.GONE 77 | viewModel.playLose() 78 | } 79 | hideKeyboard() 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/profile/ProfileFragment.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui.profile 2 | 3 | import android.content.Intent 4 | import android.os.Bundle 5 | import android.view.View 6 | import androidx.fragment.app.viewModels 7 | import com.thana.simplegame.BuildConfig 8 | import com.thana.simplegame.R 9 | import com.thana.simplegame.databinding.FragmentProfileBinding 10 | import com.thana.simplegame.ui.SharedViewModel 11 | import com.thana.simplegame.ui.common.BaseFragment 12 | import com.thana.simplegame.ui.common.viewBinding 13 | import dagger.hilt.android.AndroidEntryPoint 14 | 15 | @AndroidEntryPoint 16 | class ProfileFragment : BaseFragment(R.layout.fragment_profile) { 17 | 18 | private val binding by viewBinding(FragmentProfileBinding::bind) 19 | 20 | private val viewModel: SharedViewModel by viewModels() 21 | 22 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 23 | super.onViewCreated(view, savedInstanceState) 24 | 25 | setProfileInfo() 26 | binding.share.setOnClickListener { shareProgress() } 27 | } 28 | 29 | private fun setProfileInfo() { 30 | val score = viewModel.getScore() 31 | val coins = viewModel.getCoins() 32 | binding.progressBar.progress = viewModel.getProgress() 33 | binding.gems.text = viewModel.getGems().toString() 34 | binding.levelUnlockedNumber.text = score.toString() 35 | binding.score.text = coins.toString() 36 | } 37 | 38 | private fun shareProgress() { 39 | try { 40 | val score = viewModel.getScore() 41 | val shareIntent = Intent(Intent.ACTION_SEND) 42 | shareIntent.type = "text/plain" 43 | var shareMessage = getString(R.string.share_text, score) 44 | shareMessage = 45 | "$shareMessage https://play.google.com/store/apps/details?id=" + 46 | BuildConfig.APPLICATION_ID 47 | shareIntent.putExtra(Intent.EXTRA_TEXT, shareMessage) 48 | startActivity(Intent.createChooser(shareIntent, null)) 49 | } catch (e: Exception) { 50 | 51 | } 52 | } 53 | } 54 | 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/ui/settings/SettingsFragment.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.ui.settings 2 | 3 | import android.content.Intent 4 | import android.net.Uri 5 | import android.os.Bundle 6 | import android.view.View 7 | import com.thana.simplegame.BuildConfig 8 | import com.thana.simplegame.R 9 | import com.thana.simplegame.databinding.FragmentSettingsBinding 10 | import com.thana.simplegame.ui.common.BaseFragment 11 | import com.thana.simplegame.ui.common.viewBinding 12 | import dagger.hilt.android.AndroidEntryPoint 13 | 14 | @AndroidEntryPoint 15 | class SettingsFragment : BaseFragment(R.layout.fragment_settings) { 16 | 17 | private val binding by viewBinding(FragmentSettingsBinding::bind) 18 | 19 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 20 | super.onViewCreated(view, savedInstanceState) 21 | 22 | setListeners() 23 | 24 | } 25 | 26 | private fun setListeners() { 27 | binding.rate.setOnClickListener { rateApp() } 28 | binding.share.setOnClickListener { share() } 29 | binding.contact.setOnClickListener { contact() } 30 | binding.help.setOnClickListener { help() } 31 | } 32 | 33 | private fun share() { 34 | try { 35 | val intent = Intent(Intent.ACTION_SEND).apply { 36 | type = "text/plain" 37 | val shareMessage = 38 | "https://play.google.com/store/apps/details?id=" + 39 | BuildConfig.APPLICATION_ID 40 | putExtra(Intent.EXTRA_TEXT, shareMessage) 41 | } 42 | startActivity(Intent.createChooser(intent, null)) 43 | 44 | } catch (e: Exception) { 45 | 46 | } 47 | } 48 | 49 | private fun contact() { 50 | try { 51 | val intent = Intent(Intent.ACTION_SEND).apply { 52 | putExtra(Intent.EXTRA_EMAIL, arrayOf("Thana_CS@hotmail.com")) 53 | putExtra(Intent.EXTRA_SUBJECT, "Contact Developer") 54 | type = "message/rfc822" 55 | } 56 | 57 | startActivity(Intent.createChooser(intent, "Contact Developer")) 58 | } catch (e: Exception) { 59 | 60 | } 61 | } 62 | 63 | private fun help() { 64 | try { 65 | val intent = Intent(Intent.ACTION_SEND).apply { 66 | putExtra(Intent.EXTRA_EMAIL, arrayOf("Thana_CS@hotmail.com")) 67 | putExtra(Intent.EXTRA_SUBJECT, "Help/Suggestion") 68 | type = "message/rfc822" 69 | } 70 | 71 | startActivity(Intent.createChooser(intent, "Help/Suggestion")) 72 | } catch (e: Exception) { 73 | 74 | } 75 | } 76 | 77 | private fun rateApp() { 78 | val uri = Uri.parse("market://details?id=${BuildConfig.APPLICATION_ID}") 79 | val myAppLinkToMarket = Intent(Intent.ACTION_VIEW, uri) 80 | startActivity(myAppLinkToMarket) 81 | 82 | } 83 | } -------------------------------------------------------------------------------- /app/src/main/java/com/thana/simplegame/util/ViewExtensions.kt: -------------------------------------------------------------------------------- 1 | package com.thana.simplegame.util 2 | 3 | import android.app.Activity 4 | import android.content.Context 5 | import android.view.View 6 | import android.view.inputmethod.InputMethodManager 7 | import androidx.fragment.app.Fragment 8 | 9 | fun Context.hideKeyboard(view: View) { 10 | val inputMethodManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager 11 | inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0) 12 | } 13 | 14 | fun Fragment.hideKeyboard() { 15 | view?.let { activity?.hideKeyboard(it) } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/bee.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/burger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/burger.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/button_3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/button_3d.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/button_3d_image.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/button_3d_image_yellow.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/button_3d_yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/button_3d_yellow.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/cake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/cake.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/cake_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/cake_2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/circle.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/controller.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/controller.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/corn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/corn.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/cow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/cow.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/earth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/earth.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/eggs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/eggs.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/elephant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/elephant.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/fab_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/flour.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/flour.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/gem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/gem.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/gradient.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/home_fab.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 13 | 16 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_about.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_add.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_check.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_collapse_arrow.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_contact.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_email.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_expand_arrow.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_help.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_home.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_minus.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_more.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_next.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_profile.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_settings.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_share.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_share_dark.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_star.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_wrong.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/idea.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/idea.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/lighter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/lighter.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/line.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/lion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/lion.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/matches.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/matches.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/medal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/medal.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/monitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/monitor.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/pancake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/pancake.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/panda.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/panda.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/pizza.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/pizza.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/popcorn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/popcorn.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/screw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/screw.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/screwdriver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/screwdriver.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/tv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/tv.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/water.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/water.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/woman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/woman.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/yellow_panda.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/drawable/yellow_panda.png -------------------------------------------------------------------------------- /app/src/main/res/font/bebas.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/font/bebas.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/inconsol.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/font/inconsol.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/pixel_font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/font/pixel_font.ttf -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 19 | 20 | 38 | 39 | 48 | 49 | 59 | 60 | 70 | 71 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_home.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 19 | 20 | 24 | 25 | 34 | 35 | 45 | 46 | 54 | 55 | 66 | 67 | 68 | 69 | 70 | 71 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_level_ten.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 17 | 18 | 23 | 24 | 33 | 34 | 44 | 45 | 55 | 56 | 68 | 69 | 81 | 82 | 93 | 94 | 103 | 104 | 114 | 115 | 116 | 117 | 128 | 129 | 139 | 140 | 144 | 145 | 152 | 153 | 164 | 165 | 178 | 179 | 189 | 190 | 191 | 192 | 193 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_profile.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 20 | 21 | 25 | 26 | 35 | 36 | 46 | 47 | 55 | 56 | 67 | 68 | 69 | 80 | 81 | 91 | 92 | 102 | 103 | 114 | 115 | 116 | 127 | 128 | 142 | 143 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 171 | 172 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 19 | 20 | 24 | 25 | 35 | 36 | 46 | 47 | 57 | 58 | 70 | 71 | 85 | 86 | 95 | 96 | 110 | 111 | 125 | 126 | 139 | 140 | 149 | 150 | 159 | 160 | 169 | 170 | 171 | 172 | 173 | 184 | 185 | -------------------------------------------------------------------------------- /app/src/main/res/layout/level_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 26 | 27 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /app/src/main/res/menu/button_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 13 | 14 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/navigation/nav_graph.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 16 | 19 | 22 | 23 | 28 | 33 | 34 | 39 | 44 | 45 | 50 | 55 | 56 | 61 | 66 | 67 | 72 | 77 | 78 | 83 | 88 | 89 | 94 | 99 | 100 | 105 | 110 | 111 | 116 | 121 | 122 | 127 | 132 | 133 | 138 | 143 | 148 | 153 | 154 | 159 | 164 | 165 | 170 | 175 | 176 | 181 | 186 | 187 | 192 | 193 | -------------------------------------------------------------------------------- /app/src/main/res/raw/lose.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/raw/lose.wav -------------------------------------------------------------------------------- /app/src/main/res/raw/win.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/app/src/main/res/raw/win.wav -------------------------------------------------------------------------------- /app/src/main/res/values-ar-rSA/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PUZZ 4 | الجواب 5 | تلميح 6 | مرحلة 7 | //lvl one 8 | كم عدد النحل هنا؟ 9 | هل حاولت لمس النحل؟ يبدو أنهم قد يلدغوا … 10 | //lvl two 11 | اسحب لليسار 12 | ربما عليك القراءة بتمعن 13 | //lvl three 14 | كم عدد الكيك هنا؟ 15 | الديناصور يحب الكيك !! 16 | //lvl four 17 | اسقي "النبتة" 18 | اسقي النص 19 | //lvl five 20 | اين الفطيرة؟ 21 | ربما يجب عليك تعلم الطبخ 22 | //lvl six 23 | ابحث عن الكرة البنية 24 | جرب مزج الألوان 25 | //lvl seven 26 | ابحث عن الكرة الخضراء 27 | جرب مزج الألوان 28 | //lvl eight 29 | ابحث عن اللون الأبيض 30 | ابحث عن اي شيء لونه ابيض لا يجب ان يكون كرة 31 | //lvl nine 32 | اوجد الفروقات 33 | هذا صعب جدا! يبدون متماثلين 34 | //lvl nine 35 | ابحث عن الباندا الصفراء 36 | ابحث عن طلاء أصفر 37 | //lvl elven 38 | ابحث عن طفل الفيل 39 | هذا الاسد يبدو مريب 40 | //lvl twelve 41 | احبث عن القط فوق هذا النص 42 | حرك النص 43 | //lvl thirteen 44 | احرق كل شيء 45 | احرق \"كل شيء\" 46 | //lvl fourteen 47 | اصلح اليد 48 | لم يتم توصيلها 49 | //lvl fifteen 50 | اصنع فشارًا 51 | ابحث عن ولاعة 52 | //profile 53 | انا في مستوى %1d! حمل هذه اللعبة وشارك تقدمك\n\n 54 | 55 | مشاركة التقدم 56 | المراحل المفتوحة 57 | تقدمك 58 | //settings 59 | قيم التطبيق 60 | تواصل 61 | مساعدة 62 | مشاركة 63 | -------------------------------------------------------------------------------- /app/src/main/res/values/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Reply 5 | Reply to all 6 | 7 | 8 | 9 | reply 10 | reply_all 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #25243C 5 | #1D1588 6 | #FFBB86FC 7 | #FF6200EE 8 | #FF3700B3 9 | #FF03DAC5 10 | #FF018786 11 | #FF000000 12 | #FFFFFFFF 13 | #676767 14 | #AEAEAE 15 | #00FFFFFF 16 | #F2F3FF 17 | #C1FF0606 18 | #8BC34A 19 | #2196F3 20 | #009688 21 | #FA7AA5 22 | #885CD6 23 | #25243C 24 | #333151 25 | #734751 26 | #653838 27 | #221C27 28 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 8dp 5 | -------------------------------------------------------------------------------- /app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #25243C 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | PUZZ 3 | A N S W E R 4 | HINT 5 | Level 6 | //lvl one 7 | How many bees are there? 8 | Have you tried touching the bees? they must sting… 9 | //lvl two 10 | swipe to left 11 | Maybe you should read carefully 12 | //lvl three 13 | How many cakes are there? 14 | This dinosaur loves cake !! 15 | //lvl four 16 | Water the plant 17 | Water \"the plant\" 18 | //lvl five 19 | Find the pancake 20 | Maybe you should learn how to cook 21 | //lvl six 22 | Find the brown ball 23 | Try mixing colors 24 | //lvl seven 25 | Find the green ball 26 | Try mixing colors 27 | //lvl eight 28 | Find a white color 29 | Any white color does not have to be a ball 30 | //lvl nine 31 | Find the differences 32 | This is so difficult! they look the same 33 | //lvl nine 34 | Find the yellow panda 35 | Look for a yellow paint 36 | //lvl elven 37 | Find the elephant\'s baby 38 | The lion looks suspicious 39 | //lvl twelve 40 | Find the cat above this text 41 | Move the text around 42 | //lvl thirteen 43 | Burn EVERYTHING 44 | Burn \"everything\" 45 | //lvl fourteen 46 | Fix the controller 47 | it\'s not plugged in 48 | //lvl fifteen 49 | Make a popcorn 50 | Find a lighter 51 | //profile 52 | \nI\'m in level %1d! \n Check out this game and share your progress:\n\n 53 | Share Progress 54 | Levels Unlocked: 55 | Your progress: 56 | //settings 57 | RATE APP 58 | CONTACT 59 | HELP 60 | SHARE 61 | -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | 17 | 23 | 24 | 28 | 29 | 33 | 34 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | buildscript { 3 | ext.kotlin_version = "1.5.10" 4 | ext.hilt_version = '2.36' 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | dependencies { 10 | classpath "com.android.tools.build:gradle:4.1.3" 11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 12 | classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version" 13 | classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0" 14 | // NOTE: Do not place your application dependencies here; they belong 15 | // in the individual module build.gradle files 16 | } 17 | } 18 | 19 | allprojects { 20 | repositories { 21 | google() 22 | jcenter() 23 | maven { url 'https://jitpack.io' } 24 | } 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app"s APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | # Kotlin code style for this project: "official" or "obsolete": 21 | kotlin.code.style=official 22 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThanaCS/Kotlin-Puzzle-Game/3647899d90bbd49dfa0d62d8a9934013bd47a605/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Nov 19 21:25:22 AST 2021 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | rootProject.name = "Simple Game" --------------------------------------------------------------------------------