diff --git a/src/activities/crane/Controls.qml b/src/activities/crane/Controls.qml index f3b212b5c..6ea8b4aaa 100755 --- a/src/activities/crane/Controls.qml +++ b/src/activities/crane/Controls.qml @@ -1,41 +1,43 @@ -/* GCompris - Crane.qml +/* GCompris - Controls.qml * * Copyright (C) 2016 Stefan Toncu * * Authors: * (GTK+ version) * Stefan Toncu (Qt Quick port) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ import QtQuick 2.1 import "crane.js" as Activity Image { property var command - sourceSize.width: parent.width * 0.15 - sourceSize.height: parent.height * 0.55 + sourceSize.width: background.portrait ? parent.width * 0.175 : parent.width * 0.17 + sourceSize.height: background.portrait ? parent.height * 0.6 : parent.height * 0.48 + width: background.portrait ? parent.width * 0.175 : parent.width * 0.17 + height: background.portrait ? parent.height * 0.6 : parent.height * 0.48 anchors { verticalCenter: parent.verticalCenter } MouseArea { anchors.fill: parent onPressed: parent.opacity = 0.6 onReleased: parent.opacity = 1 onClicked: { Activity.move(command) } } } diff --git a/src/activities/crane/Crane.qml b/src/activities/crane/Crane.qml index 5cddf3b03..5f836d2f7 100644 --- a/src/activities/crane/Crane.qml +++ b/src/activities/crane/Crane.qml @@ -1,469 +1,473 @@ /* GCompris - Crane.qml * * Copyright (C) 2016 Stefan Toncu * * Authors: * (GTK+ version) * Stefan Toncu (Qt Quick port) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ import QtQuick 2.1 import "../../core" import "crane.js" as Activity ActivityBase { id: activity onStart: focus = true onStop: {} pageComponent: Rectangle { id: background anchors.fill: parent color: "#ffeecc" signal start signal stop Component.onCompleted: { activity.start.connect(start) activity.stop.connect(stop) } // Add here the QML items you need to access in javascript QtObject { id: items property Item main: activity.main property alias background: background property alias bar: bar property alias bonus: bonus property alias board: board property alias grid: grid property alias repeater: repeater property alias modelRepeater: modelRepeater property alias gridRepeater: gridRepeater property alias showGrid1: showGrid1 property int selected property int columns property int rows property bool ok: true property int sensivity: 80 property bool gameFinished: false } onStart: { Activity.start(items) } onStop: { Activity.stop() } property bool portrait: height > width ? true : false property bool inLine: true Keys.onPressed: { if (event.key === Qt.Key_Left) Activity.move("left") else if (event.key === Qt.Key_Right) Activity.move("right") else if (event.key === Qt.Key_Up) Activity.move("up") else if (event.key === Qt.Key_Down) Activity.move("down") else if (event.key === Qt.Key_Space || event.key === Qt.Key_Tab || event.key === Qt.Key_Enter || event.key === Qt.Key_Return) Activity.move("next") } //implementation of Swipe effect MouseArea { anchors.fill: parent property int startX; property int startY; onPressed: { startX = mouse.x; startY = mouse.y; } onReleased: Activity.gesture(mouse.x - startX, mouse.y - startY) } Rectangle { id: board color: "lightblue" radius: width * 0.02 z: 1 anchors { verticalCenter: crane_vertical.verticalCenter right: crane_vertical.left margins: 15 } width: background.portrait ? parent.width * 0.65 : ((parent.width - anchors.margins * 3 - crane_vertical.width) / 2 ) * 0.9 height: background.portrait ? (parent.height - bar.height * 1.45 - crane_top.height - crane_body.height ) / 2 : (parent.height - bar.height * 1.45 - crane_top.height - crane_body.height) * 0.9 } Grid { id: showGrid1 columns: items.columns rows: items.rows z: 1 anchors.fill: board Repeater { id: gridRepeater Rectangle { width: board.width/items.columns height: board.height/items.rows color: "transparent" border.width: 2 border.color: "grey" } } } Rectangle { id: coverEgdes1 color: "transparent" width: board.width height: board.height border.color: board.color border.width: 10 opacity: showGrid1.opacity anchors.centerIn: board z: 3 } Grid { id: grid columns: items.columns rows: items.rows z: 4 anchors.fill: board Repeater { id: repeater Image { id: figure sourceSize.height: board.height/3 sourceSize.width: board.width/3 width: board.width/items.columns height: board.height/items.rows property int initialIndex: -1 property bool showSelected: false property alias selected: selected property alias anim: anim property alias opac: selected.opacity property int distance property int indexChange property int startPoint property string animationProperty property int _index: index // make current index accessible from outside SequentialAnimation { id: anim PropertyAction { target: items; property: "ok"; value: "false"} NumberAnimation { target: figure; property: figure.animationProperty; from: figure.startPoint; to: figure.startPoint + distance; duration: 200 } PropertyAction { target: figure; property: "opacity"; value: 0 } PropertyAction { target: selected; property: "opacity"; value: 0 } NumberAnimation { target: figure; property: figure.animationProperty; from: figure.startPoint + distance; to: figure.startPoint; duration: 0; } PropertyAction { target: figure; property: "opacity"; value: 1 } PropertyAction { target: items.repeater.itemAt(items.selected + indexChange); property: "source"; value: figure.source } PropertyAction { target: items.repeater.itemAt(items.selected + indexChange); property: "opac"; value: 1 } PropertyAction { target: items.repeater.itemAt(items.selected + indexChange); property: "initialIndex"; value: figure.initialIndex } PropertyAction { target: figure; property: "initialIndex"; value: -1 } PropertyAction { target: figure; property: "source"; value: "" } PropertyAction { target: items; property: "ok"; value: "true"} ScriptAction { script: Activity.checkAnswer() } } MouseArea { anchors.fill: parent // Swipe effect property int startX; property int startY; onPressed: { startX = mouse.x; startY = mouse.y; } onReleased: Activity.gesture(mouse.x - startX, mouse.y - startY) // Select a figure with mouse/touch onClicked: { if (source != "") { items.repeater.itemAt(items.selected).opac = 0 items.selected = index items.repeater.itemAt(items.selected).opac = 1 } } } // selected marker Image { id: selected source: "resource/selected.png" width: parent.width height: parent.height opacity: 0 } } } } Rectangle { id: modelBoard color: "pink" radius: width * 0.02 z: 1 anchors { left: background.portrait ? board.left : crane_vertical.right top: background.portrait ? crane_body.bottom : background.inLine ? board.top : parent.top topMargin: background.portrait ? board.anchors.margins : background.inLine ? 0 : crane_top.height * 1.5 leftMargin: background.portrait ? 0 : board.anchors.margins * 1.2 margins: board.anchors.margins } width: board.width height: board.height } Grid { id: modelGrid columns: items.columns rows: items.rows anchors.fill: modelBoard z: 4 Repeater { id: modelRepeater Image { id: modelFigure sourceSize.height: board.height/items.rows sourceSize.width: board.width/items.columns width: board.width/items.columns height: board.height/items.rows } } } Grid { id: showGrid2 columns: items.columns rows: items.rows z: 1 opacity: showGrid1.opacity anchors.fill: modelBoard Repeater { id: gridRepeater2 model: gridRepeater.model Rectangle { width: modelBoard.width/items.columns height: modelBoard.height/items.rows color: "transparent" border.width: 2 border.color: showGrid1.opacity == 1 ? "grey" : "transparent" } } } Rectangle { id: coverEgdes2 color: "transparent" width: modelBoard.width height: modelBoard.height border.color: showGrid1.opacity == 1 ? modelBoard.color : "transparent" border.width: 10 anchors.centerIn: modelBoard opacity: showGrid1.opacity z: 3 } Image { id: crane_top source: "resource/crane_up.svg" sourceSize.width: background.portrait ? background.width * 0.8 : background.width * 0.5 sourceSize.height: background.portrait ? background.height * 0.03 : background.height * 0.06 width: background.portrait ? background.width * 0.8 : background.width * 0.5 height: background.portrait ? background.height * 0.03 : background.height * 0.06 z: 4 anchors { top: parent.top right: crane_vertical.right rightMargin: 0 margins: board.anchors.margins } } Image { id: crane_vertical source: "resource/crane_vertical.svg" sourceSize.width: background.width * 0.04 - sourceSize.height: background.height * 0.73 + sourceSize.height: background.portrait ? background.height * 0.5 : background.height * 0.73 width: background.width * 0.05 - height: background.portrait ? background.height * 0.45 : background.height * 0.73 + height: background.portrait ? background.height * 0.5 : background.height * 0.73 anchors { top: crane_top.top right: background.portrait ? parent.right : parent.horizontalCenter rightMargin: background.portrait ? width / 2 : - width / 2 topMargin: board.anchors.margins } } Image { id: crane_body source: "resource/crane_only.svg" z: 2 sourceSize.width: parent.width / 5 sourceSize.height: parent.height/ 3.6 mirror: background.portrait ? true : false anchors { top: crane_vertical.bottom topMargin: - (height / 1.8) right: crane_vertical.right rightMargin: background.portrait ? board.anchors.margins : - crane_body.width + crane_vertical.width margins: board.anchors.margins } } Image { id: crane_wire source: "resource/crane-wire.svg" z: 1 sourceSize.width: parent.width / 22 sourceSize.height: parent.width / 17 anchors { right: crane_body.left bottom: crane_command.verticalCenter rightMargin: -10 bottomMargin: -10 } } Image { id: crane_command source: "resource/command.svg" - sourceSize.width: parent.width / 4 - sourceSize.height: parent.height/ 3.5 + sourceSize.width: background.portrait ? parent.width / 2.7 : parent.width / 3.5 + sourceSize.height: background.portrait ? parent.height / 3.5 : parent.height / 4 + + width: background.portrait ? parent.width / 2.7 : parent.width / 3.5 + height: background.portrait ? parent.height / 3.5 : parent.height / 4 + mirror: true anchors { top: crane_body.top bottom: crane_body.bottom right: crane_wire.left rightMargin: 0 - topMargin: background.portrait ? board.anchors.margins : 50 - margins: board.anchors.margins + topMargin: background.portrait ? 0 : board.anchors.margins * 1.5 + bottomMargin: background.portrait ? 0 : board.anchors.margins * 1.5 } Controls { id: up source: "resource/arrow_up.svg" anchors { left: parent.left - leftMargin: parent.width / 10 + leftMargin: parent.width / 13 } command: "up" } Controls { id: down source: "resource/arrow_down.svg" anchors { left: up.right - leftMargin: parent.width / 20 + leftMargin: parent.width / 30 } command: "down" } Controls { id: left source: "resource/arrow_left.svg" anchors { right: right.left - rightMargin: parent.width / 20 + rightMargin: parent.width / 30 } command: "left" } Controls { id: right source: "resource/arrow_right.svg" anchors { right: parent.right rightMargin: parent.width / 10 } command: "right" } } Rectangle { id: cable color: "black" width: 5 height: convert.y - crane_top.y x: convert.x + board.width / items.columns / 2 z: 3 anchors.top: crane_top.top anchors.topMargin: 10 property var convert: items.selected == 0 ? grid : items.repeater.mapToItem(background,items.repeater.itemAt(items.selected).x, items.repeater.itemAt(items.selected).y) Behavior on x { NumberAnimation { duration: 200 } } Behavior on height { NumberAnimation { duration: 200 } } } DialogHelp { id: dialogHelp onClose: home() } Bar { id: bar content: BarEnumContent { value: help | home | level } onHelpClicked: { displayDialog(dialogHelp) } onPreviousLevelClicked: Activity.previousLevel() onNextLevelClicked: Activity.nextLevel() onHomeClicked: activity.home() } Bonus { id: bonus Component.onCompleted: win.connect(Activity.nextLevel) } } } diff --git a/src/activities/crane/crane.js b/src/activities/crane/crane.js index f19a49646..adec80003 100644 --- a/src/activities/crane/crane.js +++ b/src/activities/crane/crane.js @@ -1,357 +1,401 @@ /* GCompris - crane.js * * Copyright (C) 2016 Stefan Toncu * * Authors: * (GTK+ version) * Stefan Toncu (Qt Quick port) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ .pragma library .import QtQuick 2.0 as Quick .import "qrc:/gcompris/src/core/core.js" as Core var currentLevel = 0 var numberLevelsWords = 2 var maxWordLevels = 3 * numberLevelsWords var maxImageLevels = 10 var numberOfLevel = maxWordLevels + maxImageLevels var items var url = "qrc:/gcompris/src/activities/crane/resource/" var levels = [{showGrid: 1, noOfItems: 2, inLine: 1, columns: 4, rows: 3 }, {showGrid: 1, noOfItems: 3, inLine: 1, columns: 5, rows: 4 }, {showGrid: 1, noOfItems: 4, inLine: 1, columns: 6, rows: 5 }, {showGrid: 0, noOfItems: 5, inLine: 0, columns: 7, rows: 6 }, {showGrid: 0, noOfItems: 6, inLine: 0, columns: 7, rows: 6 }, {showGrid: 1, noOfItems: 7, inLine: 1, columns: 7, rows: 6 }, {showGrid: 1, noOfItems: 8, inLine: 1, columns: 7, rows: 6 }, {showGrid: 0, noOfItems: 9, inLine: 0, columns: 7, rows: 6 }, {showGrid: 0, noOfItems: 10, inLine: 0, columns: 7, rows: 6 }, {showGrid: 0, noOfItems: 11, inLine: 0, columns: 7, rows: 6 }] var allNames = ["bulb.svg","letter-a.svg","letter-b.svg", "rectangle1.svg","rectangle2.svg","square1.svg", "square2.svg","triangle1.svg","triangle2.svg", "tux.svg","water_drop1.svg","water_drop2.svg", "water_spot1.svg","water_spot2.svg"] var words3Letters = ["cat","dog","win","red","yes","big","box","air","arm", "car","bus","fun","day","eat","hat","leg","ice","old","egg"] var words4Letters = ["blue","best","good","area","bell","coat","easy","farm", "food","else","girl","give","hero","help","hour","sand","song"] var words5Letters = ["happy","child","white","apple","brown","truth","fresh", "green","horse","hotel","house","paper","shape","shirt","study"] +var alreadyUsed3 = [] +var alreadyUsed4 = [] +var alreadyUsed5 = [] + var names = [] var names2 = [] var good = [] function start(items_) { items = items_ currentLevel = 0 - Core.shuffle(words3Letters) - Core.shuffle(words4Letters) - Core.shuffle(words5Letters) + alreadyUsed3 = [] + alreadyUsed4 = [] + alreadyUsed5 = [] initLevel() } function stop() { } function initLevel() { items.bar.level = currentLevel + 1 + Core.shuffle(words3Letters) + Core.shuffle(words4Letters) + Core.shuffle(words5Letters) init() } function init() { // set models for repaters if (currentLevel >= maxWordLevels) setRandomModelImage() else setRandomModelWord() items.gameFinished = false // set "initialIndex" to the position in the repeater for(var i = 0; i < names.length; i++) { if (items.repeater.itemAt(i).source != "") { items.repeater.itemAt(i).initialIndex = i good[i] = i } else { // set the initialIndex to -1 if there is no item inside (no source) items.repeater.itemAt(i).initialIndex = -1 good[i] = -1 } } // select the first item in the grid for(i = 0; i < items.repeater.count; i++) { if (items.repeater.itemAt(i).source != "") { items.selected = i break } } // set opacity for first item's "selection frame" items.repeater.itemAt(items.selected).selected.opacity = 1 } // levels with words as items function setRandomModelWord(){ // reset the arrays names = [] names2 = [] var numbers = [] var i var wordsUsed = [] if (currentLevel < numberLevelsWords) { wordsUsed = words3Letters // set the number of columns and rows from "levels" items.columns = 4 items.rows = 3 // show or hide the grid items.showGrid1.opacity = 1 // set the two boards in line or not items.background.inLine = true } else if (currentLevel < numberLevelsWords * 2) { wordsUsed = words4Letters // set the number of columns and rows from "levels" items.columns = 5 items.rows = 4 // show or hide the grid items.showGrid1.opacity = 1 // set the two boards in line or not items.background.inLine = false } else { wordsUsed = words5Letters // set the number of columns and rows from "levels" items.columns = 6 items.rows = 5 // show or hide the grid items.showGrid1.opacity = 0 // set the two boards in line or not items.background.inLine = false } for (i = 0; i < items.columns * items.rows; i++) { names[i] = "" names2[i] = "" numbers[i] = i; // generate columns*rows numbers } - var currentIndex = currentLevel % numberLevelsWords + // before: // var currentIndex = currentLevel % numberLevelsWords + + // get a random word: Math.floor(Math.random() * (max - min + 1)) + min; + var currentIndex = Math.floor(Math.random() * wordsUsed.length) + + // use vectors to store the words already used + if (wordsUsed[0].length == 3) { + while(alreadyUsed3.indexOf(wordsUsed[currentIndex]) >= 0) { + // there are no more words to use => clear the "alreadyUsed3" vector + if (alreadyUsed3.length == wordsUsed.length) + alreadyUsed3 = [] + // get another random index + currentIndex = Math.floor(Math.random() * wordsUsed.length) + } + // add the word in the "aredayUsed3" vector + alreadyUsed3 = alreadyUsed3.concat(wordsUsed[currentIndex]) + } else if (wordsUsed[0].length == 4) { + while(alreadyUsed4.indexOf(wordsUsed[currentIndex]) >= 0) { + // there are no more words to use => clear the "alreadyUsed4" vector + if (alreadyUsed4.length == wordsUsed.length) + alreadyUsed4 = [] + // get another random index + currentIndex = Math.floor(Math.random() * wordsUsed.length) + } + // add the word in the "aredayUsed4" vector + alreadyUsed4 = alreadyUsed4.concat(wordsUsed[currentIndex]) + } else if (wordsUsed[0].length == 5) { + while(alreadyUsed5.indexOf(wordsUsed[currentIndex]) >= 0) { + // there are no more words to use => clear the "alreadyUsed4" vector + if (alreadyUsed5.length == wordsUsed.length) + alreadyUsed5 = [] + // get another random index + currentIndex = Math.floor(Math.random() * wordsUsed.length) + } + // add the word in the "aredayUsed4" vector + alreadyUsed5 = alreadyUsed5.concat(wordsUsed[currentIndex]) + } else print("wordsUsed[0].length ",wordsUsed[0].length) + // place the word at a random position in the grid var randomRow = Math.floor(Math.random() * items.rows) var randomCol = Math.floor(Math.random() * items.columns) // check if the word goes out of the frame and replace to left it if needed if (items.columns - randomCol - wordsUsed[currentIndex].length < 0) randomCol = randomCol - Math.abs(items.columns - randomCol - wordsUsed[currentIndex].length) // set full path (url) to the letter image for (i = 0; i < wordsUsed[currentIndex].length; i++) { names[randomRow * items.columns + randomCol + i] = url + "letters/" + wordsUsed[currentIndex].charAt(i) + ".svg" names2[randomRow * items.columns + randomCol + i] = names[randomRow * items.columns + randomCol + i] } Core.shuffle(names) // set model for repeaters items.repeater.model = names.length items.modelRepeater.model = names2.length items.gridRepeater.model = names.length // set the source of items inside repeaters to names and names2 for (i = 0; i < names.length; i++) { items.repeater.itemAt(i).source = names[i] items.repeater.itemAt(i).opac = 0 items.modelRepeater.itemAt(i).source = names2[i] } } // levels with images as items function setRandomModelImage(){ // reset the arrays names = [] names2 = [] var numbers = [] var i // set the number of columns and rows from "levels" items.columns = levels[currentLevel - maxWordLevels].columns items.rows = levels[currentLevel - maxWordLevels].rows for (i = 0; i < items.columns * items.rows; i++) { names[i] = "" names2[i] = "" numbers[i] = i; // generate columns*rows numbers } // randomize the names Core.shuffle(allNames) //get "levels[currentLevel].noOfItems" random numbers Core.shuffle(numbers) for (i = 0; i < levels[currentLevel - maxWordLevels].noOfItems; i++) names[numbers[i]] = url + allNames[i] Core.shuffle(numbers) for (i = 0; i < levels[currentLevel - maxWordLevels].noOfItems; i++) names2[numbers[i]] = url + allNames[i] // set model for repeaters items.repeater.model = names.length items.modelRepeater.model = names2.length items.gridRepeater.model = names.length // set the source of items inside repeaters to names and names2 for (i = 0; i < names.length; i++) { items.repeater.itemAt(i).source = names[i] items.repeater.itemAt(i).opac = 0 items.modelRepeater.itemAt(i).source = names2[i] } // show or hide the grid items.showGrid1.opacity = levels[currentLevel - maxWordLevels].showGrid // set the two boards in line or not if (levels[currentLevel - maxWordLevels].inLine) items.background.inLine = true else items.background.inLine = false } // returns the next index needed for switching to another item function getNextIndex() { // get the initialIndex var index = items.repeater.itemAt(items.selected).initialIndex var min = 100 var min2 = 100 var biggerIndex = -1 var smallestIndex = -1 for (var i = 0; i < items.repeater.count; i++) { // get the imediat bigger index if (index < items.repeater.itemAt(i).initialIndex) { if (min > items.repeater.itemAt(i).initialIndex) { // update min and index min = items.repeater.itemAt(i).initialIndex biggerIndex = i } } // in case current index is the biggest, search the smalles index from start if (items.repeater.itemAt(i).initialIndex >= 0 && min2 > items.repeater.itemAt(i).initialIndex) { min2 = items.repeater.itemAt(i).initialIndex smallestIndex = i } } // if a bigger index was found, return it if (biggerIndex != -1) return biggerIndex // this is the biggest index; the next one is the smallest in the array return smallestIndex } //touchscreen gestures function gesture(deltax, deltay) { if (Math.abs(deltax) > 40 || Math.abs(deltay) > 40) if (deltax > 30 && Math.abs(deltay) < items.sensivity) move("right") else if (deltax < -30 && Math.abs(deltay) < items.sensivity) move("left") else if (Math.abs(deltax) < items.sensivity && deltay > 30) move("down") else if (Math.abs(deltax) < items.sensivity && deltay < 30) move("up") } //depeding on the command, make a move to left/right/up/down or select next item function move(command) { if (items.ok == true && items.gameFinished == false) { var item = items.repeater.itemAt(items.selected) if (command === "left") { if (items.selected % items.columns != 0) makeMove(item,-item.width,item.x,-1,"x") } else if (command === "right") { if ((items.selected+1) % items.columns != 0) makeMove(item,item.width,item.x,1,"x") } else if (command === "up") { if (items.selected > items.columns-1) makeMove(item,-item.height,item.y,-items.columns,"y") } else if (command === "down") { if (items.selected < (items.repeater.count-items.columns)) makeMove(item,item.height,item.y,items.columns,"y") } else if (command === "next") { items.repeater.itemAt(items.selected).selected.opacity = 0 items.selected = getNextIndex() items.repeater.itemAt(items.selected).selected.opacity = 1 } } } //set the environment for making a move and start the animation function makeMove(item,distance,startPoint,add,animationProperty) { if (items.repeater.itemAt(items.selected+add).source == "") { //setup the animation item.distance = distance item.indexChange = add item.startPoint = startPoint item.animationProperty = animationProperty //start the animation item.anim.start() //update the selected item items.selected += add; } } //check the answer; advance to next level if the answer is good function checkAnswer() { var count = 0 for (var i = 0; i < items.repeater.count; i++) { if (items.repeater.itemAt(i).source != items.modelRepeater.itemAt(i).source){ count = -1 } } if (count == 0) { items.bonus.good("flower") items.gameFinished = true } } function nextLevel() { if(numberOfLevel <= ++currentLevel ) { currentLevel = 0 } initLevel(); } function previousLevel() { if(--currentLevel < 0) { currentLevel = numberOfLevel - 1 } initLevel(); } diff --git a/src/activities/crane/resource/command.svg b/src/activities/crane/resource/command.svg index 3f65805d9..ede21ac20 100644 --- a/src/activities/crane/resource/command.svg +++ b/src/activities/crane/resource/command.svg @@ -1,54 +1,103 @@ + width="239.91795" + inkscape:version="0.91 r13725" + sodipodi:docname="command2.svg"> + + + + + image/svg+xml + d="m 608.64143,428.50508 153.4009,-0.10397 c 21.95827,-0.13355 38.26966,17.02975 38.49029,34.93454 0.22062,17.90481 -16.89196,33.53395 -38.85058,33.52764 l -152.24412,-0.0437 c -21.95866,-0.006 -39.8134,-14.17325 -40.03405,-32.07806 -0.22063,-17.90481 17.27934,-36.10283 39.23756,-36.2364 z" + style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#f4af53;fill-opacity:0.98670206;fill-rule:nonzero;stroke:#000000;stroke-width:2.52972555;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccssssc" /> + d="m 599.45814,438.10993 68.09574,-6.8e-4 c 9.85821,-0.10055 15.02947,12.37488 15.12851,25.85629 0.099,13.48142 -6.45939,23.16495 -16.31807,23.1813 l -69.3375,0.11503 c -9.8587,0.0164 -18.01112,-8.75638 -18.11018,-22.23782 -0.099,-13.48141 10.68331,-26.81354 20.5415,-26.91412 z" + style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#f2c68c;fill-opacity:0.82978725;fill-rule:nonzero;stroke:#000000;stroke-width:1.12252188;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccssssc" /> + d="m 601.74701,440.83199 59.54119,-0.12066 c 8.83505,-0.0794 15.57977,12.64696 15.66853,23.29924 0.0888,10.65229 -10.324,-2.58257 -19.15901,-2.50311 l -57.45942,2.43991 c -8.83505,0.0794 -16.2889,11.55187 -16.37768,0.89958 -0.0888,-10.65229 8.95136,-23.93549 17.78639,-24.01496 z" + style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:0.82978725;fill-rule:nonzero;stroke:none;stroke-width:3.29445267;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccsccsc" /> + d="m 702.48552,487.43449 c -9.85326,0.52965 -16.00637,-12.40497 -16.38367,-25.8132 -0.37728,-13.40826 7.41364,-22.99643 17.26689,-23.5261 l 69.0296,-0.0199 c 9.85325,-0.52966 17.03982,4.56251 17.41713,17.97076 0.37727,13.40823 -4.87482,30.79127 -14.72806,31.32094 -24.11858,1.04307 -46.64876,-0.0424 -70.82332,0.0675 z" + style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#f2c68c;fill-opacity:0.83137255;fill-rule:nonzero;stroke:#000000;stroke-width:1.14818621;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" + inkscape:connector-curvature="0" + sodipodi:nodetypes="csccsccc" /> + d="m 708.19664,440.68623 61.9026,0.0728 c 8.80904,-0.0794 14.44681,8.97079 14.53532,19.62307 0.0885,10.65229 -9.02532,-1.42167 -17.83434,-1.34222 l -58.55866,1.27902 c -8.80906,0.0794 -16.24098,11.55188 -16.3295,0.89959 -0.0885,-10.65229 7.47555,-20.45281 16.28458,-20.53229 z" + style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:0.82978725;fill-rule:nonzero;stroke:none;stroke-width:3.29445267;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccsccsc" />