1 /* This script file handles the game logic */
2 .import QtQuick.LocalStorage 2.0 as Sql
6 var maxIndex = maxColumn * maxRow;
7 var board = new Array(maxIndex);
12 //Index function used instead of a 2D array
13 function index(column, row) {
14 return column + (row * maxColumn);
17 function startNewGame() {
18 //Delete blocks from previous game
19 for (var i = 0; i < maxIndex; i++) {
24 //Calculate board size
25 maxColumn = Math.floor(gameCanvas.width / gameCanvas.blockSize);
26 maxRow = Math.floor(gameCanvas.height / gameCanvas.blockSize);
27 maxIndex = maxRow * maxColumn;
30 nameInputDialog.hide();
34 board = new Array(maxIndex);
36 for (var column = 0; column < maxColumn; column++) {
37 for (var row = 0; row < maxRow; row++) {
38 board[index(column, row)] = null;
39 createBlock(column, row);
43 gameDuration = new Date();
46 function createBlock(column, row) {
47 if (component == null)
48 component = Qt.createComponent("content/BoomBlock.qml");
50 // Note that if Block.qml was not a local file, component.status would be
51 // Loading and we should wait for the component's statusChanged() signal to
52 // know when the file is downloaded and ready before calling createObject().
53 if (component.status == Component.Ready) {
54 var dynamicObject = component.createObject(gameCanvas);
55 if (dynamicObject == null) {
56 console.log("error creating block");
57 console.log(component.errorString());
60 dynamicObject.type = Math.floor(Math.random() * 3);
61 dynamicObject.x = column * gameCanvas.blockSize;
62 dynamicObject.y = row * gameCanvas.blockSize;
63 dynamicObject.width = gameCanvas.blockSize;
64 dynamicObject.height = gameCanvas.blockSize;
65 dynamicObject.spawned = true;
66 board[index(column, row)] = dynamicObject;
68 console.log("error loading block component");
69 console.log(component.errorString());
75 var fillFound; //Set after a floodFill call to the number of blocks found
76 var floodBoard; //Set to 1 if the floodFill reaches off that node
78 function handleClick(xPos, yPos) {
79 var column = Math.floor(xPos / gameCanvas.blockSize);
80 var row = Math.floor(yPos / gameCanvas.blockSize);
81 if (column >= maxColumn || column < 0 || row >= maxRow || row < 0)
83 if (board[index(column, row)] == null)
85 //If it's a valid block, remove it and all connected (does nothing if it's not connected)
86 floodFill(column, row, -1);
89 gameCanvas.score += (fillFound - 1) * (fillFound - 1);
94 function floodFill(column, row, type) {
95 if (board[index(column, row)] == null)
100 type = board[index(column, row)].type;
102 //Flood fill initialization
104 floodBoard = new Array(maxIndex);
106 if (column >= maxColumn || column < 0 || row >= maxRow || row < 0)
108 if (floodBoard[index(column, row)] == 1 || (!first && type != board[index(column, row)].type))
110 floodBoard[index(column, row)] = 1;
111 floodFill(column + 1, row, type);
112 floodFill(column - 1, row, type);
113 floodFill(column, row + 1, type);
114 floodFill(column, row - 1, type);
115 if (first == true && fillFound == 0)
116 return; //Can't remove single blocks
117 board[index(column, row)].dying = true;
118 board[index(column, row)] = null;
122 function shuffleDown() {
124 for (var column = 0; column < maxColumn; column++) {
126 for (var row = maxRow - 1; row >= 0; row--) {
127 if (board[index(column, row)] == null) {
131 var obj = board[index(column, row)];
132 obj.y = (row + fallDist) * gameCanvas.blockSize;
133 board[index(column, row + fallDist)] = obj;
134 board[index(column, row)] = null;
141 for (column = 0; column < maxColumn; column++) {
142 if (board[index(column, maxRow - 1)] == null) {
146 for (row = 0; row < maxRow; row++) {
147 obj = board[index(column, row)];
150 obj.x = (column - fallDist) * gameCanvas.blockSize;
151 board[index(column - fallDist, row)] = obj;
152 board[index(column, row)] = null;
160 function victoryCheck() {
162 //Award bonus points if no blocks left
163 var deservesBonus = true;
164 for (var column = maxColumn - 1; column >= 0; column--)
165 if (board[index(column, maxRow - 1)] != null)
166 deservesBonus = false;
168 gameCanvas.score += 500;
171 //Check whether game has finished
172 if (deservesBonus || !(floodMoveCheck(0, maxRow - 1, -1))) {
173 gameDuration = new Date() - gameDuration;
174 nameInputDialog.showWithInput("You won! Please enter your name: ");
179 //only floods up and right, to see if it can find adjacent same-typed blocks
180 function floodMoveCheck(column, row, type) {
181 if (column >= maxColumn || column < 0 || row >= maxRow || row < 0)
183 if (board[index(column, row)] == null)
185 var myType = board[index(column, row)].type;
188 return floodMoveCheck(column + 1, row, myType) || floodMoveCheck(column, row - 1, board[index(column, row)].type);
192 function saveHighScore(name) {
196 var db = Sql.LocalStorage.openDatabaseSync("SameGameScores", "1.0", "Local SameGame High Scores", 100);
197 var dataStr = "INSERT INTO Scores VALUES(?, ?, ?, ?)";
198 var data = [name, gameCanvas.score, maxColumn + "x" + maxRow, Math.floor(gameDuration / 1000)];
199 db.transaction(function(tx) {
200 tx.executeSql('CREATE TABLE IF NOT EXISTS Scores(name TEXT, score NUMBER, gridSize TEXT, time NUMBER)');
201 tx.executeSql(dataStr, data);
203 var rs = tx.executeSql('SELECT * FROM Scores WHERE gridSize = "12x17" ORDER BY score desc LIMIT 10');
204 var r = "\nHIGH SCORES for a standard sized grid\n\n"
205 for (var i = 0; i < rs.rows.length; i++) {
206 r += (i + 1) + ". " + rs.rows.item(i).name + ' got ' + rs.rows.item(i).score + ' points in ' + rs.rows.item(i).time + ' seconds.\n';
214 function sendHighScore(name) {
215 var postman = new XMLHttpRequest()
216 var postData = "name=" + name + "&score=" + gameCanvas.score + "&gridSize=" + maxColumn + "x" + maxRow + "&time=" + Math.floor(gameDuration / 1000);
217 postman.open("POST", scoresURL, true);
218 postman.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
219 postman.onreadystatechange = function() {
220 if (postman.readyState == postman.DONE) {
221 dialog.show("Your score has been uploaded.");
224 postman.send(postData);