From dea27f3421e29a54add2fdab2424529f77535def Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Thu, 15 Nov 2012 13:47:24 +0100 Subject: Refactoring samegame This patch cleans up the example and makes it more customizeable by adding a setting file. Also a bug has been fixed, where the "New game" button could not been clicked. Change-Id: Ia397258721dfcf4900e3ed1e176a257eccfad354 Reviewed-by: Alan Alpert (RIM) --- examples/demos/samegame/content/BlockEmitter.qml | 6 +- examples/demos/samegame/content/Button.qml | 9 ++- examples/demos/samegame/content/GameArea.qml | 4 +- examples/demos/samegame/content/PaintEmitter.qml | 5 +- examples/demos/samegame/content/SamegameText.qml | 49 ++++++++++++ examples/demos/samegame/content/samegame.js | 27 +++---- examples/demos/samegame/samegame.pro | 2 +- examples/demos/samegame/samegame.qml | 99 +++++++++--------------- examples/demos/samegame/settings.js | 56 ++++++++++++++ examples/shared/shared.h | 10 ++- 10 files changed, 178 insertions(+), 89 deletions(-) create mode 100644 examples/demos/samegame/content/SamegameText.qml create mode 100644 examples/demos/samegame/settings.js diff --git a/examples/demos/samegame/content/BlockEmitter.qml b/examples/demos/samegame/content/BlockEmitter.qml index e39616ee52..7dad509dfd 100644 --- a/examples/demos/samegame/content/BlockEmitter.qml +++ b/examples/demos/samegame/content/BlockEmitter.qml @@ -41,6 +41,8 @@ import QtQuick 2.0 import QtQuick.Particles 2.0 +import "../settings.js" as Settings + Emitter { property Item block: parent velocity: TargetDirection{targetX: block.width/2; targetY: block.height/2; magnitude: -40; magnitudeVariation: 40} @@ -50,6 +52,6 @@ Emitter { lifeSpan: 700; lifeSpanVariation: 100 emitRate: 1000 maximumEmitted: 100 //only fires 0.1s bursts (still 2x old number) - size: 28 - endSize: 14 + size: Settings.blockSize * 0.85 + endSize: Settings.blockSize * 0.85 /2 } diff --git a/examples/demos/samegame/content/Button.qml b/examples/demos/samegame/content/Button.qml index b17c831e41..aab21ec8c6 100644 --- a/examples/demos/samegame/content/Button.qml +++ b/examples/demos/samegame/content/Button.qml @@ -47,12 +47,15 @@ Item { property alias group: emitter.group signal clicked property bool rotatedButton: false - //Defaults, feel free to override + width: image.width - height: image.height + height: image.sourceSize.height Image { id: image - anchors.centerIn: parent + height: parent.height + width: height/sourceSize.height * sourceSize.width + + anchors.horizontalCenter: parent.horizontalCenter rotation: rotatedButton ? ((Math.random() * 3 + 2) * (Math.random() <= 0.5 ? -1 : 1)) : 0 MenuEmitter { id: emitter diff --git a/examples/demos/samegame/content/GameArea.qml b/examples/demos/samegame/content/GameArea.qml index 0185ab50dc..f3ca98d80e 100644 --- a/examples/demos/samegame/content/GameArea.qml +++ b/examples/demos/samegame/content/GameArea.qml @@ -48,7 +48,6 @@ Item { property int score: 0 property int highScore: 0 property int moves: 0 - property int blockSize: 32 property string mode: "" property ParticleSystem ps: particleSystem //For easy theming @@ -85,12 +84,11 @@ Item { Image { id: bg z: -1 + anchors.fill: parent source: background; fillMode: Image.PreserveAspectCrop } - width: 320 - height: 480 MouseArea { anchors.fill: parent; onClicked: { if (puzzleTextBubble.opacity == 1) { diff --git a/examples/demos/samegame/content/PaintEmitter.qml b/examples/demos/samegame/content/PaintEmitter.qml index 5f2ea1f9a9..4a67c4a2d2 100644 --- a/examples/demos/samegame/content/PaintEmitter.qml +++ b/examples/demos/samegame/content/PaintEmitter.qml @@ -40,6 +40,7 @@ import QtQuick 2.0 import QtQuick.Particles 2.0 +import "../settings.js" as Settings Emitter { property Item block: parent @@ -56,8 +57,8 @@ Emitter { "yellowspots"; } } - size: 64 - endSize: 16 + size: Settings.blockSize * 2 + endSize: Settings.blockSize/2 lifeSpan: 30000 enabled: false emitRate: 60 diff --git a/examples/demos/samegame/content/SamegameText.qml b/examples/demos/samegame/content/SamegameText.qml new file mode 100644 index 0000000000..28c85f9486 --- /dev/null +++ b/examples/demos/samegame/content/SamegameText.qml @@ -0,0 +1,49 @@ +/*************************************************************************** +** +** Copyright (C) 2012 Research In Motion +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import "../settings.js" as Settings + +Text { + font.pixelSize: Settings.fontPixelSize; + color: "white"; + textFormat: Text.StyledText; + Behavior on opacity { NumberAnimation {} } +} diff --git a/examples/demos/samegame/content/samegame.js b/examples/demos/samegame/content/samegame.js index 320203583f..7b226cb42f 100755 --- a/examples/demos/samegame/content/samegame.js +++ b/examples/demos/samegame/content/samegame.js @@ -41,6 +41,7 @@ /* This script file handles the game logic */ .pragma library .import QtQuick.LocalStorage 2.0 as Sql +.import "../settings.js" as Settings var maxColumn = 10; var maxRow = 13; @@ -110,8 +111,8 @@ function startNewGame(gc, mode, map) gc.gameOver = false; gc.mode = gameMode; // Calculate board size - maxColumn = Math.floor(gameCanvas.width/gameCanvas.blockSize); - maxRow = Math.floor(gameCanvas.height/gameCanvas.blockSize); + maxColumn = Math.floor(gameCanvas.width/Settings.blockSize); + maxRow = Math.floor(gameCanvas.height/Settings.blockSize); maxIndex = maxRow * maxColumn; if (gameMode == "arcade") //Needs to be after board sizing getHighScore(); @@ -142,8 +143,8 @@ function handleClick(x,y) { if (betweenTurns || gameOver || gameCanvas == undefined) return; - var column = Math.floor(x/gameCanvas.blockSize); - var row = Math.floor(y/gameCanvas.blockSize); + var column = Math.floor(x/Settings.blockSize); + var row = Math.floor(y/Settings.blockSize); if (column >= maxColumn || column < 0 || row >= maxRow || row < 0) return; if (board[index(column, row)] == null) @@ -211,7 +212,7 @@ function shuffleDown() } else { if (fallDist > 0) { var obj = board[index(column, row)]; - obj.y = (row + fallDist) * gameCanvas.blockSize; + obj.y = (row + fallDist) * Settings.blockSize; board[index(column, row + fallDist)] = obj; board[index(column, row)] = null; } @@ -229,7 +230,7 @@ function shuffleDown() obj = board[index(column, row)]; if (obj == null) continue; - obj.x = (column - fallDist) * gameCanvas.blockSize; + obj.x = (column - fallDist) * Settings.blockSize; board[index(column - fallDist,row)] = obj; board[index(column, row)] = null; } @@ -250,7 +251,7 @@ function shuffleUp() } else { if (fallDist > 0) { var obj = board[index(column, row)]; - obj.y = (row - fallDist) * gameCanvas.blockSize; + obj.y = (row - fallDist) * Settings.blockSize; board[index(column, row - fallDist)] = obj; board[index(column, row)] = null; } @@ -268,7 +269,7 @@ function shuffleUp() obj = board[index(column, row)]; if (obj == null) continue; - obj.x = (column - fallDist) * gameCanvas.blockSize; + obj.x = (column - fallDist) * Settings.blockSize; board[index(column - fallDist,row)] = obj; board[index(column, row)] = null; } @@ -371,17 +372,17 @@ function createBlock(column,row,type) } var dynamicObject = component.createObject(gameCanvas, {"type": type, - "x": column*gameCanvas.blockSize, - "y": -1*gameCanvas.blockSize, - "width": gameCanvas.blockSize, - "height": gameCanvas.blockSize, + "x": column*Settings.blockSize, + "y": -1*Settings.blockSize, + "width": Settings.blockSize, + "height": Settings.blockSize, "particleSystem": gameCanvas.ps}); if (dynamicObject == null){ console.log("error creating block"); console.log(component.errorString()); return false; } - dynamicObject.y = row*gameCanvas.blockSize; + dynamicObject.y = row*Settings.blockSize; dynamicObject.spawned = true; board[index(column,row)] = dynamicObject; diff --git a/examples/demos/samegame/samegame.pro b/examples/demos/samegame/samegame.pro index 4aa3a3324e..80d3d2992b 100644 --- a/examples/demos/samegame/samegame.pro +++ b/examples/demos/samegame/samegame.pro @@ -4,6 +4,6 @@ QT += qml quick SOURCES += main.cpp target.path = $$[QT_INSTALL_EXAMPLES]/qtquick/demos/samegame -qml.files = samegame.qml content +qml.files = samegame.qml content settings.js qml.path = $$[QT_INSTALL_EXAMPLES]/qtquick/demos/samegame INSTALLS += target qml diff --git a/examples/demos/samegame/samegame.qml b/examples/demos/samegame/samegame.qml index 5b57058a19..2b0b82a37c 100644 --- a/examples/demos/samegame/samegame.qml +++ b/examples/demos/samegame/samegame.qml @@ -41,13 +41,14 @@ import QtQuick 2.0 import QtQuick.Particles 2.0 import "content/samegame.js" as Logic +import "settings.js" as Settings import "content" Rectangle { id: root width: 320; height: 480 property int acc: 0 - property int menuDelay: 500 + function loadPuzzle() { if (gameCanvas.mode != "") @@ -77,10 +78,11 @@ Rectangle { GameArea { id: gameCanvas z: 1 + y: Settings.headerHeight + width: parent.width + height: parent.height - Settings.headerHeight - Settings.footerHeight - y: 20 - height: parent.height - 64 backgroundVisible: root.state == "in-game" onModeChanged: if (gameCanvas.mode != "puzzle") puzzleWon = false; //UI has stricter constraints on this variable than the game does Age { @@ -102,7 +104,7 @@ Rectangle { LogoAnimation { x: 64 - y: 20 + y: Settings.headerHeight particleSystem: gameCanvas.ps running: root.state == "" } @@ -116,10 +118,9 @@ Rectangle { Column { y: 100 + 40 - spacing: 0 + spacing: Settings.menuButtonSpacing Button { - height: 64 width: root.width rotatedButton: true imgSrc: "content/gfx/but-game-1.png" @@ -136,7 +137,7 @@ Rectangle { group: "green" Timer { id: arcadeTimer - interval: menuDelay + interval: Settings.menuDelay running : false repeat : false onTriggered: Logic.startNewGame(gameCanvas) @@ -144,7 +145,6 @@ Rectangle { } Button { - height: 64 width: root.width rotatedButton: true imgSrc: "content/gfx/but-game-2.png" @@ -160,7 +160,7 @@ Rectangle { group: "green" Timer { id: twopTimer - interval: menuDelay + interval: Settings.menuDelay running : false repeat : false onTriggered: Logic.startNewGame(gameCanvas, "multiplayer") @@ -168,7 +168,6 @@ Rectangle { } Button { - height: 64 width: root.width rotatedButton: true imgSrc: "content/gfx/but-game-3.png" @@ -184,7 +183,7 @@ Rectangle { group: "blue" Timer { id: endlessTimer - interval: menuDelay + interval: Settings.menuDelay running : false repeat : false onTriggered: Logic.startNewGame(gameCanvas, "endless") @@ -192,7 +191,6 @@ Rectangle { } Button { - height: 64 width: root.width rotatedButton: true imgSrc: "content/gfx/but-game-4.png" @@ -207,7 +205,7 @@ Rectangle { } Timer { id: puzzleTimer - interval: menuDelay + interval: Settings.menuDelay running : false repeat : false onTriggered: loadPuzzle(); @@ -222,61 +220,45 @@ Rectangle { source: "content/gfx/bar.png" width: parent.width z: 6 - y: -24 - height: 24 + y: -Settings.headerHeight + height: Settings.headerHeight Behavior on opacity { NumberAnimation {} } - Text { + SamegameText { id: arcadeScore anchors { right: parent.right; topMargin: 3; rightMargin: 11; top: parent.top} text: 'P1: ' + gameCanvas.score - font.pixelSize: 14 + font.pixelSize: Settings.fontPixelSize textFormat: Text.StyledText color: "white" opacity: gameCanvas.mode == "arcade" ? 1 : 0 Behavior on opacity { NumberAnimation {} } } - Text { + SamegameText { id: arcadeHighScore anchors { left: parent.left; topMargin: 3; leftMargin: 11; top: parent.top} text: 'Highscore: ' + gameCanvas.highScore - font.pixelSize: 14 - color: "white" - textFormat: Text.StyledText opacity: gameCanvas.mode == "arcade" ? 1 : 0 - Behavior on opacity { NumberAnimation {} } } - Text { + SamegameText { id: p1Score anchors { right: parent.right; topMargin: 3; rightMargin: 11; top: parent.top} text: 'P1: ' + gameCanvas.score - textFormat: Text.StyledText - font.pixelSize: 14 - color: "white" opacity: gameCanvas.mode == "multiplayer" ? 1 : 0 - Behavior on opacity { NumberAnimation {} } } - Text { + SamegameText { id: p2Score anchors { left: parent.left; topMargin: 3; leftMargin: 11; top: parent.top} text: 'P2: ' + gameCanvas.score2 - textFormat: Text.StyledText - font.pixelSize: 14 - color: "white" opacity: gameCanvas.mode == "multiplayer" ? 1 : 0 - Behavior on opacity { NumberAnimation {} } rotation: 180 } - Text { + SamegameText { id: puzzleMoves anchors { left: parent.left; topMargin: 3; leftMargin: 11; top: parent.top} text: 'Moves: ' + gameCanvas.moves - textFormat: Text.StyledText - font.pixelSize: 14 - color: "white" opacity: gameCanvas.mode == "puzzle" ? 1 : 0 - Behavior on opacity { NumberAnimation {} } } - Text { + SamegameText { Image { source: "content/gfx/icon-time.png" x: -20 @@ -284,10 +266,7 @@ Rectangle { id: puzzleTime anchors { topMargin: 3; top: parent.top; horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: 20} text: "00:00" - font.pixelSize: 14 - color: "white" opacity: gameCanvas.mode == "puzzle" ? 1 : 0 - Behavior on opacity { NumberAnimation {} } Timer { interval: 1000 repeat: true @@ -300,56 +279,51 @@ Rectangle { } } } - Text { + SamegameText { id: puzzleScore anchors { right: parent.right; topMargin: 3; rightMargin: 11; top: parent.top} text: 'Score: ' + gameCanvas.score - textFormat: Text.StyledText - font.pixelSize: 14 - color: "white" opacity: gameCanvas.mode == "puzzle" ? 1 : 0 - Behavior on opacity { NumberAnimation {} } } } Image { id: bottomBar width: parent.width - height: 44 + height: Settings.footerHeight source: "content/gfx/bar.png" - y: parent.height - 44 + y: parent.height - Settings.footerHeight; z: 2 - function selectButtons() { - menuButton.visible = (root.state == "in-game"); - nextButton.visible = (root.state == "in-game"); - againButton.visible = (root.state == "in-game"); - } Button { id: quitButton + height: Settings.toolButtonHeight imgSrc: "content/gfx/but-quit.png" onClicked: {Qt.quit(); } anchors { left: parent.left; verticalCenter: parent.verticalCenter; leftMargin: 11 } } Button { id: menuButton + height: Settings.toolButtonHeight imgSrc: "content/gfx/but-menu.png" - visible: false + visible: (root.state == "in-game"); onClicked: {root.state = ""; Logic.cleanUp(); gameCanvas.mode = ""} anchors { left: quitButton.right; verticalCenter: parent.verticalCenter; leftMargin: 0 } } Button { id: againButton + height: Settings.toolButtonHeight imgSrc: "content/gfx/but-game-new.png" - visible: false - opacity: gameCanvas.gameOver && (gameCanvas.mode == "arcade" || gameCanvas.mode == "multiplayer") ? 1 : 0 + visible: (root.state == "in-game"); + opacity: gameCanvas.gameOver && (gameCanvas.mode == "arcade" || gameCanvas.mode == "multiplayer") Behavior on opacity{ NumberAnimation {} } - onClicked: {if (gameCanvas.gameOver) Logic.startNewGame(gameCanvas, gameCanvas.mode);} + onClicked: {if (gameCanvas.gameOver) { Logic.startNewGame(gameCanvas, gameCanvas.mode);}} anchors { right: parent.right; verticalCenter: parent.verticalCenter; rightMargin: 11 } } Button { id: nextButton + height: Settings.toolButtonHeight imgSrc: "content/gfx/but-puzzle-next.png" - visible: false + visible: (root.state == "in-game") && gameCanvas.mode == "puzzle" && gameCanvas.puzzleWon opacity: gameCanvas.puzzleWon ? 1 : 0 Behavior on opacity{ NumberAnimation {} } onClicked: {if (gameCanvas.puzzleWon) nextPuzzle();} @@ -364,13 +338,12 @@ Rectangle { SequentialAnimation { id: stateChangeAnim ParallelAnimation { - NumberAnimation { target: bottomBar; property: "y"; to: root.height; duration: menuDelay/2; easing.type: Easing.OutQuad } - NumberAnimation { target: scoreBar; property: "y"; to: -24; duration: menuDelay/2; easing.type: Easing.OutQuad } + NumberAnimation { target: bottomBar; property: "y"; to: root.height; duration: Settings.menuDelay/2; easing.type: Easing.OutQuad } + NumberAnimation { target: scoreBar; property: "y"; to: -Settings.headerHeight; duration: Settings.menuDelay/2; easing.type: Easing.OutQuad } } - ScriptAction { script: bottomBar.selectButtons(); } ParallelAnimation { - NumberAnimation { target: bottomBar; property: "y"; to: root.height - 44; duration: menuDelay/2; easing.type: Easing.OutBounce} - NumberAnimation { target: scoreBar; property: "y"; to: root.state == "" ? -24 : 0; duration: menuDelay/2; easing.type: Easing.OutBounce} + NumberAnimation { target: bottomBar; property: "y"; to: root.height - Settings.footerHeight; duration: Settings.menuDelay/2; easing.type: Easing.OutBounce} + NumberAnimation { target: scoreBar; property: "y"; to: root.state == "" ? -Settings.headerHeight : 0; duration: Settings.menuDelay/2; easing.type: Easing.OutBounce} } } diff --git a/examples/demos/samegame/settings.js b/examples/demos/samegame/settings.js new file mode 100644 index 0000000000..e09dee9af3 --- /dev/null +++ b/examples/demos/samegame/settings.js @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Research In Motion +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +.pragma library + +//This should be switched over once a proper QML settings API exists + +var menuDelay = 500 + +var headerHeight = 20 // 70 on BB10 +var footerHeight = 44 // 100 on BB10 + +var fontPixelSize = 14 // 55 on BB10 + +var blockSize = 32 // 64 on BB10 + +var toolButtonHeight = 32 // 64 on BB10 + +var menuButtonSpacing = 0 // 15 on BB10 diff --git a/examples/shared/shared.h b/examples/shared/shared.h index e725f8146b..7fd2f08a40 100644 --- a/examples/shared/shared.h +++ b/examples/shared/shared.h @@ -70,7 +70,13 @@ return -1;\ }\ view.connect(view.engine(), SIGNAL(quit()), &app, SLOT(quit()));\ - view.setSource(QUrl::fromLocalFile(fileName));\ - view.show();\ + view.setSource(QUrl::fromLocalFile(fileName)); \ + if (QGuiApplication::platformName() == QLatin1String("qnx") || \ + QGuiApplication::platformName() == QLatin1String("eglfs")) {\ + view.setResizeMode(QQuickView::SizeRootObjectToView);\ + view.showFullScreen();\ + } else {\ + view.show();\ + }\ return app.exec();\ } -- cgit v1.2.3