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