From d7aaf421fc38c257785d005498c6332e9ef7673c Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 18 May 2011 21:35:51 +0200 Subject: missing files --- EffectSampleSlide.qml | 4 +- VSyncSlide.qml | 6 +- images/landscape.png | Bin 0 -> 386514 bytes images/ogre.png | Bin 0 -> 184116 bytes images/particle.png | Bin 0 -> 861 bytes images/render-threading.png | Bin 0 -> 34324 bytes samegame/SameGame.qml | 193 +++++++++++++++++++ samegame/SamegameCore/BoomBlock.qml | 112 +++++++++++ samegame/SamegameCore/Button.qml | 75 ++++++++ samegame/SamegameCore/Dialog.qml | 80 ++++++++ samegame/SamegameCore/pics/background.png | Bin 0 -> 313930 bytes samegame/SamegameCore/pics/blueStone.png | Bin 0 -> 3054 bytes samegame/SamegameCore/pics/greenStone.png | Bin 0 -> 2932 bytes samegame/SamegameCore/pics/particle.png | Bin 0 -> 861 bytes samegame/SamegameCore/pics/redStone.png | Bin 0 -> 2902 bytes samegame/SamegameCore/pics/yellowStone.png | Bin 0 -> 3056 bytes samegame/SamegameCore/qmldir | 3 + samegame/SamegameCore/samegame.js | 288 +++++++++++++++++++++++++++++ samegame/qmldir | 1 + 19 files changed, 757 insertions(+), 5 deletions(-) create mode 100644 images/landscape.png create mode 100644 images/ogre.png create mode 100644 images/particle.png create mode 100644 images/render-threading.png create mode 100644 samegame/SameGame.qml create mode 100644 samegame/SamegameCore/BoomBlock.qml create mode 100644 samegame/SamegameCore/Button.qml create mode 100644 samegame/SamegameCore/Dialog.qml create mode 100644 samegame/SamegameCore/pics/background.png create mode 100644 samegame/SamegameCore/pics/blueStone.png create mode 100644 samegame/SamegameCore/pics/greenStone.png create mode 100644 samegame/SamegameCore/pics/particle.png create mode 100644 samegame/SamegameCore/pics/redStone.png create mode 100644 samegame/SamegameCore/pics/yellowStone.png create mode 100644 samegame/SamegameCore/qmldir create mode 100755 samegame/SamegameCore/samegame.js create mode 100644 samegame/qmldir diff --git a/EffectSampleSlide.qml b/EffectSampleSlide.qml index 123d243..c71d705 100644 --- a/EffectSampleSlide.qml +++ b/EffectSampleSlide.qml @@ -9,8 +9,8 @@ Slide { ] contentWidth: parent.width / 3 CodeSection { - x: parent.width / 3 - width: 2 * parent.width / 3 + x: parent.width / 3 + parent.baseFontSize + width: 2 * parent.width / 3 - parent.baseFontSize text: " ShaderEffectItem { width: 180 diff --git a/VSyncSlide.qml b/VSyncSlide.qml index df9aa61..4432bd8 100644 --- a/VSyncSlide.qml +++ b/VSyncSlide.qml @@ -12,8 +12,8 @@ Slide { // Vsync animations / flickable.. Flickable { id: vsyncFlickable - x: parent.width / 2 - width: parent.width / 2 + x: parent.width / 2 + parent.baseFontSize + width: parent.width / 2 - parent.baseFontSize height: parent.height clip: true @@ -33,7 +33,7 @@ Slide { // Vsync animations / flickable.. Text { font.pixelSize: parent.baseFontSize * 0.3 color: "white" - text: "Must be viewed experienced first hand, not via video capture" + text: "Must be experienced first hand, not via video capture" anchors.top: vsyncFlickable.bottom anchors.horizontalCenter: vsyncFlickable.horizontalCenter } diff --git a/images/landscape.png b/images/landscape.png new file mode 100644 index 0000000..404c0d4 Binary files /dev/null and b/images/landscape.png differ diff --git a/images/ogre.png b/images/ogre.png new file mode 100644 index 0000000..cb36a41 Binary files /dev/null and b/images/ogre.png differ diff --git a/images/particle.png b/images/particle.png new file mode 100644 index 0000000..5c83896 Binary files /dev/null and b/images/particle.png differ diff --git a/images/render-threading.png b/images/render-threading.png new file mode 100644 index 0000000..27cb088 Binary files /dev/null and b/images/render-threading.png differ diff --git a/samegame/SameGame.qml b/samegame/SameGame.qml new file mode 100644 index 0000000..f6356ea --- /dev/null +++ b/samegame/SameGame.qml @@ -0,0 +1,193 @@ +/**************************************************************************** +** +** 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import Qt.labs.particles 2.0 +import "SamegameCore" +import "SamegameCore/samegame.js" as Logic + +Rectangle { + id: screen + width: 360; height: 640 + property bool inAnotherDemo: true //Samegame often is just plonked straight into other demos + + SystemPalette { id: activePalette } + + Item { + width: parent.width + anchors { top: parent.top; bottom: toolBar.top } + + Image { + id: background + anchors.fill: parent + source: "SamegameCore/pics/background.png" + fillMode: Image.PreserveAspectCrop + smooth: true + } + + 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; } + ColoredParticle { + system: particleSystem + particles: ["red"] + color: Qt.darker("red");//Actually want desaturated... + image: "SamegameCore/pics/particle.png" + colorVariation: 0.4 + alpha: 0.1 + } + ColoredParticle { + system: particleSystem + particles: ["green"] + color: Qt.darker("green");//Actually want desaturated... + image: "SamegameCore/pics/particle.png" + colorVariation: 0.4 + alpha: 0.1 + } + ColoredParticle { + system: particleSystem + particles: ["blue"] + color: Qt.darker("blue");//Actually want desaturated... + image: "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 + color: activePalette.window + anchors.bottom: screen.bottom + + Button { + id: newGameButton + anchors { left: parent.left; leftMargin: 3; verticalCenter: parent.verticalCenter } + text: "New Game" + onClicked: Logic.startNewGame() + } + + Button { + visible: !inAnotherDemo + text: "Quit" + anchors { left: newGameButton.right; leftMargin: 3; verticalCenter: parent.verticalCenter } + onClicked: screen.visible = false + } + + Text { + id: score + anchors { right: parent.right; rightMargin: 3; verticalCenter: parent.verticalCenter } + text: "Score: " + gameCanvas.score + font.bold: true + font.pixelSize: 24 + color: activePalette.windowText + } + } +} diff --git a/samegame/SamegameCore/BoomBlock.qml b/samegame/SamegameCore/BoomBlock.qml new file mode 100644 index 0000000..a7abbb7 --- /dev/null +++ b/samegame/SamegameCore/BoomBlock.qml @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import Qt.labs.particles 2.0 + +Item { + id: block + property bool dying: false + property bool spawned: false + property int type: 0 + + Behavior on x { + enabled: spawned; + SpringAnimation{ spring: 2; damping: 0.2 } + } + Behavior on y { + SpringAnimation{ spring: 2; damping: 0.2 } + } + + Image { + id: img + source: { + if(type == 0){ + "pics/redStone.png"; + } else if(type == 1) { + "pics/blueStone.png"; + } else { + "pics/greenStone.png"; + } + } + opacity: 0 + Behavior on opacity { NumberAnimation { duration: 200 } } + anchors.fill: parent + smooth: true + } + TrailEmitter { + id: particles + system: particleSystem + particle: { + if(type == 0){ + "red"; + } else if (type == 1) { + "blue"; + } else { + "green"; + } + } + anchors.fill: parent + + speed: DirectedVector{targetX: block.width/2; targetY: block.height/2; magnitude: -60; magnitudeVariation: 60} + shape: Ellipse{fill:true} + emitting: false; + particleDuration: 700; particleDurationVariation: 100 + particlesPerSecond: 1000 + maxParticles: 100 //only fires 0.1s bursts (still 2x old number, ColoredParticle wants less than 16000 max though) + particleSize: 28 + particleEndSize: 14 + } + + states: [ + State { + name: "AliveState"; when: spawned == true && dying == false + PropertyChanges { target: img; opacity: 1 } + }, + + State { + name: "DeathState"; when: dying == true + StateChangeScript { script: particles.pulse(0.1); } + PropertyChanges { target: img; opacity: 0 } + StateChangeScript { script: block.destroy(1000); } + } + ] +} diff --git a/samegame/SamegameCore/Button.qml b/samegame/SamegameCore/Button.qml new file mode 100644 index 0000000..8bcca5b --- /dev/null +++ b/samegame/SamegameCore/Button.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + id: container + + property string text: "Button" + + signal clicked + + width: buttonLabel.width + 20; height: buttonLabel.height + 20 + smooth: true + border { width: 1; color: Qt.darker(activePalette.button) } + radius: 8 + color: activePalette.button + + gradient: Gradient { + GradientStop { + position: 0.0 + color: { + if (mouseArea.pressed) + return activePalette.dark + else + return activePalette.light + } + } + GradientStop { position: 1.0; color: activePalette.button } + } + + MouseArea { id: mouseArea; anchors.fill: parent; onClicked: container.clicked() } + + Text { + id: buttonLabel; text: container.text; anchors.centerIn: container; color: activePalette.buttonText; font.pixelSize: 24 + } +} diff --git a/samegame/SamegameCore/Dialog.qml b/samegame/SamegameCore/Dialog.qml new file mode 100644 index 0000000..ee1b510 --- /dev/null +++ b/samegame/SamegameCore/Dialog.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + id: page + + property Item text: dialogText + property bool open: false + + signal closed + signal opened + function forceClose() { + if(!open) + return; //already closed + page.open = false; + page.closed(); + page.opacity = 0; + } + + function show(txt) { + page.open = true; + page.opened(); + dialogText.text = txt; + page.opacity = 1; + } + + width: dialogText.width + 20; height: dialogText.height + 20 + color: "white" + border.width: 1 + opacity: 0 + visible: opacity > 0 + Behavior on opacity { + NumberAnimation { duration: 1000 } + } + + Text { id: dialogText; anchors.centerIn: parent; text: "Hello World!" } + + MouseArea { anchors.fill: parent; onClicked: forceClose(); } +} + diff --git a/samegame/SamegameCore/pics/background.png b/samegame/SamegameCore/pics/background.png new file mode 100644 index 0000000..3734a27 Binary files /dev/null and b/samegame/SamegameCore/pics/background.png differ diff --git a/samegame/SamegameCore/pics/blueStone.png b/samegame/SamegameCore/pics/blueStone.png new file mode 100644 index 0000000..20e43c7 Binary files /dev/null and b/samegame/SamegameCore/pics/blueStone.png differ diff --git a/samegame/SamegameCore/pics/greenStone.png b/samegame/SamegameCore/pics/greenStone.png new file mode 100644 index 0000000..b568a19 Binary files /dev/null and b/samegame/SamegameCore/pics/greenStone.png differ diff --git a/samegame/SamegameCore/pics/particle.png b/samegame/SamegameCore/pics/particle.png new file mode 100644 index 0000000..5c83896 Binary files /dev/null and b/samegame/SamegameCore/pics/particle.png differ diff --git a/samegame/SamegameCore/pics/redStone.png b/samegame/SamegameCore/pics/redStone.png new file mode 100644 index 0000000..36b09a2 Binary files /dev/null and b/samegame/SamegameCore/pics/redStone.png differ diff --git a/samegame/SamegameCore/pics/yellowStone.png b/samegame/SamegameCore/pics/yellowStone.png new file mode 100644 index 0000000..b1ce762 Binary files /dev/null and b/samegame/SamegameCore/pics/yellowStone.png differ diff --git a/samegame/SamegameCore/qmldir b/samegame/SamegameCore/qmldir new file mode 100644 index 0000000..e17b1f5 --- /dev/null +++ b/samegame/SamegameCore/qmldir @@ -0,0 +1,3 @@ +BoomBlock BoomBlock.qml +Button Button.qml +Dialog Dialog.qml diff --git a/samegame/SamegameCore/samegame.js b/samegame/SamegameCore/samegame.js new file mode 100755 index 0000000..4c5cbe5 --- /dev/null +++ b/samegame/SamegameCore/samegame.js @@ -0,0 +1,288 @@ +/* This script file handles the game logic */ + +var maxColumn = 10; +var maxRow = 15; +var maxIndex = maxColumn*maxRow; +var board = new Array(maxIndex); +var blockSrc = "BoomBlock.qml"; +var scoresURL = ""; +var gameDuration; +var component = Qt.createComponent(blockSrc); +var highScoreBar = 0; + +// Index function used instead of a 2D array +function index(column, row) +{ + return column + row * maxColumn; +} + +function timeStr(msecs) +{ + var secs = Math.floor(msecs/1000); + var m = Math.floor(secs/60); + var ret = "" + m + "m " + (secs%60) + "s"; + return ret; +} + +function startNewGame() +{ + // Delete blocks from previous game + for (var i = 0; i < maxIndex; i++) { + if (board[i] != null) + board[i].destroy(); + } + + // Calculate board size + maxColumn = Math.floor(gameCanvas.width/gameCanvas.blockSize); + maxRow = Math.floor(gameCanvas.height/gameCanvas.blockSize); + maxIndex = maxRow * maxColumn; + + // Close dialogs + nameInputDialog.forceClose(); + dialog.forceClose(); + + // Initialize Board + board = new Array(maxIndex); + gameCanvas.score = 0; + for (var column = 0; column < maxColumn; column++) { + for (var row = 0; row < maxRow; row++) { + board[index(column, row)] = null; + createBlock(column, row); + } + } + gameDuration = new Date(); +} + +var fillFound; // Set after a floodFill call to the number of blocks found +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) +{ + var column = Math.floor(x/gameCanvas.blockSize); + var row = Math.floor(y/gameCanvas.blockSize); + if (column >= maxColumn || column < 0 || row >= maxRow || row < 0) + return; + if (board[index(column, row)] == null) + return; + // If it's a valid block, remove it and all connected (does nothing if it's not connected) + floodFill(column,row, -1); + if (fillFound <= 0) + return; + gameCanvas.score += (fillFound - 1) * (fillFound - 1); + shuffleDown(); + victoryCheck(); +} + +function floodFill(column,row,type) +{ + if (board[index(column, row)] == null) + return; + var first = false; + if (type == -1) { + first = true; + type = board[index(column,row)].type; + + // Flood fill initialization + fillFound = 0; + floodBoard = new Array(maxIndex); + } + if (column >= maxColumn || column < 0 || row >= maxRow || row < 0) + return; + if (floodBoard[index(column, row)] == 1 || (!first && type != board[index(column, row)].type)) + return; + floodBoard[index(column, row)] = 1; + floodFill(column + 1, row, type); + floodFill(column - 1, row, type); + floodFill(column, row + 1, type); + floodFill(column, row - 1, type); + if (first == true && fillFound == 0) + return; // Can't remove single blocks + board[index(column, row)].dying = true; + board[index(column, row)] = null; + fillFound += 1; +} + +function shuffleDown() +{ + // Fall down + for (var column = 0; column < maxColumn; column++) { + var fallDist = 0; + for (var row = maxRow - 1; row >= 0; row--) { + if (board[index(column,row)] == null) { + fallDist += 1; + } else { + if (fallDist > 0) { + var obj = board[index(column, row)]; + obj.y = (row + fallDist) * gameCanvas.blockSize; + board[index(column, row + fallDist)] = obj; + board[index(column, row)] = null; + } + } + } + } + // Fall to the left + fallDist = 0; + for (column = 0; column < maxColumn; column++) { + if (board[index(column, maxRow - 1)] == null) { + fallDist += 1; + } else { + if (fallDist > 0) { + for (row = 0; row < maxRow; row++) { + obj = board[index(column, row)]; + if (obj == null) + continue; + obj.x = (column - fallDist) * gameCanvas.blockSize; + board[index(column - fallDist,row)] = obj; + board[index(column, row)] = null; + } + } + } + } +} + +function victoryCheck() +{ + // Awards bonuses for no blocks left + var deservesBonus = true; + for (var column = maxColumn - 1; column >= 0; column--) + if (board[index(column, maxRow - 1)] != null) + deservesBonus = false; + if (deservesBonus) + gameCanvas.score += 500; + // Checks for game over + if (deservesBonus || !(floodMoveCheck(0, maxRow - 1, -1))) { + gameDuration = new Date() - gameDuration; + 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.text.opacity = 0; // Just a spacer + }else{ + dialog.show("You won!"); + } + } +} + +// Only floods up and right, to see if it can find adjacent same-typed blocks +function floodMoveCheck(column, row, type) +{ + if (column >= maxColumn || column < 0 || row >= maxRow || row < 0) + return false; + if (board[index(column, row)] == null) + return false; + var myType = board[index(column, row)].type; + if (type == myType) + return true; + return floodMoveCheck(column + 1, row, myType) || + floodMoveCheck(column, row - 1, board[index(column, row)].type); +} + +function createBlock(column,row) +{ + // Note that we don't wait for the component to become ready. This will + // 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){ + var dynamicObject = component.createObject(gameCanvas, + {"type": Math.floor(Math.random() * 3), + "x": column*gameCanvas.blockSize, + "width": gameCanvas.blockSize, + "height": gameCanvas.blockSize}); + if(dynamicObject == null){ + console.log("error creating block"); + console.log(component.errorString()); + return false; + } + dynamicObject.y = row*gameCanvas.blockSize; + dynamicObject.spawned = true; + + board[index(column,row)] = dynamicObject; + }else{ + console.log("error loading block component"); + console.log(component.errorString()); + return false; + } + return true; +} + +function initHighScoreBar() +{ + if(scoresURL != "") + return true;//don't query remote scores + var db = openDatabaseSync( + "SameGameScores", + "1.0", + "Local SameGame High Scores", + 100 + ); + db.transaction( + function(tx) { + tx.executeSql('CREATE TABLE IF NOT EXISTS Scores(name TEXT, score NUMBER, gridSize TEXT, time NUMBER)'); + // Only show results for the current grid size + var rs = tx.executeSql('SELECT * FROM Scores WHERE gridSize = "' + + maxColumn + "x" + maxRow + '" ORDER BY score desc LIMIT 10'); + if(rs.rows.length < 10) + highScoreBar = 0; + else + highScoreBar = rs.rows.item(rs.rows.length - 1).score; + } + ); +} + +function saveHighScore(name) +{ + if (scoresURL != "") + sendHighScore(name); + // Offline storage + var db = openDatabaseSync( + "SameGameScores", + "1.0", + "Local SameGame High Scores", + 100 + ); + var dataStr = "INSERT INTO Scores VALUES(?, ?, ?, ?)"; + var data = [ + name, + gameCanvas.score, + maxColumn + "x" + maxRow, + Math.floor(gameDuration / 1000) + ]; + db.transaction( + function(tx) { + tx.executeSql('CREATE TABLE IF NOT EXISTS Scores(name TEXT, score NUMBER, gridSize TEXT, time NUMBER)'); + tx.executeSql(dataStr, data); + + // Only show results for the current grid size + var rs = tx.executeSql('SELECT * FROM Scores WHERE gridSize = "' + + maxColumn + "x" + maxRow + '" ORDER BY score desc LIMIT 10'); + var r = "\nHIGH SCORES for this grid size\n\n" + for (var i = 0; i < rs.rows.length; i++) { + r += (i+1) + ". " + rs.rows.item(i).name + ' got ' + + rs.rows.item(i).score + ' points in ' + + rs.rows.item(i).time + ' seconds.\n'; + } + if(rs.rows.length == 10) + highScoreBar = rs.rows.item(9).score; + dialog.show(r); + } + ); +} + +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/samegame/qmldir b/samegame/qmldir new file mode 100644 index 0000000..1b74f7a --- /dev/null +++ b/samegame/qmldir @@ -0,0 +1 @@ +SameGame 1.0 SameGame.qml -- cgit v1.2.3