From 4796c4d9550166500d54b829fa97541e4de6e929 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 10 Aug 2011 13:24:37 +1000 Subject: SameGame refactor A little more imperative with dialogs controlled from script, but better separation of GameArea and UI. Also removes old highscore script that was never used. Change-Id: Ib244acc90b0fc92b3a6534169e429b6acef0838e Reviewed-on: http://codereview.qt.nokia.com/2798 Reviewed-by: Alan Alpert --- .../samegame/SamegameCore/BoomBlock.qml | 1 + .../declarative/samegame/SamegameCore/Dialog.qml | 1 + .../declarative/samegame/SamegameCore/GameArea.qml | 91 ++++++++++++++++ .../samegame/SamegameCore/NameInputDialog.qml | 93 ++++++++++++++++ examples/declarative/samegame/SamegameCore/qmldir | 3 - .../declarative/samegame/SamegameCore/samegame.js | 51 ++++----- examples/declarative/samegame/highscores/README | 1 - .../declarative/samegame/highscores/score_data.xml | 2 - .../samegame/highscores/score_style.xsl | 28 ----- .../declarative/samegame/highscores/scores.php | 34 ------ examples/declarative/samegame/samegame.qml | 121 ++------------------- 11 files changed, 220 insertions(+), 206 deletions(-) create mode 100644 examples/declarative/samegame/SamegameCore/GameArea.qml create mode 100644 examples/declarative/samegame/SamegameCore/NameInputDialog.qml delete mode 100644 examples/declarative/samegame/SamegameCore/qmldir delete mode 100644 examples/declarative/samegame/highscores/README delete mode 100755 examples/declarative/samegame/highscores/score_data.xml delete mode 100755 examples/declarative/samegame/highscores/score_style.xsl delete mode 100755 examples/declarative/samegame/highscores/scores.php diff --git a/examples/declarative/samegame/SamegameCore/BoomBlock.qml b/examples/declarative/samegame/SamegameCore/BoomBlock.qml index 2d8fdba2c9..4f8ef70851 100644 --- a/examples/declarative/samegame/SamegameCore/BoomBlock.qml +++ b/examples/declarative/samegame/SamegameCore/BoomBlock.qml @@ -47,6 +47,7 @@ Item { property bool dying: false property bool spawned: false property int type: 0 + property ParticleSystem particleSystem Behavior on x { enabled: spawned; diff --git a/examples/declarative/samegame/SamegameCore/Dialog.qml b/examples/declarative/samegame/SamegameCore/Dialog.qml index aea6ac7dda..eddc5caacc 100644 --- a/examples/declarative/samegame/SamegameCore/Dialog.qml +++ b/examples/declarative/samegame/SamegameCore/Dialog.qml @@ -43,6 +43,7 @@ import QtQuick 2.0 Rectangle { id: page + anchors.centerIn: parent property Item text: dialogText property bool open: false diff --git a/examples/declarative/samegame/SamegameCore/GameArea.qml b/examples/declarative/samegame/SamegameCore/GameArea.qml new file mode 100644 index 0000000000..967e299577 --- /dev/null +++ b/examples/declarative/samegame/SamegameCore/GameArea.qml @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Particles 2.0 +import "samegame.js" as Logic + +Item { + id: gameCanvas + property int score: 0 + property int blockSize: 40 + property ParticleSystem ps: particleSystem + Image { + id: background + anchors.fill: parent + z: -1 + source: "pics/background.png" + fillMode: Image.PreserveAspectCrop + } + + width: 480 + height: 800 + MouseArea { + anchors.fill: parent; onClicked: Logic.handleClick(mouse.x,mouse.y); + } + ParticleSystem{ + id: particleSystem; + z:2 + ImageParticle { + particles: ["red"] + color: Qt.darker("red");//Actually want desaturated... + source: "pics/particle.png" + colorVariation: 0.4 + alpha: 0.1 + } + ImageParticle { + particles: ["green"] + color: Qt.darker("green");//Actually want desaturated... + source: "pics/particle.png" + colorVariation: 0.4 + alpha: 0.1 + } + ImageParticle { + particles: ["blue"] + color: Qt.darker("blue");//Actually want desaturated... + source: "pics/particle.png" + colorVariation: 0.4 + alpha: 0.1 + } + anchors.fill: parent + } +} + diff --git a/examples/declarative/samegame/SamegameCore/NameInputDialog.qml b/examples/declarative/samegame/SamegameCore/NameInputDialog.qml new file mode 100644 index 0000000000..9b27d2f8a7 --- /dev/null +++ b/examples/declarative/samegame/SamegameCore/NameInputDialog.qml @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 2.0 + +Dialog { + id: nameInputDialog + + property int initialWidth: 0 + property alias name: nameInputText.text + + anchors.centerIn: parent + z: 22; + + Behavior on width { + NumberAnimation {} + enabled: nameInputDialog.initialWidth != 0 + } + + signal accepted(string name) + onClosed: { + if (nameInputText.text != "") + accepted(name); + } + Text { + id: dialogText + anchors { left: nameInputDialog.left; leftMargin: 20; verticalCenter: parent.verticalCenter } + text: "You won! Please enter your name: " + } + MouseArea { + anchors.fill: parent + onClicked: { + if (nameInputText.text == "") + nameInputText.openSoftwareInputPanel(); + else + nameInputDialog.forceClose(); + } + } + + TextInput { + id: nameInputText + anchors { verticalCenter: parent.verticalCenter; left: dialogText.right } + focus: visible + autoScroll: false + maximumLength: 24 + onTextChanged: { + var newWidth = nameInputText.width + dialogText.width + 40; + if ( (newWidth > nameInputDialog.width && newWidth < screen.width) + || (nameInputDialog.width > nameInputDialog.initialWidth) ) + nameInputDialog.width = newWidth; + } + onAccepted: { + nameInputDialog.forceClose(); + } + } +} diff --git a/examples/declarative/samegame/SamegameCore/qmldir b/examples/declarative/samegame/SamegameCore/qmldir deleted file mode 100644 index e17b1f5d2b..0000000000 --- a/examples/declarative/samegame/SamegameCore/qmldir +++ /dev/null @@ -1,3 +0,0 @@ -BoomBlock BoomBlock.qml -Button Button.qml -Dialog Dialog.qml diff --git a/examples/declarative/samegame/SamegameCore/samegame.js b/examples/declarative/samegame/SamegameCore/samegame.js index 4c5cbe5bb3..8c15af763a 100755 --- a/examples/declarative/samegame/SamegameCore/samegame.js +++ b/examples/declarative/samegame/SamegameCore/samegame.js @@ -1,4 +1,5 @@ /* This script file handles the game logic */ +.pragma library var maxColumn = 10; var maxRow = 15; @@ -8,7 +9,10 @@ var blockSrc = "BoomBlock.qml"; var scoresURL = ""; var gameDuration; var component = Qt.createComponent(blockSrc); -var highScoreBar = 0; +var highScoreBar = -1; +var gameCanvas; +var nameInputDialog = null; +var dialog = null; // Index function used instead of a 2D array function index(column, row) @@ -24,8 +28,9 @@ function timeStr(msecs) return ret; } -function startNewGame() +function startNewGame(gc) { + gameCanvas = gc; // Delete blocks from previous game for (var i = 0; i < maxIndex; i++) { if (board[i] != null) @@ -38,8 +43,10 @@ function startNewGame() maxIndex = maxRow * maxColumn; // Close dialogs - nameInputDialog.forceClose(); - dialog.forceClose(); + if(nameInputDialog != null) + nameInputDialog.forceClose(); + if(dialog != null) + dialog.forceClose(); // Initialize Board board = new Array(maxIndex); @@ -59,6 +66,10 @@ var floodBoard; // Set to 1 if the floodFill reaches off that node // NOTE: Be careful with vars named x,y, as the calling object's x,y are still in scope function handleClick(x,y) { + if(gameCanvas == undefined){ + console.log("But the game hasn't started yet!"); + return; + } var column = Math.floor(x/gameCanvas.blockSize); var row = Math.floor(y/gameCanvas.blockSize); if (column >= maxColumn || column < 0 || row >= maxRow || row < 0) @@ -153,11 +164,18 @@ function victoryCheck() // Checks for game over if (deservesBonus || !(floodMoveCheck(0, maxRow - 1, -1))) { gameDuration = new Date() - gameDuration; + if(nameInputDialog == null){ + nameInputDialog = Qt.createQmlObject('import "."; import "samegame.js" as Logic; NameInputDialog{onAccepted: Logic.saveHighScore(name)}', gameCanvas, "highscoredialog.qml"); + } + if(dialog == null){ + dialog = Qt.createComponent("Dialog.qml").createObject(gameCanvas); + } + initHighScoreBar(); if(gameCanvas.score > highScoreBar){ nameInputDialog.show("You won! Please enter your name: "); nameInputDialog.initialWidth = nameInputDialog.text.width + 20; if (nameInputDialog.name == "") - nameInputDialog.width = nameInputDialog.initialWidth; + nameInputDialog.width = nameInputDialog.initialWidth; nameInputDialog.text.opacity = 0; // Just a spacer }else{ dialog.show("You won!"); @@ -185,12 +203,13 @@ function createBlock(column,row) // only work if the block QML is a local file. Otherwise the component will // not be ready immediately. There is a statusChanged signal on the // component you could use if you want to wait to load remote files. - if(component.status == Component.Ready){ + if(component.status == 1){ var dynamicObject = component.createObject(gameCanvas, {"type": Math.floor(Math.random() * 3), "x": column*gameCanvas.blockSize, "width": gameCanvas.blockSize, - "height": gameCanvas.blockSize}); + "height": gameCanvas.blockSize, + "particleSystem": gameCanvas.ps}); if(dynamicObject == null){ console.log("error creating block"); console.log(component.errorString()); @@ -210,8 +229,6 @@ function createBlock(column,row) function initHighScoreBar() { - if(scoresURL != "") - return true;//don't query remote scores var db = openDatabaseSync( "SameGameScores", "1.0", @@ -270,19 +287,3 @@ function saveHighScore(name) } ); } - -function sendHighScore(name) -{ - var postman = new XMLHttpRequest() - var postData = "name=" + name + "&score=" + gameCanvas.score - + "&gridSize=" + maxColumn + "x" + maxRow - + "&time=" + Math.floor(gameDuration / 1000); - postman.open("POST", scoresURL, true); - postman.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); - postman.onreadystatechange = function() { - if (postman.readyState == postman.DONE) { - dialog.show("Your score has been uploaded."); - } - } - postman.send(postData); -} diff --git a/examples/declarative/samegame/highscores/README b/examples/declarative/samegame/highscores/README deleted file mode 100644 index eaa00fae37..0000000000 --- a/examples/declarative/samegame/highscores/README +++ /dev/null @@ -1 +0,0 @@ -The SameGame example can interface with a simple PHP script to store XML high score data on a remote server. We do not have a publically accessible server available for this use, but if you have access to a PHP capable webserver you can copy the files (score_data.xml, score.php, score_style.xsl) to it and alter the highscore_server variable at the top of the samegame.js file to point to it. diff --git a/examples/declarative/samegame/highscores/score_data.xml b/examples/declarative/samegame/highscores/score_data.xml deleted file mode 100755 index c3fd90d9cf..0000000000 --- a/examples/declarative/samegame/highscores/score_data.xml +++ /dev/null @@ -1,2 +0,0 @@ -1000000Alan the Tester0x00 -6213Alan12x1751 diff --git a/examples/declarative/samegame/highscores/score_style.xsl b/examples/declarative/samegame/highscores/score_style.xsl deleted file mode 100755 index 670354c965..0000000000 --- a/examples/declarative/samegame/highscores/score_style.xsl +++ /dev/null @@ -1,28 +0,0 @@ - - - - - SameGame High Scores - -

SameGame High Scores

- - - - - - - - - - - - - - - - -
NameScoreGrid SizeTime, s
- - -
-
diff --git a/examples/declarative/samegame/highscores/scores.php b/examples/declarative/samegame/highscores/scores.php deleted file mode 100755 index 3cceb2d738..0000000000 --- a/examples/declarative/samegame/highscores/scores.php +++ /dev/null @@ -1,34 +0,0 @@ -"; - echo "SameGame High Scores"; - if($score > 0){#Sending in a new high score - $name = $_POST["name"]; - $grid = $_POST["gridSize"]; - $time = $_POST["time"]; - if($name == "") - $name = "Anonymous"; - //if($grid != "10x10"){ - //Need a standard, so as to reject others? - //} - $file = fopen("score_data.xml", "a"); #It's XML. Happy? - $ret = fwrite($file, "". $score . "" - . $name . "" . $grid . "" - . $time . "\n"); - echo "Your score has been recorded. Thanks for playing!"; - if($ret == False) - echo "
There was an error though, so don't expect to see that score again."; - }else{#Read high score list - #Now uses XSLT to display. So just print the file. With XML cruft added. - #Note that firefox at least won't apply the XSLT on a php file. So redirecting - $file = fopen("scores.xml", "w"); - $ret = fwrite($file, '' . "\n" - . '' . "\n" - . "\n" . file_get_contents("score_data.xml") . "\n"); - if($ret == False) - echo "There was an internal error. Sorry."; - else - echo ''; - } - echo ""; -?> diff --git a/examples/declarative/samegame/samegame.qml b/examples/declarative/samegame/samegame.qml index 887cfe1cc9..baf5b8e926 100644 --- a/examples/declarative/samegame/samegame.qml +++ b/examples/declarative/samegame/samegame.qml @@ -46,143 +46,38 @@ import "SamegameCore/samegame.js" as Logic Rectangle { id: screen - width: 360; height: 640 - property bool inAnotherDemo: false //Samegame often is just plonked straight into other examples + width: 480; height: 640 SystemPalette { id: activePalette } - Item { + GameArea { + id: gameCanvas width: parent.width anchors { top: parent.top; bottom: toolBar.top } - - Image { - id: background - anchors.fill: parent - source: "SamegameCore/pics/background.png" - fillMode: Image.PreserveAspectCrop - } - - Item { - id: gameCanvas - property int score: 0 - property int blockSize: 40 - - z: 20; anchors.centerIn: parent - width: parent.width - (parent.width % blockSize); - height: parent.height - (parent.height % blockSize); - - MouseArea { - anchors.fill: parent; onClicked: Logic.handleClick(mouse.x,mouse.y); - } - } - Item{ - ParticleSystem{ id: particleSystem; } - ImageParticle { - system: particleSystem - particles: ["red"] - color: Qt.darker("red");//Actually want desaturated... - source: "SamegameCore/pics/particle.png" - colorVariation: 0.4 - alpha: 0.1 - } - ImageParticle { - system: particleSystem - particles: ["green"] - color: Qt.darker("green");//Actually want desaturated... - source: "SamegameCore/pics/particle.png" - colorVariation: 0.4 - alpha: 0.1 - } - ImageParticle { - system: particleSystem - particles: ["blue"] - color: Qt.darker("blue");//Actually want desaturated... - source: "SamegameCore/pics/particle.png" - colorVariation: 0.4 - alpha: 0.1 - } - id: aboveGameCanvas - anchors.fill: gameCanvas - z: gameCanvas.z + 1 - } - } - - Dialog { id: dialog; anchors.centerIn: parent; z: 21 } - - Dialog { - id: nameInputDialog - - property int initialWidth: 0 - property alias name: nameInputText.text - - anchors.centerIn: parent - z: 22; - - Behavior on width { - NumberAnimation {} - enabled: nameInputDialog.initialWidth != 0 - } - - onClosed: { - if (nameInputText.text != "") - Logic.saveHighScore(nameInputText.text); - } - Text { - id: dialogText - anchors { left: nameInputDialog.left; leftMargin: 20; verticalCenter: parent.verticalCenter } - text: "You won! Please enter your name: " - } - MouseArea { - anchors.fill: parent - onClicked: { - if (nameInputText.text == "") - nameInputText.openSoftwareInputPanel(); - else - nameInputDialog.forceClose(); - } - } - - TextInput { - id: nameInputText - anchors { verticalCenter: parent.verticalCenter; left: dialogText.right } - focus: visible - autoScroll: false - maximumLength: 24 - onTextChanged: { - var newWidth = nameInputText.width + dialogText.width + 40; - if ( (newWidth > nameInputDialog.width && newWidth < screen.width) - || (nameInputDialog.width > nameInputDialog.initialWidth) ) - nameInputDialog.width = newWidth; - } - onAccepted: { - nameInputDialog.forceClose(); - } - } } Rectangle { id: toolBar - width: parent.width; height: 58 + width: parent.width; height: 80 color: activePalette.window anchors.bottom: screen.bottom Button { id: newGameButton - anchors { left: parent.left; leftMargin: 3; verticalCenter: parent.verticalCenter } + anchors { left: parent.left; leftMargin: 12; verticalCenter: parent.verticalCenter } text: "New Game" - onClicked: Logic.startNewGame() + onClicked: Logic.startNewGame(gameCanvas) } Button { - visible: !inAnotherDemo text: "Quit" - anchors { left: newGameButton.right; leftMargin: 3; verticalCenter: parent.verticalCenter } + anchors { left: newGameButton.right; leftMargin: 12; verticalCenter: parent.verticalCenter } onClicked: Qt.quit(); } Text { id: score - anchors { right: parent.right; rightMargin: 3; verticalCenter: parent.verticalCenter } + anchors { right: parent.right; rightMargin: 12; verticalCenter: parent.verticalCenter } text: "Score: " + gameCanvas.score font.bold: true font.pixelSize: 24 -- cgit v1.2.3