1/* GCompris - FollowLine.qml 2 * 3 * SPDX-FileCopyrightText: 2014 Bruno Coudoin <bruno.coudoin@gcompris.net> 4 * 5 * Authors: 6 * Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version) 7 * Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port) 8 * Timothée Giet <animtim@gmail.com> (Gameplay refactoring and improvements) 9 * 10 * SPDX-License-Identifier: GPL-3.0-or-later 11 */ 12import QtQuick 2.9 13import GCompris 1.0 14 15import "../../core" 16import "followline.js" as Activity 17 18ActivityBase { 19 id: activity 20 21 onStart: focus = true 22 onStop: {} 23 24 pageComponent: Image { 25 id: background 26 source: Activity.url + "background.svg" 27 fillMode: Image.PreserveAspectCrop 28 sourceSize.width: width 29 sourceSize.height: height 30 31 signal start 32 signal stop 33 34 Component.onCompleted: { 35 activity.start.connect(start) 36 activity.stop.connect(stop) 37 } 38 39 // Add here the QML items you need to access in javascript 40 QtObject { 41 id: items 42 property alias background: background 43 property GCSfx audioEffects: activity.audioEffects 44 property alias fireman: fireman 45 property alias lineArea: lineArea 46 property alias fire: fire 47 property alias lineBrokenTimer: lineBrokenTimer 48 property alias bar: bar 49 property alias bonus: bonus 50 property int currentLock: 0 51 property int lastLock: 0 52 property bool verticalLayout: lineArea.height > lineArea.width 53 } 54 55 onHeightChanged: Activity.initLevel() 56 onWidthChanged: Activity.initLevel() 57 58 onStart: { Activity.start(items) } 59 onStop: { Activity.stop() } 60 61 Image { 62 id: fireman 63 source: Activity.url + "fireman.svg" 64 sourceSize.width: 182 * ApplicationInfo.ratio 65 anchors { 66 left: parent.left 67 verticalCenter: parent.verticalCenter 68 verticalCenterOffset: - height / 10 69 } 70 } 71 72 Image { 73 id: fire 74 source: Activity.url + "fire.svg" 75 sourceSize.width: 90 * ApplicationInfo.ratio 76 anchors { 77 right: parent.right 78 bottom: bar.top 79 } 80 81 Image { 82 id: fireflame 83 source: Activity.url + "fire_flame.svg" 84 sourceSize.width: 90 * ApplicationInfo.ratio 85 anchors { 86 fill: parent 87 } 88 Behavior on opacity { NumberAnimation { duration: 2000 } } 89 onOpacityChanged: if(opacity == 0) Activity.nextLevel() 90 } 91 } 92 93 Image { 94 id: water 95 source: Activity.url + "water_spot.svg" 96 sourceSize.width: 148 * ApplicationInfo.ratio 97 z: 200 98 opacity: 0 99 anchors { 100 right: parent.right 101 bottom: fire.top 102 bottomMargin: - fire.height / 2 103 } 104 Behavior on opacity { NumberAnimation { duration: 500 } } 105 } 106 107 DialogHelp { 108 id: dialogHelp 109 onClose: home() 110 } 111 112 function win() { 113 fireflame.opacity = 0 114 water.opacity = 1 115 } 116 117 Bar { 118 id: bar 119 content: BarEnumContent { value: help | home | level } 120 onHelpClicked: displayDialog(dialogHelp) 121 onPreviousLevelClicked: Activity.previousLevel() 122 onNextLevelClicked: Activity.nextLevel() 123 onHomeClicked: activity.home() 124 onLevelChanged: { 125 fireflame.opacity = 1 126 water.opacity = 0 127 } 128 } 129 130 Bonus { 131 id: bonus 132 Component.onCompleted: win.connect(Activity.nextLevel) 133 } 134 135 MouseArea { 136 anchors.fill: parent 137 enabled: !ApplicationInfo.isMobile 138 hoverEnabled: true 139 onPositionChanged: items.currentLock > 0 && water.opacity === 0 ? 140 lineBrokenTimer.start() : false 141 } 142 143 Item { 144 id: lineArea 145 anchors.top: fireman.top 146 anchors.left: fireman.right 147 anchors.bottom: fire.top 148 anchors.right: fire.left 149 150 MultiPointTouchArea { 151 anchors.fill: parent 152 maximumTouchPoints: 1 153 enabled: ApplicationInfo.isMobile && water.opacity === 0 154 z: 1000 155 onTouchUpdated: { 156 for(var i in touchPoints) { 157 var touch = touchPoints[i] 158 var part = lineArea.childAt(touch.x, touch.y) 159 if(part && part.isPart) { 160 if(items.currentLock <= part.index && !Activity.movedOut) { 161 items.currentLock = part.index 162 if(items.currentLock >= items.lastLock) { 163 background.win() 164 activity.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/water.wav") 165 } else { 166 Activity.playAudioFx() 167 } 168 } else if(items.currentLock >= part.index && Activity.movedOut) { 169 lineBrokenTimer.stop(); 170 Activity.movedOut = false; 171 } 172 } else { 173 lineBrokenTimer.start() 174 } 175 } 176 } 177 onReleased: if(water.opacity === 0) lineBrokenTimer.start() 178 } 179 } 180 181 Timer { 182 id: lineBrokenTimer 183 interval: 20 184 onTriggered: { 185 if(items.currentLock > 0 && water.opacity === 0) { 186 Activity.cursorMovedOut(); 187 restart(); 188 } 189 } 190 } 191 } 192 193} 194