Juicy Squash - Match-3 Game
import Felgo 4.0
import QtQuick 2.0
import "../game"
import "../ui"
SceneBase {
id: scene
width: 320
height: 480
property int score
property double juicyMeterPercentage
property int remainingTime
property alias overlayText: overlays
property alias gameSound: gameSoundItem
property bool vPlayMsgBox: false
onBackButtonPressed: backPressed()
EntityManager {
id: entityManager
entityContainer: gameArea
poolingEnabled: true
dynamicCreationEntityList: [
Qt.resolvedUrl("../game/Block.qml") + ""
]
}
BackgroundImage {
source: Qt.resolvedUrl("../../assets/img/JuicyBackground.png")
anchors.centerIn: scene.gameWindowAnchorItem
}
BackgroundMusic {
id: bgMusic
source: Qt.resolvedUrl("../../assets/snd/POL-coconut-land-short.wav")
}
Component.onCompleted: {
bgMusic.play()
}
GameSound {
id: gameSoundItem
}
JuicyMeter {
percentage: scene.juicyMeterPercentage
anchors.centerIn: gameArea
width: gameArea.width+36
height: gameArea.height
onJuicyMeterFull: {
overlays.showOverload()
whiteScreen.flash()
}
}
Image {
id: grid
source: Qt.resolvedUrl("../../assets/img/Grid.png")
width: 258
height: 378
anchors.horizontalCenter: scene.horizontalCenter
anchors.bottom: scene.bottom
anchors.bottomMargin: 92
}
Image {
id: filledGrid
source: Qt.resolvedUrl("../../assets/img/GridFull.png")
width: 258
height: 378
anchors.horizontalCenter: scene.horizontalCenter
anchors.bottom: scene.bottom
anchors.bottomMargin: 92
opacity: 1
Behavior on opacity {
PropertyAnimation { duration: 500 }
}
}
GameArea {
id: gameArea
anchors.horizontalCenter: scene.horizontalCenter
anchors.verticalCenter: grid.verticalCenter
blockSize: 30
onGameOver: { currentGameEnded() }
onInitFinished: {
whiteScreen.stopLoading()
scene.score = 0
scene.juicyMeterPercentage = 0
scene.remainingTime = 120
filledGrid.opacity = 0
gameTimer.start()
}
opacity: filledGrid.opacity == 1 ? 0 : 1
}
Image {
id: juicyLogo
source: Qt.resolvedUrl("../../assets/img/JuicySquashLogo.png")
width: 119
height: 59
anchors.horizontalCenter: scene.horizontalCenter
anchors.bottom: scene.bottom
anchors.bottomMargin: 35
}
Text {
font.family: gameFont.name
font.pixelSize: 12
color: "red"
text: scene.score
anchors.horizontalCenter: parent.horizontalCenter
y: 446
}
Image {
width: 80
height: 46
source: Qt.resolvedUrl("../../assets/img/TimeLeft.png")
anchors.right: scene.gameWindowAnchorItem.right
anchors.top: juicyLogo.top
anchors.topMargin: juicyLogo.height / 2
Text {
font.family: gameFont.name
font.pixelSize: 12
color: "red"
text: remainingTime + " s"
y: 25
x: 15
width: 80 - 15
horizontalAlignment: Text.AlignHCenter
}
enabled: opacity == 1
visible: opacity > 0
opacity: filledGrid.opacity > 0.5 ? 0 : 1
Behavior on opacity {
PropertyAnimation { duration: 200 }
}
}
Timer {
id: gameTimer
repeat: true
interval: 1000
onTriggered: {
if(scene.remainingTime > 0)
scene.remainingTime--
else if(!gameArea.fieldLocked) {
currentGameEnded()
}
}
}
TitleWindow {
id: titleWindow
y: 25
opacity: 1
anchors.horizontalCenter: scene.horizontalCenter
onStartClicked: scene.startGame()
onCreditsClicked: {
titleWindow.hide(); creditsWindow.show()
}
onVplayClicked: {
vPlayMsgBox = true
NativeUtils.displayMessageBox(qsTr("Felgo"),
qsTr("This game is built with Felgo. The source code is available in the free Felgo SDK - so you can build your own match-3 game in minutes! Visit Felgo.net now?"), 2)
}
}
GameOverWindow {
id: gameOverWindow
y: 90
opacity: 0
anchors.horizontalCenter: scene.horizontalCenter
onNewGameClicked: scene.startGame()
onBackClicked: { openTitleWindow() }
}
CreditsWindow {
id: creditsWindow
y: 90
opacity: 0
anchors.horizontalCenter: scene.horizontalCenter
onBackClicked: { openTitleWindow() }
onVplayClicked: {
NativeUtils.openUrl("https://felgo.com/doc/felgo-demos-match-3-example/")
}
}
Image {
width: 52
height: 45
source: Qt.resolvedUrl("../../assets/img/HomeButton.png")
MouseArea {
anchors.fill: parent
onClicked: backButtonPressed()
}
x: 5
y: 432
visible: opacity > 0
enabled: opacity == 1
opacity: titleWindow.opacity > 0.5 ? 0 : 1
Behavior on opacity {
PropertyAnimation { duration: 200 }
}
}
Rectangle {
id: whiteScreen
anchors.fill: gameArea
anchors.centerIn: gameArea
color: "white"
opacity: 0
visible: opacity > 0
enabled: opacity > 0
SequentialAnimation {
id: flashAnimation
NumberAnimation {
target: whiteScreen
property: "opacity"
to: 1
duration: 300
}
NumberAnimation {
target: whiteScreen
property: "opacity"
from: 1
to: 0
duration: 700
}
}
SequentialAnimation {
id: loadingAnimation
loops: Animation.Infinite
NumberAnimation {
target: whiteScreen
property: "opacity"
to: 1
duration: 400
}
NumberAnimation {
target: whiteScreen
property: "opacity"
from: 1
to: 0.8
duration: 1000
}
}
Text {
id: loadingText
font.family: gameFont.name
font.pixelSize: 12
color: "red"
text: "preparing fruits"
anchors.centerIn: parent
opacity: 0
Behavior on opacity {
PropertyAnimation { duration: 400 }
}
}
function flash() {
loadingText.opacity = 0
loadingAnimation.stop()
flashAnimation.stop()
flashAnimation.start()
}
function startLoading() {
loadingAnimation.start()
loadingText.opacity = 1
}
function stopLoading() {
flash()
}
}
Overlays {
id: overlays
y: 190
onOverloadTextDisappeared: {
scene.juicyMeterPercentage = 0
gameTimer.stop()
gameArea.removeAllBlocks()
whiteScreen.flash()
scene.remainingTime += 60
gameTimer.start()
}
}
Connections {
target: NativeUtils
function onMessageBoxFinished(accepted) {
if(!accepted) {
vPlayMsgBox = false
if(!titleWindow.visible && !gameTimer.running)
gameTimer.start()
return
}
if(vPlayMsgBox) {
vPlayMsgBox = false
NativeUtils.openUrl("https://felgo.com/doc/felgo-demos-match-3-example/")
}
else if(!titleWindow.visible) {
if(scene.score > 0)
currentGameEnded()
else
openTitleWindow()
}
else {
Qt.quit()
}
}
}
Timer {
id: initTimer
interval: 400
onTriggered: {
gameArea.initializeField()
}
}
function openTitleWindow() {
filledGrid.opacity = 1
scene.juicyMeterPercentage = 0
gameTimer.stop()
creditsWindow.hide()
gameOverWindow.hide()
titleWindow.show()
}
function currentGameEnded() {
gameArea.gameEnded = true
gameOverWindow.show()
gameTimer.stop()
}
function startGame() {
titleWindow.hide()
gameOverWindow.hide()
creditsWindow.hide()
whiteScreen.startLoading()
initTimer.start()
}
function backPressed() {
if(titleWindow.visible) {
NativeUtils.displayMessageBox("Really quit the game?", "", 2)
}
else if(creditsWindow.visible) {
openTitleWindow()
}
else if(gameOverWindow.visible) {
openTitleWindow()
}
else {
if(gameTimer.running)
gameTimer.stop()
NativeUtils.displayMessageBox("Abort current game?", "", 2)