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

0001 /* GCompris - babymatch.js
0002  *
0003  * SPDX-FileCopyrightText: 2015 Pulkit Gupta
0004  *
0005  * Authors:
0006  *   Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
0007  *   Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
0008  *
0009  *   SPDX-License-Identifier: GPL-3.0-or-later
0010  */
0011 .pragma library
0012 .import QtQuick 2.12 as Quick
0013 .import GCompris 1.0 as GCompris //for ApplicationInfo
0014 .import "qrc:/gcompris/src/core/core.js" as Core
0015 
0016 var useMultipleDataset;
0017 var currentSubLevel = 0;
0018 var numberOfLevel;
0019 var numberOfSubLevel;
0020 var items;
0021 var imagesUrl;
0022 var soundsUrl;
0023 var boardsUrl;
0024 var glowEnabled;
0025 var glowEnabledDefault;
0026 var spots = [];
0027 var showText = [];
0028 var displayDropCircle;
0029 
0030 function start(items_, imagesUrl_, soundsUrl_, boardsUrl_, levelCount_, answerGlow_, displayDropCircle_, useMultipleDataset_) {
0031     items = items_;
0032     imagesUrl = imagesUrl_;
0033     soundsUrl = soundsUrl_;
0034     boardsUrl = boardsUrl_;
0035     useMultipleDataset = useMultipleDataset_;
0036     numberOfLevel = useMultipleDataset ? items.levels.length : levelCount_;
0037     glowEnabledDefault = answerGlow_;
0038     displayDropCircle = displayDropCircle_;
0039 
0040     items.currentLevel = Core.getInitialLevel(numberOfLevel);
0041 
0042     currentSubLevel = 0;
0043     numberOfSubLevel = 0;
0044     resetData();
0045     initLevel();
0046 }
0047 
0048 function resetData() {
0049     items.availablePieces.model.clear();
0050     for(var i = 0 ; i < spots.length ; ++ i) {
0051         spots[i].destroy();
0052     }
0053     spots = [];
0054 
0055     for(var i = 0 ; i < showText.length ; ++ i)
0056         showText[i].destroy();
0057     showText = [];
0058 
0059     items.backgroundPiecesModel.clear();
0060     items.backgroundImageSource.source = "";
0061 }
0062 
0063 function stop() {
0064     resetData();
0065 }
0066 
0067 function initLevel() {
0068     if(useMultipleDataset)
0069         items.dataset.source = items.levels[items.currentLevel][currentSubLevel];
0070     else
0071         items.dataset.source = boardsUrl + "board" + "/" + "board" + (items.currentLevel+1) + "_" + currentSubLevel + ".qml";
0072     var levelData = items.dataset.item;
0073     resetData();
0074     items.availablePieces.view.currentDisplayedGroup = 0;
0075     items.availablePieces.view.previousNavigation = 1;
0076     items.availablePieces.view.nextNavigation = 1;
0077     items.availablePieces.view.okShowed = false;
0078     items.availablePieces.view.showGlow = false;
0079     items.availablePieces.view.ok.height = 0;
0080 
0081     var dropItemComponent = Qt.createComponent("qrc:/gcompris/src/activities/babymatch/DropAnswerItem.qml");
0082     var textItemComponent = Qt.createComponent("qrc:/gcompris/src/activities/babymatch/TextItem.qml");
0083 
0084     if(currentSubLevel == 0 && levelData.numberOfSubLevel != undefined)
0085         numberOfSubLevel = levelData.numberOfSubLevel;
0086 
0087     items.score.currentSubLevel = currentSubLevel + 1;
0088     items.score.numberOfSubLevels = numberOfSubLevel + 1;
0089 
0090     if(levelData.glow === undefined)
0091         glowEnabled = glowEnabledDefault;
0092     else
0093         glowEnabled = levelData.glow;
0094 
0095     items.toolTip.show('');
0096 
0097     if(levelData.instruction === undefined) {
0098         items.instruction.opacity = 0;
0099         items.instruction.text = "";
0100     } else if(!displayDropCircle) {
0101         items.instruction.opacity = 0;
0102         items.instruction.text = levelData.instruction;
0103     }
0104     else {
0105         items.instruction.opacity = 1;
0106         items.instruction.text = levelData.instruction;
0107     }
0108         
0109     // Fill available pieces
0110     var arr = [];
0111     var levelDataLength = levelData.levels.length;
0112     for(var i=0 ; i < levelDataLength ; i++)
0113         arr[i] = i;
0114 
0115     var i = 0, j = 0, k = 0, n = 0;
0116     while(levelDataLength--) {
0117 
0118         //Randomize the order of pieces
0119         var rand = Math.floor(Math.random() * levelDataLength);
0120         i = arr[rand];
0121         arr.splice(rand,1);
0122 
0123         //Create answer pieces
0124         if(levelData.levels[i].type === undefined) {
0125             items.availablePieces.model.append( {
0126                 "imgName": levelData.levels[i].pixmapfile,
0127                 "imgSound": levelData.levels[i].soundFile ?
0128                      soundsUrl + levelData.levels[i].soundFile :
0129                      "qrc:/gcompris/src/core/resource/sounds/scroll.wav",
0130                 "imgHeight": levelData.levels[i].height === undefined ? 0 : levelData.levels[i].height,
0131                 "imgWidth": levelData.levels[i].width === undefined ? 0 : levelData.levels[i].width,
0132                 "toolTipText":
0133                    // We remove the text before the pipe symbol if any (translation disembiguation)
0134                    levelData.levels[i].toolTipText === undefined ?
0135                                                        "" :
0136                                                        (levelData.levels[i].toolTipText.split('|').length > 1 ?
0137                                                         levelData.levels[i].toolTipText.split('|')[1] :
0138                                                         levelData.levels[i].toolTipText),
0139             });
0140 
0141             spots[j++] = dropItemComponent.createObject(
0142                          items.backgroundImage, {
0143                             "posX": levelData.levels[i].x,
0144                             "posY": levelData.levels[i].y,
0145                             "imgName" : levelData.levels[i].pixmapfile,
0146                          });
0147         }
0148         //Create Text pieces for the level which has to display additional information
0149         else if(levelData.levels[i].type === "DisplayText") {
0150                         showText[k++] = textItemComponent.createObject(
0151                             items.backgroundImage, {
0152                                 "posX": levelData.levels[i].x,
0153                                 "posY": levelData.levels[i].y,
0154                                 "textWidth": levelData.levels[i].width,
0155                                 "textHeight": levelData.levels[i].height,
0156                                 "showText" : levelData.levels[i].text
0157                             });
0158         }
0159         //Create static background pieces
0160         else {
0161             if(levelData.levels[i].type === "SHAPE_BACKGROUND_IMAGE") {
0162                 items.backgroundImageSource.source = imagesUrl + levelData.levels[i].pixmapfile;
0163                 if(levelData.levels[i].width)
0164                     items.backgroundImageSource.sourceSize.width = levelData.levels[i].width;
0165                 if(levelData.levels[i].height)
0166                     items.backgroundImageSource.sourceSize.height = levelData.levels[i].height;
0167             }
0168             else {
0169                 items.backgroundPiecesModel.append( {
0170                     "imgName": levelData.levels[i].pixmapfile,
0171                     "posX": levelData.levels[i].x,
0172                     "posY": levelData.levels[i].y,
0173                     "imgHeight": levelData.levels[i].height === undefined ? 0 : levelData.levels[i].height,
0174                     "imgWidth": levelData.levels[i].width === undefined ? 0 : levelData.levels[i].width,
0175                 });
0176             }
0177         }
0178     }
0179 
0180     //Initialize displayedGroup variable which is used for showing navigation bars
0181     for(var i=0;i<items.availablePieces.view.nbDisplayedGroup;++i)
0182         items.availablePieces.view.displayedGroup[i] = true;
0183     items.inputLocked = false;
0184 }
0185 
0186 function hideInstructions() {
0187         items.instruction.opacity = 0;
0188 }
0189 
0190 function nextSubLevel() {
0191     if(numberOfSubLevel < ++currentSubLevel) {
0192         nextLevel();
0193     }
0194     else
0195         initLevel();
0196 }
0197 
0198 function nextLevel() {
0199     currentSubLevel = 0;
0200     numberOfSubLevel = 0;
0201     items.currentLevel = Core.getNextLevel(items.currentLevel, numberOfLevel);
0202     initLevel();
0203 }
0204 
0205 function previousLevel() {
0206     currentSubLevel = 0;
0207     numberOfSubLevel = 0;
0208     items.currentLevel = Core.getPreviousLevel(items.currentLevel, numberOfLevel);
0209     initLevel();
0210 }
0211 
0212 function win() {
0213     items.bonus.good("flower");
0214 }
0215 
0216 function getClosestSpot(x, y) {
0217     var minDist = 200 * GCompris.ApplicationInfo.ratio;
0218     var closestDist = Number.MAX_VALUE;
0219     var closestItem;
0220     for(var i = 0 ; i < spots.length ; ++ i) {
0221         // Calc Distance
0222         var spot = spots[i];
0223         var dist = Math.floor(Math.sqrt(Math.pow(x - spot.x, 2) +
0224                                         Math.pow(y - spot.y, 2)));
0225         if(dist < closestDist) {
0226             closestDist = dist;
0227             closestItem = spot;
0228         }
0229     }
0230     if(closestDist < minDist) {
0231         return closestItem;
0232     } else {
0233         return null;
0234     }
0235 }
0236 
0237 function highLightSpot(stopItem, tile) {
0238     for(var i = 0 ; i < spots.length ; ++ i) {
0239         if(spots[i] === stopItem) {
0240             spots[i].show(tile);
0241         } else {
0242             spots[i].hide();
0243         }
0244     }
0245 }
0246 
0247 function clearHighLightSpots() {
0248     for(var i = 0 ; i < spots.length ; ++ i) {
0249         spots[i].hide();
0250     }
0251 }