1 /* This script file handles the game logic */
4 var maxIndex = maxColumn * maxRow;
5 var board = new Array(maxIndex);
10 //Index function used instead of a 2D array
11 function index(column, row) {
12 return column + (row * maxColumn);
15 function startNewGame() {
16 //Delete blocks from previous game
17 for (var i = 0; i < maxIndex; i++) {
22 //Calculate board size
23 maxColumn = Math.floor(gameCanvas.width / gameCanvas.blockSize);
24 maxRow = Math.floor(gameCanvas.height / gameCanvas.blockSize);
25 maxIndex = maxRow * maxColumn;
28 nameInputDialog.hide();
32 board = new Array(maxIndex);
34 for (var column = 0; column < maxColumn; column++) {
35 for (var row = 0; row < maxRow; row++) {
36 board[index(column, row)] = null;
37 createBlock(column, row);
41 gameDuration = new Date();
44 function createBlock(column, row) {
45 if (component == null)
46 component = Qt.createComponent("content/BoomBlock.qml");
48 // Note that if Block.qml was not a local file, component.status would be
49 // Loading and we should wait for the component's statusChanged() signal to
50 // know when the file is downloaded and ready before calling createObject().
51 if (component.status == Component.Ready) {
52 var dynamicObject = component.createObject(gameCanvas);
53 if (dynamicObject == null) {
54 console.log("error creating block");
55 console.log(component.errorString());
58 dynamicObject.type = Math.floor(Math.random() * 3);
59 dynamicObject.x = column * gameCanvas.blockSize;
60 dynamicObject.y = row * gameCanvas.blockSize;
61 dynamicObject.width = gameCanvas.blockSize;
62 dynamicObject.height = gameCanvas.blockSize;
63 dynamicObject.spawned = true;
64 board[index(column, row)] = dynamicObject;
66 console.log("error loading block component");
67 console.log(component.errorString());
73 var fillFound; //Set after a floodFill call to the number of blocks found
74 var floodBoard; //Set to 1 if the floodFill reaches off that node
76 function handleClick(xPos, yPos) {
77 var column = Math.floor(xPos / gameCanvas.blockSize);
78 var row = Math.floor(yPos / gameCanvas.blockSize);
79 if (column >= maxColumn || column < 0 || row >= maxRow || row < 0)
81 if (board[index(column, row)] == null)
83 //If it's a valid block, remove it and all connected (does nothing if it's not connected)
84 floodFill(column, row, -1);
87 gameCanvas.score += (fillFound - 1) * (fillFound - 1);
92 function floodFill(column, row, type) {
93 if (board[index(column, row)] == null)
98 type = board[index(column, row)].type;
100 //Flood fill initialization
102 floodBoard = new Array(maxIndex);
104 if (column >= maxColumn || column < 0 || row >= maxRow || row < 0)
106 if (floodBoard[index(column, row)] == 1 || (!first && type != board[index(column, row)].type))
108 floodBoard[index(column, row)] = 1;
109 floodFill(column + 1, row, type);
110 floodFill(column - 1, row, type);
111 floodFill(column, row + 1, type);
112 floodFill(column, row - 1, type);
113 if (first == true && fillFound == 0)
114 return; //Can't remove single blocks
115 board[index(column, row)].dying = true;
116 board[index(column, row)] = null;
120 function shuffleDown() {
122 for (var column = 0; column < maxColumn; column++) {
124 for (var row = maxRow - 1; row >= 0; row--) {
125 if (board[index(column, row)] == null) {
129 var obj = board[index(column, row)];
130 obj.y = (row + fallDist) * gameCanvas.blockSize;
131 board[index(column, row + fallDist)] = obj;
132 board[index(column, row)] = null;
139 for (column = 0; column < maxColumn; column++) {
140 if (board[index(column, maxRow - 1)] == null) {
144 for (row = 0; row < maxRow; row++) {
145 obj = board[index(column, row)];
148 obj.x = (column - fallDist) * gameCanvas.blockSize;
149 board[index(column - fallDist, row)] = obj;
150 board[index(column, row)] = null;
158 function victoryCheck() {
160 //Award bonus points if no blocks left
161 var deservesBonus = true;
162 for (var column = maxColumn - 1; column >= 0; column--)
163 if (board[index(column, maxRow - 1)] != null)
164 deservesBonus = false;
166 gameCanvas.score += 500;
169 //Check whether game has finished
170 if (deservesBonus || !(floodMoveCheck(0, maxRow - 1, -1))) {
171 gameDuration = new Date() - gameDuration;
172 nameInputDialog.showWithInput("You won! Please enter your name: ");
177 //only floods up and right, to see if it can find adjacent same-typed blocks
178 function floodMoveCheck(column, row, type) {
179 if (column >= maxColumn || column < 0 || row >= maxRow || row < 0)
181 if (board[index(column, row)] == null)
183 var myType = board[index(column, row)].type;
186 return floodMoveCheck(column + 1, row, myType) || floodMoveCheck(column, row - 1, board[index(column, row)].type);
190 function saveHighScore(name) {
194 var db = openDatabaseSync("SameGameScores", "1.0", "Local SameGame High Scores", 100);
195 var dataStr = "INSERT INTO Scores VALUES(?, ?, ?, ?)";
196 var data = [name, gameCanvas.score, maxColumn + "x" + maxRow, Math.floor(gameDuration / 1000)];
197 db.transaction(function(tx) {
198 tx.executeSql('CREATE TABLE IF NOT EXISTS Scores(name TEXT, score NUMBER, gridSize TEXT, time NUMBER)');
199 tx.executeSql(dataStr, data);
201 var rs = tx.executeSql('SELECT * FROM Scores WHERE gridSize = "12x17" ORDER BY score desc LIMIT 10');
202 var r = "\nHIGH SCORES for a standard sized grid\n\n"
203 for (var i = 0; i < rs.rows.length; i++) {
204 r += (i + 1) + ". " + rs.rows.item(i).name + ' got ' + rs.rows.item(i).score + ' points in ' + rs.rows.item(i).time + ' seconds.\n';
212 function sendHighScore(name) {
213 var postman = new XMLHttpRequest()
214 var postData = "name=" + name + "&score=" + gameCanvas.score + "&gridSize=" + maxColumn + "x" + maxRow + "&time=" + Math.floor(gameDuration / 1000);
215 postman.open("POST", scoresURL, true);
216 postman.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
217 postman.onreadystatechange = function() {
218 if (postman.readyState == postman.DONE) {
219 dialog.show("Your score has been uploaded.");
222 postman.send(postData);