/**************************************************************************** ** ** Copyright (C) 2011 Nokia Institute of Technology. ** All rights reserved. ** Contact: Manager (renato.chencarek@openbossa.org) ** ** This file is part of the Incredible Circus project. ** ** GNU Lesser General Public License Usage ** ** This file may be used under the terms of the GNU Lesser General Public ** License version 2.1 as published by the Free Software Foundation and ** appearing in the file LICENSE.LGPL included in the packaging of this ** file. Please review the following information to ensure the GNU Lesser ** General Public License version 2.1 requirements will be met: ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ****************************************************************************/ import QtQuick 1.1 import Circus 1.0 import "widgets" import "Core.js" as Core Item { id: root anchors.fill: parent property bool applicationActive: Qt.application.active Item { id: switcher anchors.fill: parent Image { anchors.fill: parent fillMode: Image.Tile source: "image://cache/common/bg.png" } Row { id: row width: parent.width height: parent.height property bool animated: true Behavior on x { enabled: row.animated NumberAnimation { duration: 700; easing.type: Easing.InOutQuart; } } MainScreen { width: parent.width height: parent.height onPlayClicked: row.x = -root.width; } WorldScreen { id: worldSelector width: parent.width height: parent.height onBackClicked: row.x = 0; onNextClicked: { row.state = "onLevels"; row.x = -root.width * 2; levelScreen.tryToUnlockExtraLevels(); } onAchievementsClicked: { achievementsScreen.restartIndex(); row.state = "onAchievements"; row.x = -root.width * 2; } Connections { target: levelScreen onBackClicked: worldSelector.updateStars() } } LevelScreen { id: levelScreen width: parent.width height: parent.height onBackClicked: row.x = -root.width; onSelected: Core.selectLevel(model); } AchievementsScreen { id: achievementsScreen width: parent.width height: parent.height onBackClicked: row.x = -root.width; } states: [ State { name: "onLevels" PropertyChanges { target: levelScreen; visible: true; } PropertyChanges { target: achievementsScreen; visible: false; } }, State { name: "onAchievements" PropertyChanges { target: achievementsScreen; visible: true; } PropertyChanges { target: levelScreen; visible: false; } } ] Connections { id: rootStateConnection target: root onStateChanged: { if (root.state == "" && row.state == "onLevels") levelScreen.tryToUnlockExtraLevels(); } } } } IntroLoader { id: introLoader anchors.fill: parent onPresented: { stage.load(); root.state = "playing"; } } GameEngine { id: stage property double lastAchievementUnlockTime: 0 property double nextPopupTime: 0 property bool reloadingLevel: false anchors.fill: parent opacity: 0.0 smooth: true visible: false levelModel: manager.currentLevel onWon: Core.win(); onLoaded: Core.start(); onGameOver: Core.gameOver(); onSoundRequest: { sound.play(name); } onSoundLoopRequest: { if (stop) sound.stopLoop(name); else sound.playLoop(name); } onPauseSoundRequest: { sound.pause(name); } onResumeSoundRequest: { sound.resume(name); } onUnlockAchievement: { if (achievementManager) achievementManager.unlockAchievement(name) } Row { spacing: 4 anchors.top: parent.top anchors.left: parent.left anchors.margins: 10 LifeIndicator { active: (stage.playerLife > 0) } LifeIndicator { active: (stage.playerLife > 1) } LifeIndicator { active: (stage.playerLife > 2) } } ImageButton { source: "image://cache/common/pause.png" anchors.top: parent.top anchors.right: parent.right onClicked: { stage.pause(); root.state = "paused"; } enabled: root.state != "congrats" && !stage.reloadingLevel } HelpLayer { id: helpLayer anchors.fill: parent onOkClicked: { stage.start(); helpLayer.state = ""; } } Connections { target: achievementNotifier onPublish: stage.publishAchievement(name, description, icon) } // we are not using the description argument right now function publishAchievement(name, description, icon) { var popupTime = 2000; var now = (new Date()).getTime() var elapsedTime = now - lastAchievementUnlockTime if (elapsedTime > popupTime) nextPopupTime = 0 else nextPopupTime += popupTime var component = Qt.createComponent("AchievementPopup.qml"); var achievementPopup = component.createObject(root) achievementPopup.popupAchievement(name, icon, nextPopupTime) lastAchievementUnlockTime = now } Rectangle { id: fadeLayer color: "white" opacity: 0.0 visible: false anchors.fill: parent MouseArea { anchors.fill: parent } } SequentialAnimation { id: reloadAnimation function reload() { stage.load(); if (!applicationActive) { stage.pause() root.state = "paused"; } } ScriptAction { script: stage.reloadingLevel = true } PropertyAction { target: fadeLayer; property: "visible"; value: true; } PauseAnimation { duration: 400; } NumberAnimation { target: fadeLayer; property: "opacity"; from: 0.0; to: 1.0; duration: 300; } ScriptAction { script: reloadAnimation.reload(); } NumberAnimation { target: fadeLayer; property: "opacity"; from: 1.0; to: 0.0; duration: 100; } PropertyAction { target: fadeLayer; property: "visible"; value: false; } ScriptAction { script: stage.reloadingLevel = false } } } onApplicationActiveChanged: { if (pauseGameWhenInactive && !applicationActive && root.state == "playing") { stage.pause(); root.state = "paused"; } } PauseScreen { id: pauseMenu anchors.fill: parent opacity: 0.0 visible: false onMenuClicked: { if (achievementDatabase != undefined) achievementDatabase.flush(); root.state = "" } onPlayClicked: { root.state = "playing"; stage.start(); } onRestartClicked: { root.state = "playing"; stage.load(); } } RemainingStars { id: remainingStars anchors.fill: parent onOkClicked: { remainingStars.state = ""; } } YouWonScreen { id: winMenu anchors.fill: parent opacity: 0.0 visible: false onNextClicked: { if (manager.hasExtraLevels(manager.currentWorld.index) && manager.isExtraLevel(manager.currentWorld.index, winMenu.nextLevel.index) && !manager.isExtraLevelsUnlocked(manager.currentWorld.index)) { root.state = ""; remainingStars.updateValue(); if (remainingStars.value > 0) { remainingStars.state = "opened"; return; } } if (achievementDatabase != undefined) achievementDatabase.flush(); Core.nextLevel(); } onMenuClicked: { // unlock pending level if it is not an extra level if (winMenu.nextLevel && !manager.isExtraLevel(manager.currentWorld.index, winMenu.nextLevel.index)) winMenu.nextLevel.unlock(); if (achievementDatabase != undefined) achievementDatabase.flush(); root.state = "" } onRestartClicked: { // unlock pending level if (winMenu.nextLevel) winMenu.nextLevel.unlock(); stage.load(); root.state = "playing" } } MouseArea { id: blocker enabled: false anchors.fill: parent } onStateChanged: { if (state == "playing") { sound.stopLoop("menu_sound"); if (sound.state("bg_sound") == Sound.STOPPED_STATE) sound.playLoop("bg_sound"); } else { sound.stopLoop("bg_sound"); if (sound.state("menu_sound") == Sound.STOPPED_STATE) sound.playLoop("menu_sound"); } } states: [ State { name: "playing" PropertyChanges { target: switcher; visible: false; } PropertyChanges { target: stage; opacity: 1.0; visible: true; } }, State { name: "paused" extend: "playing" PropertyChanges { target: pauseMenu; opacity: 1.0; visible: true; } }, State { name: "congrats" extend: "playing" PropertyChanges { target: winMenu; opacity: 1.0; visible: true; } } ] transitions: [ // http://bugreports.qt.nokia.com/browse/QTBUG-13927 // // XXX: due the above QML bug, the top-level animation inside a transition // does not change its running state when animating. So, we cannot use the // running property to enabled/disable the blocker overlay (ugly workaround) Transition { from: ""; to: "playing"; SequentialAnimation { PropertyAction { target: blocker; property: "enabled"; value: true; } NumberAnimation { target: stage; properties: "opacity"; duration: 500; } PropertyAction { target: switcher; properties: "visible"; } PropertyAction { target: blocker; property: "enabled"; value: false; } } }, Transition { from: "playing"; to: ""; SequentialAnimation { PropertyAction { target: blocker; property: "enabled"; value: true; } PropertyAction { target: switcher; properties: "visible"; } NumberAnimation { target: stage; properties: "opacity"; duration: 500; } PropertyAction { target: blocker; property: "enabled"; value: false; } } }, Transition { from: "playing"; to: "paused"; SequentialAnimation { PropertyAction { target: blocker; property: "enabled"; value: true; } PropertyAction { target: pauseMenu; properties: "visible"; } NumberAnimation { target: pauseMenu; properties: "opacity"; duration: 400; } PropertyAction { target: blocker; property: "enabled"; value: false; } } }, Transition { from: "paused"; to: "playing"; SequentialAnimation { PropertyAction { target: blocker; property: "enabled"; value: true; } NumberAnimation { target: pauseMenu; properties: "opacity"; duration: 400; } PropertyAction { target: pauseMenu; properties: "visible"; } PropertyAction { target: blocker; property: "enabled"; value: false; } } }, Transition { from: "playing"; to: "congrats"; SequentialAnimation { PropertyAction { target: blocker; property: "enabled"; value: true; } PauseAnimation { duration: 2000; } // delay PropertyAction { target: winMenu; properties: "visible"; } NumberAnimation { target: winMenu; properties: "opacity"; duration: 400; } ScriptAction { script: winMenu.showScore(); } ScriptAction { script: if (winMenu.highscore) winMenu.showBalloon(); } PropertyAction { target: blocker; property: "enabled"; value: false; } } }, Transition { from: "congrats"; to: "playing"; SequentialAnimation { PropertyAction { target: blocker; property: "enabled"; value: true; } NumberAnimation { target: winMenu; properties: "opacity"; duration: 400; } PropertyAction { target: winMenu; properties: "visible"; } PropertyAction { target: blocker; property: "enabled"; value: false; } } }, Transition { from: "paused"; to: ""; SequentialAnimation { PropertyAction { target: blocker; property: "enabled"; value: true; } PropertyAction { target: switcher; properties: "visible"; } ParallelAnimation { NumberAnimation { target: stage; properties: "opacity"; duration: 400; } NumberAnimation { target: pauseMenu; properties: "opacity"; duration: 400; } } PropertyAction { target: stage; properties: "visible"; } PropertyAction { target: pauseMenu; properties: "visible"; } PropertyAction { target: blocker; property: "enabled"; value: false; } } }, Transition { from: ""; to: "paused"; SequentialAnimation { PropertyAction { target: blocker; property: "enabled"; value: true; } PropertyAction { target: stage; properties: "visible"; } PropertyAction { target: pauseMenu; properties: "visible"; } ParallelAnimation { NumberAnimation { target: stage; properties: "opacity"; duration: 400; } NumberAnimation { target: pauseMenu; properties: "opacity"; duration: 400; } } PropertyAction { target: switcher; properties: "visible"; } PropertyAction { target: blocker; property: "enabled"; value: false; } } }, Transition { from: "congrats"; to: ""; SequentialAnimation { PropertyAction { target: blocker; property: "enabled"; value: true; } PropertyAction { target: switcher; properties: "visible"; } NumberAnimation { target: winMenu; properties: "opacity"; duration: 400; } PropertyAction { target: winMenu; properties: "visible"; } PropertyAction { target: blocker; property: "enabled"; value: false; } } } ] }