Hello everyone! Today you will find an easy article that will tell you how to write a simple mobile quiz game in Kotlin. Here I will clearly show what Kotlin looks like for mobile development and offer my ideas on how to structure such a project. Well, I will not torment you with graphomania, go ahead!
Now you will see the skeleton of an idea that burned brightly, but quickly burned out. My designer friend and I came up with the idea of ββmaking a simple mobile game in text format. The genre was planned to be adventure, and the mean text had to be fueled by unique pictures in a certain style. Unfortunately, things did not go beyond the skeleton of the application, so I decided to make it public. Suddenly someone will find new thoughts. I'll make a reservation right away that the project can hardly be called a serious decision, and for really large applications, it may be worth considering more complex abstractions. The application should be perceived as a kind of MVP.
Folder structure
First, let's talk about the folder structure. It is unlikely that there will be anything innovative here, but I consider the folder structure in a project to be one of the most important and interesting things in programming.
2 Activity, .
StartActivity , - (, ββ ..).
MainActivity, - GameActivity, , .
Entity . json , , Entity.
dao ( data access object) , . , Runtime, , .
core , . , .
UI , , - . , presenter- activity.
MVP json-, . :
{
"id": 2,
"type": "Q",
"question": " . !",
"answers": [
{
"next_question_id": 5,
"answer": " "
},
{
"next_question_id": 3,
"answer": ", "
}
]
}
, :
Id - . . ,
type - . Q , "question" . F (Fail) S (Success). , ,
question - ,
answers - . 0 4 . , F S. , , ,
JSON assests. , . , , JSON , sqllite. , .
, , , . , . .
, runtime. Store.
public interface Store {
fun getAllQuestions(): List<Question>
fun getQuestionById(id: Int): Question
fun init(context: Context): Store
}
, . , - . MVP JSON-, , . , , , , sqllite . , - .
class StoreFactory {
companion object {
fun getStore(ctx: Context): Store {
return LocalStore().init(ctx)
}
}
}
. , . , , ANR. IO - . production , RX. , .
:
class Game {
private lateinit var store: Store
private lateinit var question: Question
fun init(context: Context) {
this.store = StoreFactory.getStore(context)
question = store.getQuestionById(1)
}
fun isGameEnd(): Boolean {
return isSuccess() || isFail()
}
fun isSuccess(): Boolean {
return question.isSuccess()
}
fun isFail(): Boolean {
return question.isFail()
}
fun chooseAnswer(numberOfAnswer: Int) {
val answer: Answer = question.getAnswers()[numberOfAnswer - 1]
question = store.getQuestionById(answer.getNextQuestionId())
}
fun getQuestion(): Question {
return question
}
}
2 : Store, , , . , ( type F S). , .
. , , . .
(Question.kt). :
fun getAnswers(): List<Answer> {
val list: MutableList<Answer> = ArrayList(this.answers)
val shouldAdd: Int = 4 - list.size
for (i in 1..shouldAdd) {
list.add(Answer("", -1))
}
return list
}
List 4 , , 2. id. , . , .
, 4 , . , presenter:
private fun updateView() {
if (game.isGameEnd()) {
showEndGame()
return
}
activity.setQuestion(game.getQuestion().getText())
val answers: List<Answer> = game.getQuestion().getAnswers()
answers.forEachIndexed {idx, answer -> activity.setAnswer(idx + 1, answer.getText())}
}
fun chooseAnswer(number: Int) {
game.chooseAnswer(number)
updateView()
}
, StartActivity, ( ) Intent:
private fun showEndGame() {
val intent = Intent(activity, StartActivity::class.java).apply {
putExtra(StartActivity.RESULT_MESSAGE, game.getQuestion().getText())
}
activity.startActivity(intent)
}
, production-ready. , . MVP, , . , :
. ,
UI- , .
,
json - , loader
json sqllite