Warning, /education/gcompris/src/activities/maze/Maze.qml is written in an unsupported language. File is not indexed.

0001 /* GCompris - maze.qml
0002 *
0003 * SPDX-FileCopyrightText: 2014 Stephane Mankowski <stephane@mankowski.fr>
0004 *
0005 * Authors:
0006 *   Bastiaan Verhoef <b.f.verhoef@student.utwente.nl> (GTK+ version)
0007 *   Stephane Mankowski <stephane@mankowski.fr> (Qt Quick port)
0008 *
0009 *   SPDX-License-Identifier: GPL-3.0-or-later
0010 */
0011 import QtQuick 2.12
0012 import GCompris 1.0
0013 
0014 import "../../core"
0015 import "maze.js" as Activity
0016 
0017 ActivityBase {
0018     id: activity
0019     property bool relativeMode: false
0020     property bool invisibleMode: false
0021 
0022     onStart: focus = true
0023     onStop: {
0024 
0025     }
0026 
0027     Keys.onPressed: Activity.processPressedKey(event)
0028 
0029     pageComponent: Image {
0030         id: background
0031         source: Activity.url + "maze_bg.svg"
0032         sourceSize.width: parent.width
0033         anchors.fill: parent
0034         signal start
0035         signal stop
0036 
0037         Component.onCompleted: {
0038             activity.start.connect(start)
0039             activity.stop.connect(stop)
0040         }
0041 
0042         // Add here the QML items you need to access in javascript
0043         QtObject {
0044             id: items
0045             property Item main: activity.main
0046             property alias background: background
0047             property int currentLevel: activity.currentLevel
0048             property alias bonus: bonus
0049             property alias mazeRows: maze.rows
0050             property alias mazeColumns: maze.columns
0051             property alias mazeRepeater: mazeRepeater.model
0052             property GCSfx audioEffects: activity.audioEffects
0053             property alias message: message
0054             property int playerx: 0
0055             property int playery: 0
0056             property int playerr: 270
0057             property int doory: 0
0058             property int cellSize: Math.min((parent.height - bar.height * 1.2 - 40) / mazeRows,
0059                                             (parent.width - 40) / mazeColumns)
0060             property int wallSize: Math.max(2, cellSize / 10)
0061             property bool wallVisible: true
0062             property bool fastMode: false
0063         }
0064 
0065         onStart: {
0066             Activity.start(items, relativeMode, invisibleMode)
0067         }
0068         onStop: {
0069             timeAutoMove.stop()
0070             Activity.stop()
0071         }
0072 
0073         Rectangle {
0074             color: "#E3DEDB"
0075             anchors.fill: maze
0076         }
0077 
0078         Grid {
0079             id: maze
0080             anchors.top: parent.top
0081             anchors.topMargin: 40
0082             anchors.horizontalCenter: parent.horizontalCenter
0083             columns: 1
0084             rows: 1
0085             spacing: 0
0086 
0087             Repeater {
0088                 id: mazeRepeater
0089                 Item {
0090                     width: items.cellSize
0091                     height: items.cellSize
0092                     Rectangle {
0093                         id: north
0094                         width: items.cellSize + items.wallSize
0095                         height: items.wallSize
0096                         radius: height / 2
0097                         anchors.top: parent.top
0098                         anchors.left: parent.left
0099                         anchors.topMargin: -items.wallSize / 2
0100                         anchors.leftMargin: -items.wallSize / 2
0101                         color: "#B38B56"
0102                         visible: modelData & 1 ? items.wallVisible : false
0103                         z: 1
0104                     }
0105 
0106                     Rectangle {
0107                         id: south
0108                         width: items.cellSize + items.wallSize
0109                         height: items.wallSize
0110                         radius: height / 2
0111                         anchors.bottom: parent.bottom
0112                         anchors.left: parent.left
0113                         anchors.bottomMargin: -items.wallSize / 2
0114                         anchors.leftMargin: -items.wallSize / 2
0115                         color: "#B38B56"
0116                         visible: modelData & 4 ? items.wallVisible : false
0117                         z: 1
0118                     }
0119 
0120                     Rectangle {
0121                         id: east
0122                         width: items.wallSize
0123                         height: items.cellSize + items.wallSize
0124                         radius: width / 2
0125                         anchors.bottom: parent.bottom
0126                         anchors.right: parent.right
0127                         anchors.bottomMargin: -items.wallSize / 2
0128                         anchors.rightMargin: -items.wallSize / 2
0129                         color: "#B38B56"
0130                         visible: modelData & 8 ? items.wallVisible : false
0131                         z: 1
0132                     }
0133 
0134                     Rectangle {
0135                         id: west
0136                         width: items.wallSize
0137                         height: items.cellSize + items.wallSize
0138                         radius: width / 2
0139                         anchors.bottom: parent.bottom
0140                         anchors.left: parent.left
0141                         anchors.bottomMargin: -items.wallSize / 2
0142                         anchors.leftMargin: -items.wallSize / 2
0143                         color: "#B38B56"
0144                         visible: modelData & 2 ? items.wallVisible : false
0145                         z: 1
0146                     }
0147                 }
0148             }
0149         }
0150 
0151         MultiPointTouchArea {
0152             anchors.fill: parent
0153             touchPoints: [ TouchPoint { id: point1 } ]
0154             property real startX
0155             property real startY
0156             // Workaround to avoid having 2 times the onReleased event
0157             property bool started
0158 
0159             onPressed: {
0160                 startX = point1.x
0161                 startY = point1.y
0162                 started = true
0163             }
0164 
0165             onReleased: {
0166                 if(!started)
0167                     return false
0168                 var moveX = point1.x - startX
0169                 var moveY = point1.y - startY
0170                 // Find the direction with the most move
0171                 if(Math.abs(moveX) * ApplicationInfo.ratio > 10 &&
0172                    Math.abs(moveX) > Math.abs(moveY)) {
0173                     if(moveX > 10 * ApplicationInfo.ratio)
0174                         Activity.clickRight()
0175                     else if(moveX < -10 * ApplicationInfo.ratio)
0176                         Activity.clickLeft()
0177                 } else if(Math.abs(moveY) * ApplicationInfo.ratio > 10 &&
0178                           Math.abs(moveX) < Math.abs(moveY)) {
0179                     if(moveY > 10 * ApplicationInfo.ratio)
0180                         Activity.clickDown()
0181                     else if(moveY < -10 * ApplicationInfo.ratio)
0182                         Activity.clickUp()
0183                 } else {
0184                     // No move, just a tap or mouse click
0185                     if(point1.x > player.x + player.width)
0186                         Activity.clickRight()
0187                     else if(point1.x < player.x)
0188                         Activity.clickLeft()
0189                     else if(point1.y < player.y)
0190                         Activity.clickUp()
0191                     else if(point1.y > player.y + player.height)
0192                         Activity.clickDown()
0193 
0194                 }
0195 
0196                 started = false
0197             }
0198         }
0199 
0200         // Show an hint to show that can move by swiping anywhere
0201         Image {
0202             anchors {
0203                 right: parent.right
0204                 bottom: parent.bottom
0205                 margins: 12
0206             }
0207             source: "qrc:/gcompris/src/core/resource/arrows_move.svg"
0208             sourceSize.width: 140
0209             opacity: bar.level == 1 && ApplicationInfo.isMobile ? 1 : 0
0210         }
0211 
0212         Image {
0213             id: player
0214             source: Activity.url + "tux_top_south.svg"
0215             sourceSize.width: items.cellSize * 0.8
0216             x: maze.x + items.cellSize * 0.05 + items.wallSize / 2 + items.playerx * items.cellSize
0217             y: maze.y + items.cellSize * 0.20 + items.wallSize / 2 + items.playery * items.cellSize
0218             z: 2
0219             rotation: items.playerr
0220             Timer {
0221                 id: timeAutoMove
0222                 interval: 10
0223                 running: false
0224                 repeat: false
0225                 onTriggered: Activity.autoMove()
0226             }
0227 
0228             Behavior on x {
0229                 SequentialAnimation {
0230                     NumberAnimation {
0231                         duration: 100
0232                     }
0233                     ScriptAction {
0234                         script: timeAutoMove.running = true
0235                     }
0236                 }
0237             }
0238             Behavior on y {
0239                 SequentialAnimation {
0240                     NumberAnimation {
0241                         duration: 100
0242                     }
0243                     ScriptAction {
0244                         script: timeAutoMove.running = true
0245                     }
0246                 }
0247             }
0248             Behavior on rotation {
0249                 PropertyAnimation {
0250                     duration: 100
0251                 }
0252             }
0253 
0254             Image {
0255                 id: shoes
0256                 source: Activity.url + "tux_shoes_top_south.svg"
0257                 sourceSize.width: items.cellSize * 0.8
0258                 anchors.centerIn: parent
0259                 visible: items.fastMode
0260             }
0261         }
0262 
0263         Image {
0264             id: door
0265             source: Activity.url + "door.svg"
0266             width: items.cellSize * 0.6
0267             height: items.cellSize * 0.8
0268             y: maze.y + items.cellSize * 0.05 + items.wallSize / 2 + items.doory * items.cellSize
0269             z: 1
0270             anchors.right: maze.right
0271             anchors.rightMargin: items.cellSize * 0.15 + items.wallSize / 2
0272         }
0273 
0274         BarButton {
0275             id: fastmode
0276             source: Activity.url + "fast-mode-button.svg"
0277             sourceSize.width: 66 * bar.barZoom
0278             visible: !message.visible
0279             x: 10 * ApplicationInfo.ratio
0280             y: 10 * ApplicationInfo.ratio
0281             onClicked: items.fastMode = !items.fastMode
0282         }
0283 
0284         BarButton {
0285             id: switchMaze
0286             source: Activity.url + "maze-2d-bubble.svg"
0287             anchors {
0288                 right: parent.right
0289                 top: parent.top
0290                 margins: 10
0291             }
0292             sourceSize.width: 66 * bar.barZoom
0293             visible: invisibleMode
0294             onClicked: {
0295                 items.wallVisible = !items.wallVisible
0296                 message.visible = items.wallVisible
0297             }
0298         }
0299 
0300         GCText {
0301             id: message
0302             anchors {
0303                 left: parent.left
0304                 right: switchMaze.left
0305                 top: parent.top
0306                 margins: 10
0307             }
0308             width: background.width - x - 20
0309             fontSize: regularSize
0310             horizontalAlignment: Text.AlignHCenter
0311             verticalAlignment: Text.AlignVCenter
0312             visible: false
0313             wrapMode: Text.Wrap
0314             text: qsTr("Look at your position, then switch back to invisible mode to continue your moves")
0315         }
0316 
0317         DialogHelp {
0318             id: dialogHelp
0319             onClose: home()
0320         }
0321 
0322         Bar {
0323             id: bar
0324             level: items.currentLevel + 1
0325             content: BarEnumContent {
0326                 value: help | home | level
0327             }
0328             onHelpClicked: displayDialog(dialogHelp)
0329             onPreviousLevelClicked: Activity.previousLevel()
0330             onNextLevelClicked: Activity.nextLevel()
0331             onHomeClicked: activity.home()
0332         }
0333 
0334         Bonus {
0335             id: bonus
0336             Component.onCompleted: win.connect(Activity.nextLevel)
0337         }
0338     }
0339 }