C

Qt Quick Ultralite swipe_game Demo

/****************************************************************************** ** ** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Quick Ultralite module. ** ** $QT_BEGIN_LICENSE:COMM$ ** ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see http://www.qt.io/terms-conditions. For further ** information use the contact form at http://www.qt.io/contact-us. ** ** $QT_END_LICENSE$ ** ******************************************************************************/
import QtQuick 2.0 import StyleModule 1.0 import SwipeModule 1.0 /* This view displays information about the current game status and controls the flow of the game. */ BaseView { id: root signal gameOver() signal gameAborted() // start/stop the timers which control the flow if the view is (not) visible onVisibleChanged: { if (visible) { restartTimer.restart() } else { responseTimer.stop() } } MouseArea { id: swipeArea anchors.fill: parent property int startX: 0 property int startY: 0 property bool swipeFinished: false onPressed: { startX = mouseX startY = mouseY swipeFinished = false } function guessedGreater(swipe : Swipe.Direction) : bool { return (swipe == Swipe.Direction.Right) || (swipe == Swipe.Direction.Up) } onPositionChanged: { if (swipeFinished) { return } var swipe = Swipe.detectDirection(mouseX, mouseY, startX, startY, Style.swipeThreshold) if ((Globals.isNumberMode() && Swipe.isHorizontal(swipe)) || (!Globals.isNumberMode() && Swipe.isVertical(swipe))) { swipeFinished = true Globals.checkAnswer(guessedGreater(swipe)) internal.checkStatus() } } } Row { id: failRow anchors { top: parent.top topMargin: Style.marginBig horizontalCenter: parent.horizontalCenter } spacing: Style.lineSize Repeater { model: Globals.tries delegate: Rectangle { height: Style.buttonHeight width: height radius: height * 0.5 color: Style.colorLines Rectangle { anchors { fill: parent margins: Style.lineSize } radius: height * 0.5 color: index < Globals.fails ? Style.colorWarning : Style.colorButtonBackground } } } } Text { id: currentValue anchors.centerIn: parent font: Globals.isNumberMode() ? Style.textFontBig : Style.textFontDefault color: Style.colorText text: Globals.isNumberMode() ? Globals.gameCurrentNumber : Globals.gameCurrentCountry } Text { id: score anchors { bottom: stopButton.top bottomMargin: Style.marginDefault horizontalCenter: parent.horizontalCenter } font: Style.textFontDefault color: Style.colorText text: "Score: " + Globals.score } Button { id: stopButton anchors { bottom: parent.bottom bottomMargin: Style.marginDefault horizontalCenter: parent.horizontalCenter } font: Style.textFontDefault text: "Stop" onClicked: { root.gameAborted() } } QtObject { id: internal function checkStatus() { if (Globals.fails >= Globals.tries) { root.gameOver() } else { Globals.requestNewValue() restartTimer.restart() } } } Timer { id: responseTimer property int steps: 12 // aim for 12 steps to visualize the timeout indicators property int currentStep: 0 property int angle: currentStep * 360/steps interval: Globals.time / steps repeat: true onTriggered: { currentStep += 1 if (currentStep >= steps) { stop() Globals.addFail() internal.checkStatus() } } } // restarting a timer while its onTriggered block is still active doesn't work. // It even crashes when the timer is set to repeat and restart is called while onTriggered is still active. // Use a second timer to restart the responseTimer with a small delay Timer { id: restartTimer interval: 10 onTriggered: { responseTimer.currentStep = 0 responseTimer.restart() } } // the timeoutIndicator displays a line which grows circular around the frame // to indicate how much time is left to respond to the current game value. Item { id: timeoutIndicator anchors.fill: parent Item { id: rightArcClipper anchors { left: parent.horizontalCenter right: parent.right top: parent.top bottom: parent.bottom } clip: true visible: responseTimer.running Image { id: rightArc anchors { verticalCenter: parent.verticalCenter horizontalCenter: parent.left } width: timeoutIndicator.width height: width source: "timebar.svg" rotation: Math.min(180, responseTimer.angle) } } Item { id: leftArcClipper anchors { left: parent.left right: parent.horizontalCenter top: parent.top bottom: parent.bottom } clip: true visible: responseTimer.running Image { id: leftArc width: timeoutIndicator.width height: width source: "timebar.svg" rotation: Math.max(180, responseTimer.angle) } } } }