ad4d39d7b1147ce76a0fae2d331f8d67ac10d635
[profile/ivi/qtdeclarative.git] / examples / tutorials / samegame / samegame4 / content / samegame.js
1 /* This script file handles the game logic */
2 .import QtQuick.LocalStorage 2.0 as Sql
3
4 var maxColumn = 10;
5 var maxRow = 15;
6 var maxIndex = maxColumn * maxRow;
7 var board = new Array(maxIndex);
8 var component;
9 var scoresURL = "";
10 var gameDuration;
11
12 //Index function used instead of a 2D array
13 function index(column, row) {
14     return column + (row * maxColumn);
15 }
16
17 function startNewGame() {
18     //Delete blocks from previous game
19     for (var i = 0; i < maxIndex; i++) {
20         if (board[i] != null)
21             board[i].destroy();
22     }
23
24     //Calculate board size
25     maxColumn = Math.floor(gameCanvas.width / gameCanvas.blockSize);
26     maxRow = Math.floor(gameCanvas.height / gameCanvas.blockSize);
27     maxIndex = maxRow * maxColumn;
28
29     //Close dialogs
30     nameInputDialog.hide();
31     dialog.hide();
32
33     //Initialize Board
34     board = new Array(maxIndex);
35     gameCanvas.score = 0;
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);
40         }
41     }
42
43     gameDuration = new Date();
44 }
45
46 function createBlock(column, row) {
47     if (component == null)
48         component = Qt.createComponent("content/BoomBlock.qml");
49
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());
58             return false;
59         }
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;
67     } else {
68         console.log("error loading block component");
69         console.log(component.errorString());
70         return false;
71     }
72     return true;
73 }
74
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
77
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)
82         return;
83     if (board[index(column, row)] == null)
84         return;
85     //If it's a valid block, remove it and all connected (does nothing if it's not connected)
86     floodFill(column, row, -1);
87     if (fillFound <= 0)
88         return;
89     gameCanvas.score += (fillFound - 1) * (fillFound - 1);
90     shuffleDown();
91     victoryCheck();
92 }
93
94 function floodFill(column, row, type) {
95     if (board[index(column, row)] == null)
96         return;
97     var first = false;
98     if (type == -1) {
99         first = true;
100         type = board[index(column, row)].type;
101
102         //Flood fill initialization
103         fillFound = 0;
104         floodBoard = new Array(maxIndex);
105     }
106     if (column >= maxColumn || column < 0 || row >= maxRow || row < 0)
107         return;
108     if (floodBoard[index(column, row)] == 1 || (!first && type != board[index(column, row)].type))
109         return;
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;
119     fillFound += 1;
120 }
121
122 function shuffleDown() {
123     //Fall down
124     for (var column = 0; column < maxColumn; column++) {
125         var fallDist = 0;
126         for (var row = maxRow - 1; row >= 0; row--) {
127             if (board[index(column, row)] == null) {
128                 fallDist += 1;
129             } else {
130                 if (fallDist > 0) {
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;
135                 }
136             }
137         }
138     }
139     //Fall to the left
140     fallDist = 0;
141     for (column = 0; column < maxColumn; column++) {
142         if (board[index(column, maxRow - 1)] == null) {
143             fallDist += 1;
144         } else {
145             if (fallDist > 0) {
146                 for (row = 0; row < maxRow; row++) {
147                     obj = board[index(column, row)];
148                     if (obj == null)
149                         continue;
150                     obj.x = (column - fallDist) * gameCanvas.blockSize;
151                     board[index(column - fallDist, row)] = obj;
152                     board[index(column, row)] = null;
153                 }
154             }
155         }
156     }
157 }
158
159 //![3]
160 function victoryCheck() {
161 //![3]
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;
167     if (deservesBonus)
168         gameCanvas.score += 500;
169
170 //![4]
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: ");
175     }
176 }
177 //![4]
178
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)
182         return false;
183     if (board[index(column, row)] == null)
184         return false;
185     var myType = board[index(column, row)].type;
186     if (type == myType)
187         return true;
188     return floodMoveCheck(column + 1, row, myType) || floodMoveCheck(column, row - 1, board[index(column, row)].type);
189 }
190
191 //![2]
192 function saveHighScore(name) {
193     if (scoresURL != "")
194         sendHighScore(name);
195
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);
202
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';
207         }
208         dialog.show(r);
209     });
210 }
211 //![2]
212
213 //![1]
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.");
222         }
223     }
224     postman.send(postData);
225 }
226 //![1]