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