File indexing completed on 2024-04-28 15:07:58

0001 /* GCompris - note_names.js
0002  *
0003  * SPDX-FileCopyrightText: 2018 Aman Kumar Gupta <gupta2140@gmail.com>
0004  *
0005  * Authors:
0006  *   Aman Kumar Gupta <gupta2140@gmail.com>
0007  *
0008  *   SPDX-License-Identifier: GPL-3.0-or-later
0009  */
0010 .pragma library
0011 .import QtQuick 2.12 as Quick
0012 .import "qrc:/gcompris/src/core/core.js" as Core
0013 
0014 var numberOfLevel
0015 var dataset
0016 var items
0017 var levels
0018 var targetNotes = []
0019 var newNotesSequence = []
0020 var currentNoteIndex
0021 var noteIndexToDisplay
0022 var percentageDecreaseValue = 4
0023 var percentageIncreaseValue = 2
0024 var timerNormalInterval
0025 
0026 function start(items_, timerNormalInterval_) {
0027     items = items_
0028     timerNormalInterval = timerNormalInterval_
0029     dataset = items.dataset.item
0030     levels = dataset.levels
0031     numberOfLevel = levels.length
0032     items.currentLevel = Core.getInitialLevel(numberOfLevel)
0033     items.doubleOctave.coloredKeyLabels = dataset.referenceNotes[levels[0]["clef"]]
0034     items.doubleOctave.currentOctaveNb = 1
0035     items.introMessage.intro = [dataset.objective]
0036     initLevel()
0037 }
0038 
0039 function stop() {
0040     newNotesSequence = []
0041     items.multipleStaff.pauseNoteAnimation()
0042     items.displayNoteNameTimer.stop()
0043     items.addNoteTimer.stop()
0044 }
0045 
0046 function initLevel() {
0047     targetNotes = []
0048     newNotesSequence = []
0049     items.background.clefType = levels[items.currentLevel]["clef"]
0050     items.doubleOctave.coloredKeyLabels = dataset.referenceNotes[items.background.clefType]
0051     if(items.background.clefType === "Treble")
0052         items.doubleOctave.currentOctaveNb = 1
0053     else
0054         items.doubleOctave.currentOctaveNb = 2
0055 
0056     items.multipleStaff.pauseNoteAnimation()
0057     items.displayNoteNameTimer.stop()
0058     items.addNoteTimer.stop()
0059     items.multipleStaff.initClefs(items.background.clefType)
0060     targetNotes = JSON.parse(JSON.stringify(levels[items.currentLevel]["sequence"]))
0061     items.isTutorialMode = true
0062     items.progressBar.percentage = 0
0063     items.multipleStaff.coloredNotes = dataset.referenceNotes[items.background.clefType]
0064     if(!items.iAmReady.visible  && !items.introMessage.visible)
0065         showTutorial()
0066 }
0067 
0068 function showTutorial() {
0069     items.messageBox.visible = false
0070     if(targetNotes.length) {
0071         displayNote(targetNotes[0])
0072         items.messageBox.visible = true
0073         targetNotes.shift()
0074     }
0075     else if (!items.iAmReady.visible) {
0076         items.isTutorialMode = false
0077         startGame()
0078     }
0079 }
0080 
0081 // The principle is to fill half sequence (length 25) with the notes from previous levels and another half with current level's target notes and shuffle them.
0082 function formNewNotesSequence() {
0083     var halfSequenceLength = 25
0084     var fullSequenceLength = 50
0085     targetNotes = JSON.parse(JSON.stringify(levels[items.currentLevel]["sequence"]))
0086     for(var i = 0; i < items.currentLevel && newNotesSequence.length < halfSequenceLength; i++) {
0087         if(levels[items.currentLevel]["clef"] === levels[i]["clef"]) {
0088             for(var j = 0; j < levels[i]["sequence"].length && newNotesSequence.length < halfSequenceLength; j++)
0089                 newNotesSequence.push(levels[i]["sequence"][j])
0090         }
0091     }
0092 
0093     for(var i = 0; newNotesSequence.length && newNotesSequence.length < halfSequenceLength; i++)
0094         newNotesSequence.push(newNotesSequence[i % newNotesSequence.length])
0095 
0096     for(var i = 0; newNotesSequence.length < fullSequenceLength; i++)
0097         newNotesSequence.push(targetNotes[i % targetNotes.length])
0098 
0099     Core.shuffle(newNotesSequence)
0100 }
0101 
0102 function startGame() {
0103     currentNoteIndex = 0
0104     noteIndexToDisplay = 0
0105     items.progressBar.percentage = 0
0106     formNewNotesSequence()
0107     displayNote(newNotesSequence[0])
0108 }
0109 
0110 function displayNote(currentNote) {
0111     items.multipleStaff.addMusicElement("note", currentNote, "Quarter", false, false, items.background.clefType)
0112     items.multipleStaff.playNoteAudio(currentNote, "Quarter", items.background.clefType, 500)
0113     if(!items.isTutorialMode) {
0114         items.addNoteTimer.interval = timerNormalInterval
0115         items.addNoteTimer.start()
0116     }
0117 }
0118 
0119 function wrongAnswer() {
0120     if(items.multipleStaff.musicElementRepeater.itemAt(1).x <= items.multipleStaff.clefImageWidth) {
0121         items.multipleStaff.musicElementModel.remove(1)
0122         currentNoteIndex = (currentNoteIndex + 1) % newNotesSequence.length
0123     }
0124 
0125     items.progressBar.percentage = Math.max(0, items.progressBar.percentage - percentageDecreaseValue)
0126     items.multipleStaff.resumeNoteAnimation()
0127     if(items.multipleStaff.musicElementModel.count <= 1)
0128         items.addNoteTimer.restart()
0129 }
0130 
0131 function correctAnswer() {
0132     currentNoteIndex = (currentNoteIndex + 1) % newNotesSequence.length
0133     items.multipleStaff.pauseNoteAnimation()
0134     items.multipleStaff.musicElementModel.remove(1)
0135     items.multipleStaff.resumeNoteAnimation()
0136     items.progressBar.percentage += percentageIncreaseValue
0137     if(items.progressBar.percentage === 100) {
0138         items.multipleStaff.pauseNoteAnimation()
0139         items.displayNoteNameTimer.stop()
0140         items.addNoteTimer.stop()
0141         items.bonus.good("flower")
0142     }
0143     else if(items.multipleStaff.musicElementModel.count <= 1)
0144         items.addNoteTimer.restart()
0145 }
0146 
0147 function checkAnswer(noteName) {
0148     if(noteName === items.multipleStaff.musicElementModel.get(1).noteName_)
0149         correctAnswer()
0150     else
0151         items.displayNoteNameTimer.start()
0152 }
0153 
0154 function nextLevel() {
0155     items.currentLevel = Core.getNextLevel(items.currentLevel, numberOfLevel)
0156     initLevel()
0157 }
0158 
0159 function previousLevel() {
0160     items.currentLevel = Core.getPreviousLevel(items.currentLevel, numberOfLevel);
0161     initLevel()
0162 }