Improve tutorial screen
This commit is contained in:
parent
f286f04618
commit
6d7ffc9e28
4 changed files with 102 additions and 18 deletions
|
@ -196,6 +196,10 @@ object TutorialField {
|
|||
this[23] = this[23].copy(isCovered = false)
|
||||
this[22] = this[22].copy(mark = Mark.Flag)
|
||||
this[18] = this[18].copy(highlighted = true)
|
||||
|
||||
this[24] = this[24].copy(highlighted = true)
|
||||
this[19] = this[19].copy(highlighted = true)
|
||||
this[14] = this[14].copy(highlighted = true)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,10 @@ package dev.lucasnlm.antimine.tutorial.view
|
|||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.text.bold
|
||||
import androidx.core.text.buildSpannedString
|
||||
import androidx.core.text.color
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
|
@ -65,8 +69,23 @@ class TutorialLevelFragment : Fragment(R.layout.fragment_tutorial_level) {
|
|||
|
||||
lifecycleScope.launchWhenCreated {
|
||||
tutorialViewModel.tutorialState.collect {
|
||||
val flagAction = tutorialViewModel.flagActionLabel()
|
||||
val openAction = tutorialViewModel.openActionLabel()
|
||||
|
||||
tutorial_top.apply {
|
||||
text = it.topMessage
|
||||
text = buildSpannedString {
|
||||
it.topMessage
|
||||
.splitKeeping(flagAction, openAction)
|
||||
.forEach {
|
||||
when (it) {
|
||||
flagAction, openAction -> {
|
||||
bold { color(ContextCompat.getColor(context, R.color.accent)) { append(it) } }
|
||||
}
|
||||
else -> append(it)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
setTextColor(
|
||||
Color.argb(
|
||||
255,
|
||||
|
@ -77,7 +96,19 @@ class TutorialLevelFragment : Fragment(R.layout.fragment_tutorial_level) {
|
|||
)
|
||||
}
|
||||
tutorial_bottom.apply {
|
||||
text = it.bottomMessage
|
||||
text = buildSpannedString {
|
||||
it.bottomMessage
|
||||
.splitKeeping(flagAction, openAction)
|
||||
.forEach {
|
||||
when (it) {
|
||||
flagAction, openAction -> {
|
||||
bold { color(ContextCompat.getColor(context, R.color.accent)) { append(it) } }
|
||||
}
|
||||
else -> append(it)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
setTextColor(
|
||||
Color.argb(
|
||||
255,
|
||||
|
@ -91,6 +122,18 @@ class TutorialLevelFragment : Fragment(R.layout.fragment_tutorial_level) {
|
|||
}
|
||||
}
|
||||
|
||||
private fun String.splitKeeping(str: String): List<String> {
|
||||
return this.split(str).flatMap {listOf(it, str)}.dropLast(1).filterNot {it.isEmpty()}
|
||||
}
|
||||
|
||||
private fun String.splitKeeping(vararg targetStrings: String): List<String> {
|
||||
var res = listOf(this)
|
||||
targetStrings.forEach { str ->
|
||||
res = res.flatMap {it.splitKeeping(str)}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
companion object {
|
||||
val TAG = TutorialLevelFragment::class.simpleName
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import dev.lucasnlm.antimine.common.level.utils.IHapticFeedbackManager
|
|||
import dev.lucasnlm.antimine.common.level.viewmodel.GameViewModel
|
||||
import dev.lucasnlm.antimine.core.analytics.IAnalyticsManager
|
||||
import dev.lucasnlm.antimine.core.analytics.models.Analytics
|
||||
import dev.lucasnlm.antimine.core.control.ControlStyle
|
||||
import dev.lucasnlm.antimine.core.preferences.IPreferencesRepository
|
||||
import dev.lucasnlm.antimine.core.sound.ISoundManager
|
||||
import dev.lucasnlm.antimine.core.themes.repository.IThemeRepository
|
||||
|
@ -23,15 +24,15 @@ class TutorialViewModel(
|
|||
savesRepository: ISavesRepository,
|
||||
statsRepository: IStatsRepository,
|
||||
dimensionRepository: IDimensionRepository,
|
||||
preferencesRepository: IPreferencesRepository,
|
||||
themeRepository: IThemeRepository,
|
||||
soundManager: ISoundManager,
|
||||
minefieldRepository: IMinefieldRepository,
|
||||
analyticsManager: IAnalyticsManager,
|
||||
playGamesManager: IPlayGamesManager,
|
||||
clock: Clock,
|
||||
private val clock: Clock,
|
||||
private val context: Context,
|
||||
private val hapticFeedbackManager: IHapticFeedbackManager,
|
||||
private val preferencesRepository: IPreferencesRepository,
|
||||
) : GameViewModel(
|
||||
savesRepository,
|
||||
statsRepository,
|
||||
|
@ -63,14 +64,25 @@ class TutorialViewModel(
|
|||
return tutorialState.value.step
|
||||
}
|
||||
|
||||
private fun wrapAction(action: String) = "\'$action\'"
|
||||
fun openActionLabel(): String =
|
||||
when (preferencesRepository.controlStyle()) {
|
||||
ControlStyle.Standard -> context.getString(R.string.single_click)
|
||||
ControlStyle.FastFlag -> context.getString(R.string.long_press)
|
||||
ControlStyle.DoubleClick -> context.getString(R.string.double_click)
|
||||
ControlStyle.DoubleClickInverted -> context.getString(R.string.single_click)
|
||||
}
|
||||
|
||||
private fun openActionLabel(): String = wrapAction(context.getString(R.string.single_click))
|
||||
|
||||
private fun flagActionLabel(): String = wrapAction(context.getString(R.string.long_press))
|
||||
fun flagActionLabel(): String =
|
||||
when (preferencesRepository.controlStyle()) {
|
||||
ControlStyle.Standard -> context.getString(R.string.long_press)
|
||||
ControlStyle.FastFlag -> context.getString(R.string.single_click)
|
||||
ControlStyle.DoubleClick -> context.getString(R.string.single_click)
|
||||
ControlStyle.DoubleClickInverted -> context.getString(R.string.double_click)
|
||||
}
|
||||
|
||||
private fun postStep(step: List<Area>, top: String, bottom: String, completed: Boolean = false) {
|
||||
field.postValue(step)
|
||||
clock.stop()
|
||||
tutorialState.value = tutorialState.value.copy(
|
||||
completed = completed,
|
||||
step = currentStep() + 1,
|
||||
|
@ -79,16 +91,13 @@ class TutorialViewModel(
|
|||
)
|
||||
}
|
||||
|
||||
override suspend fun onDoubleClick(index: Int) {
|
||||
}
|
||||
|
||||
override suspend fun onSingleClick(index: Int) {
|
||||
private fun openTileAction(index: Int) {
|
||||
when (currentStep()) {
|
||||
0 -> {
|
||||
postStep(
|
||||
TutorialField.getStep1(),
|
||||
context.getString(R.string.tutorial_1_top),
|
||||
context.getString(R.string.tutorial_1_bottom, openActionLabel()),
|
||||
context.getString(R.string.tutorial_1_bottom, flagActionLabel()),
|
||||
)
|
||||
}
|
||||
2 -> {
|
||||
|
@ -133,7 +142,7 @@ class TutorialViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun onLongClick(index: Int) {
|
||||
private fun longTileAction(index: Int) {
|
||||
when (currentStep()) {
|
||||
1 -> {
|
||||
if (index == 10) {
|
||||
|
@ -177,4 +186,32 @@ class TutorialViewModel(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun onDoubleClick(index: Int) {
|
||||
clock.stop()
|
||||
when (preferencesRepository.controlStyle()) {
|
||||
ControlStyle.DoubleClick -> openTileAction(index)
|
||||
ControlStyle.DoubleClickInverted -> longTileAction(index)
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun onSingleClick(index: Int) {
|
||||
clock.stop()
|
||||
when (preferencesRepository.controlStyle()) {
|
||||
ControlStyle.Standard -> openTileAction(index)
|
||||
ControlStyle.FastFlag -> longTileAction(index)
|
||||
ControlStyle.DoubleClick -> longTileAction(index)
|
||||
ControlStyle.DoubleClickInverted -> openTileAction(index)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun onLongClick(index: Int) {
|
||||
clock.stop()
|
||||
when (preferencesRepository.controlStyle()) {
|
||||
ControlStyle.Standard -> longTileAction(index)
|
||||
ControlStyle.FastFlag -> openTileAction(index)
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
|
@ -11,13 +12,12 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16sp"
|
||||
android:padding="24dp"
|
||||
android:paddingHorizontal="24dp"
|
||||
android:gravity="center_horizontal"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@+id/recyclerGrid"
|
||||
android:alpha="1.0"
|
||||
tools:text="Tutorial"/>
|
||||
|
||||
|
||||
|
@ -45,7 +45,7 @@
|
|||
android:layout_gravity="center_horizontal|bottom"
|
||||
android:gravity="center_horizontal"
|
||||
android:textSize="16sp"
|
||||
android:padding="24dp"
|
||||
android:paddingHorizontal="24dp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
|
|
Loading…
Reference in a new issue