Creating an app for Ubuntu Touch [QML] - [Part 2]

Introduction:

Well here we have the post that follows the PartIn this one we are going to focus on handling the data (questions), and we will start with the logic part of the game, in the next one we will finish the logic and implement the time and the 3 options.

You can find the code in my Launchpad repository (click here), where I'll update it as I go.

Database:

For the database we will use u1db, which is a database that saves the data in the format JSON.

First of all let's see what data we should save, we have 1 question (apart from the text of the question it would be nice to have an identifier), with 4 possible answers, of which only 1 can be, therefore the document in JSON single question should be:

{ "id": 1, "question": " there will be dev.desdelinux.net ", "answers" : { r1: "yes", r2: "no", r3: "don't know", r4: "this is a false answer" }, "correct": 3 }

As we see we have structured in format JSON where we have an identifier, a string with the question and r1, r2 that represent answer 1 and answer 2, finally we have which of the answers is correct.

Let's see a little how U1db works, the first thing we have to do to use U1db is to import the module:

import U1db 1.0 as U1db

We declare the database:

U1db.Database {
id: aDatabase
path: "aU1DbDatabase"
}

The databases will be saved as aU1DbDatabase.u1db, now we create a document:

U1db.Document {
id: aDocument
database: aDatabase
docId: 'helloworld'
create: true
defaults: { "hello": "Hello World!" }
}

Where we can see the format {«hello»: «something»}, to execute queries, either to add data, obtain data, delete them etc. We have the U1db.Query element.

We can find a tutorial on the development website of Ubuntu.

Let's go to our application and create our database, as we have seen we define the database:

U1db.Database {id: db questions; path: "questionsdb.u1db"}

Okay, now let's put some default elements in the database document questionsdb:

    U1db.Document { id: aDocument database: questionsdb docId: 'questions' create: true defaults: { "questions": [ {"question":"There will be dev.desdelinux.net ?", "r1":"yes", "r2":"no", "r3":"nose", "r4":"false answer", "correct": "3" }, {"question ":"Who is Hagrid (Harry Potter)?", "r1":"The vice principal of the school", "r2":"The gamekeeper", "r3":"The transformation teacher", "r4":" A prefect", "correct": "2"}, {"question":"What is the capital of Iceland?", "r1":"Amsterdam", "r2":"Reykjavik", "r3":" Tbilisi", "r4":"Almaty", "correct": "2"} ] } }

I am aware that the code is not displayed as it should, but if we look closely we will see that we have an element questions, which with the »[]» we specify that there can be several (they are not static) elements; in this case we will have 4 by default, 4 questions with their respective answers.

To get the document elements JSON, we can specify the identifier of the document we have created (which is aDocument). Let's imagine that we want to get the text of the first question:

aDocument.contents.questions [0] .question

This line of code returns us the question content of the document aDocument, of element 0 (the first in the index), which is: «There will be dev.desdelinux.net?” If we put the number 1 in the index, then it is the second question.

Programming the game logic

Well, now that we know how to handle a bit of the database where we have saved the questions, we are going to program the logic of the game. First of all we will create a file JavaScript (.js): Add new -> Qt -> Js File. I will call him logic.js.

In the file we are going to create several functions, to import the js file into our qml document:

import "logica.js" as Logica

We associate it with the name Logica, therefore when we want to call a function we will do it as Logica.funcion (), as if it were an object which has its methods.

For now, so that the post does not become too long, we will leave the time of the question and the options for later, we will concentrate on the questions and the points, let's see a function that we will use to move on from the question:

function nextQuestion (num) {// time = 0 question.text = aDocument.contents.questions [num] .question; resp1.text = aDocument.contents.questions [num] .r1; resp2.text = aDocument.contents.questions [num] .r2; resp3.text = aDocument.contents.questions [num] .r3; resp4.text = aDocument.contents.questions [num] .r4; }

As we can see, we pass the question number where we are as an argument and from here it puts the answers to the buttons and the question label. Let's see now to validate if the selected answer is correct:

function hit (num, option) {var hit = false; var num_correcto = aDocument.contents.questions [num] .correcto; if (option == correct_num) hit = true; return hit; }

The code speaks for itself, in case the chosen option is the same as the one provided by the database, then it will be true, otherwise it will not. Now that we have these functions defined, we will apply them in our qml code.

First of all we will add a variable that will control what question we are in, we will call it num; We will also have three more variables: hits, misses and points.

    property int num: 0 property int nfaults: 0 property int births: 0 property int npoints: 0

Initially they are all at 0.

Now we add an onClick to all the answer buttons. onClick, as its name says, is an event that will happen when that button is clicked:

            Button {id: resp1 text: "Response 1" anchors.horizontalCenter: parent.horizontalCenter width: parent.width - 20 onClicked: {if (Logic.certain (num, 1)) {num = num + 1; Logic.nextQuestion (num) npoints = npoints + 50 births = births + 1} else {nfaults = nfaults + 1}}}

We see that when you click the button, it checks if it is correct or not, if it is, add the points and pass the question, otherwise one life remains.

Finally we will make the first question load when the Page component loads:

    Page {id: pageGame Component.onCompleted: {Logic.nextPregunta (0)}

Let's see how it turned out:

test


Leave a Comment

Your email address will not be published. Required fields are marked with *

*

*

  1. Responsible for the data: Miguel Ángel Gatón
  2. Purpose of the data: Control SPAM, comment management.
  3. Legitimation: Your consent
  4. Communication of the data: The data will not be communicated to third parties except by legal obligation.
  5. Data storage: Database hosted by Occentus Networks (EU)
  6. Rights: At any time you can limit, recover and delete your information.

  1.   gabielus said

    I follow the steps and everything works. Just to collaborate I say that:
    * Does not change the value of hits and misses. You have to add that to each button in your click event.
    * And that in the line:
    if (Logic.acerto (num, 1)) {
    change the 1 to the number of the button / answer.

    lolbimbo, I find your contribution interesting. I hope new tutos !!!

    Thanks for sharing.

    1.    lolbimbo said

      I like that you have commented on these points because I did not make it clear in the post, what's more, I do not remember the points, the successes and failures, if you look at it you will see that when we click the button, we add the points the successes ... but they are not reflected in the Label, that is why we have to put it in its text property that shows the points:

      Label {
      id: failures
      text: «Faults:» + nfaults
      color: "red"
      }

      Label {
      id: hits
      text: «Hits:» + born
      }

      Label {
      id: points
      text: «Points:» + npoints
      fontSize: "medium"
      }

      I will also clarify it in part 3.