1 /****************************************************************************
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
6 ** This file is part of the examples of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:BSD$
9 ** You may use this file under the terms of the BSD license as follows:
11 ** "Redistribution and use in source and binary forms, with or without
12 ** modification, are permitted provided that the following conditions are
14 ** * Redistributions of source code must retain the above copyright
15 ** notice, this list of conditions and the following disclaimer.
16 ** * Redistributions in binary form must reproduce the above copyright
17 ** notice, this list of conditions and the following disclaimer in
18 ** the documentation and/or other materials provided with the
20 ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 ** of its contributors may be used to endorse or promote products derived
22 ** from this software without specific prior written permission.
25 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
39 ****************************************************************************/
42 import QtQuick.Particles 2.0
43 import "content/samegame.js" as Logic
44 import "settings.js" as Settings
49 width: 320; height: 480
53 function loadPuzzle() {
54 if (gameCanvas.mode != "")
56 Logic.startNewGame(gameCanvas,"puzzle","levels/level"+acc+".qml")
58 function nextPuzzle() {
65 running : gameCanvas.gameOver && gameCanvas.mode == "puzzle" //mode will be reset by cleanUp();
74 source: "content/gfx/background.png"
81 y: Settings.headerHeight
84 height: parent.height - Settings.headerHeight - Settings.footerHeight
86 backgroundVisible: root.state == "in-game"
87 onModeChanged: if (gameCanvas.mode != "puzzle") puzzleWon = false; //UI has stricter constraints on this variable than the game does
89 groups: ["redspots", "greenspots", "bluespots", "yellowspots"]
90 enabled: root.state == ""
94 onPuzzleLost: acc--;//So that nextPuzzle() reloads the current one
102 anchors.top: parent.top
103 anchors.bottom: bottomBar.top
107 y: Settings.headerHeight
108 particleSystem: gameCanvas.ps
109 running: root.state == ""
114 Image { source: "content/gfx/logo-a.png" }
115 Image { source: "content/gfx/logo-m.png" }
116 Image { source: "content/gfx/logo-e.png" }
121 spacing: Settings.menuButtonSpacing
126 imgSrc: "content/gfx/but-game-1.png"
128 if (root.state == "in-game")
129 return //Prevent double clicking
130 root.state = "in-game"
131 gameCanvas.blockFile = "Block.qml"
132 gameCanvas.background = "gfx/background.png"
135 //Emitted particles don't fade out, because ImageParticle is on the GameArea
136 system: gameCanvas.ps
140 interval: Settings.menuDelay
143 onTriggered: Logic.startNewGame(gameCanvas)
150 imgSrc: "content/gfx/but-game-2.png"
152 if (root.state == "in-game")
154 root.state = "in-game"
155 gameCanvas.blockFile = "Block.qml"
156 gameCanvas.background = "gfx/background.png"
159 system: gameCanvas.ps
163 interval: Settings.menuDelay
166 onTriggered: Logic.startNewGame(gameCanvas, "multiplayer")
173 imgSrc: "content/gfx/but-game-3.png"
175 if (root.state == "in-game")
177 root.state = "in-game"
178 gameCanvas.blockFile = "SimpleBlock.qml"
179 gameCanvas.background = "gfx/background.png"
180 endlessTimer.start();
182 system: gameCanvas.ps
186 interval: Settings.menuDelay
189 onTriggered: Logic.startNewGame(gameCanvas, "endless")
196 imgSrc: "content/gfx/but-game-4.png"
199 if (root.state == "in-game")
201 root.state = "in-game"
202 gameCanvas.blockFile = "PuzzleBlock.qml"
203 gameCanvas.background = "gfx/background.png"
208 interval: Settings.menuDelay
211 onTriggered: loadPuzzle();
213 system: gameCanvas.ps
220 source: "content/gfx/bar.png"
223 y: -Settings.headerHeight
224 height: Settings.headerHeight
225 Behavior on opacity { NumberAnimation {} }
228 anchors { right: parent.right; topMargin: 3; rightMargin: 11; top: parent.top}
229 text: '<font color="#f7d303">P1:</font> ' + gameCanvas.score
230 font.pixelSize: Settings.fontPixelSize
231 textFormat: Text.StyledText
233 opacity: gameCanvas.mode == "arcade" ? 1 : 0
234 Behavior on opacity { NumberAnimation {} }
238 anchors { left: parent.left; topMargin: 3; leftMargin: 11; top: parent.top}
239 text: '<font color="#f7d303">Highscore:</font> ' + gameCanvas.highScore
240 opacity: gameCanvas.mode == "arcade" ? 1 : 0
244 anchors { right: parent.right; topMargin: 3; rightMargin: 11; top: parent.top}
245 text: '<font color="#f7d303">P1:</font> ' + gameCanvas.score
246 opacity: gameCanvas.mode == "multiplayer" ? 1 : 0
250 anchors { left: parent.left; topMargin: 3; leftMargin: 11; top: parent.top}
251 text: '<font color="#f7d303">P2:</font> ' + gameCanvas.score2
252 opacity: gameCanvas.mode == "multiplayer" ? 1 : 0
257 anchors { left: parent.left; topMargin: 3; leftMargin: 11; top: parent.top}
258 text: '<font color="#f7d303">Moves:</font> ' + gameCanvas.moves
259 opacity: gameCanvas.mode == "puzzle" ? 1 : 0
263 source: "content/gfx/icon-time.png"
267 anchors { topMargin: 3; top: parent.top; horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: 20}
269 opacity: gameCanvas.mode == "puzzle" ? 1 : 0
273 running: gameCanvas.mode == "puzzle" && !gameCanvas.gameOver
275 var elapsed = Math.floor((new Date() - Logic.gameDuration)/ 1000.0);
276 var mins = Math.floor(elapsed/60.0);
277 var secs = (elapsed % 60);
278 puzzleTime.text = (mins < 10 ? "0" : "") + mins + ":" + (secs < 10 ? "0" : "") + secs;
284 anchors { right: parent.right; topMargin: 3; rightMargin: 11; top: parent.top}
285 text: '<font color="#f7d303">Score:</font> ' + gameCanvas.score
286 opacity: gameCanvas.mode == "puzzle" ? 1 : 0
293 height: Settings.footerHeight
294 source: "content/gfx/bar.png"
295 y: parent.height - Settings.footerHeight;
299 height: Settings.toolButtonHeight
300 imgSrc: "content/gfx/but-quit.png"
301 onClicked: {Qt.quit(); }
302 anchors { left: parent.left; verticalCenter: parent.verticalCenter; leftMargin: 11 }
306 height: Settings.toolButtonHeight
307 imgSrc: "content/gfx/but-menu.png"
308 visible: (root.state == "in-game");
309 onClicked: {root.state = ""; Logic.cleanUp(); gameCanvas.mode = ""}
310 anchors { left: quitButton.right; verticalCenter: parent.verticalCenter; leftMargin: 0 }
314 height: Settings.toolButtonHeight
315 imgSrc: "content/gfx/but-game-new.png"
316 visible: (root.state == "in-game");
317 opacity: gameCanvas.gameOver && (gameCanvas.mode == "arcade" || gameCanvas.mode == "multiplayer")
318 Behavior on opacity{ NumberAnimation {} }
319 onClicked: {if (gameCanvas.gameOver) { Logic.startNewGame(gameCanvas, gameCanvas.mode);}}
320 anchors { right: parent.right; verticalCenter: parent.verticalCenter; rightMargin: 11 }
324 height: Settings.toolButtonHeight
325 imgSrc: "content/gfx/but-puzzle-next.png"
326 visible: (root.state == "in-game") && gameCanvas.mode == "puzzle" && gameCanvas.puzzleWon
327 opacity: gameCanvas.puzzleWon ? 1 : 0
328 Behavior on opacity{ NumberAnimation {} }
329 onClicked: {if (gameCanvas.puzzleWon) nextPuzzle();}
330 anchors { right: parent.right; verticalCenter: parent.verticalCenter; rightMargin: 11 }
336 onStateChanged: stateChangeAnim.running = true
338 SequentialAnimation {
341 NumberAnimation { target: bottomBar; property: "y"; to: root.height; duration: Settings.menuDelay/2; easing.type: Easing.OutQuad }
342 NumberAnimation { target: scoreBar; property: "y"; to: -Settings.headerHeight; duration: Settings.menuDelay/2; easing.type: Easing.OutQuad }
345 NumberAnimation { target: bottomBar; property: "y"; to: root.height - Settings.footerHeight; duration: Settings.menuDelay/2; easing.type: Easing.OutBounce}
346 NumberAnimation { target: scoreBar; property: "y"; to: root.state == "" ? -Settings.headerHeight : 0; duration: Settings.menuDelay/2; easing.type: Easing.OutBounce}
363 NumberAnimation {properties: "x,y,opacity"}
369 Keys.onAsteriskPressed: Logic.nuke();
370 Keys.onSpacePressed: gameCanvas.puzzleWon = true;