Update more examples to QtQuick 2.0
[profile/ivi/qtdeclarative.git] / examples / declarative / snake / content / snake.js
1
2 var snake = new Array;
3 var board = new Array;
4 var links = new Array;
5 var scheduledDirections = new Array;
6 var numRows = 1;
7 var numColumns = 1;
8 var linkComponent = Qt.createComponent("Link.qml");
9 var cookieComponent = Qt.createComponent("Cookie.qml");
10 var cookie;
11 var linksToGrow = 0;
12 var linksToDie = 0;
13 var waitForCookie = 0;
14 var growType = 0;
15 var skullMovementsBeforeDirectionChange = 0;
16
17
18 function rand(n)
19 {
20   return (Math.floor(Math.random() * n));
21 }
22
23 function scheduleDirection(dir)
24 {
25     if (state == "starting") {
26         direction = dir;
27         headDirection = direction;
28         head.rotation = headDirection;
29     } else if (state == "running"){
30         direction = dir;
31         if(scheduledDirections[scheduledDirections.length-1]!=direction)
32             scheduledDirections.push(direction);
33     }
34 }
35
36 function startNewGame()
37 {
38     if (state == "starting") {
39         return;
40     }
41
42     if (activeGame) {
43         endGame();
44         startNewGameTimer.running = true;
45         return;
46     }
47
48     state = "starting";
49
50     numRows = numRowsAvailable;
51     numColumns = numColumnsAvailable;
52     board = new Array(numRows * numColumns);
53     snake = new Array;
54     scheduledDirections = new Array;
55     growType = 0;
56
57     skull.z = numRows * numColumns + 1;
58
59     for (var i = 0; i < numRows * numColumns; ++i) {
60         if (i < links.length) {
61             var link = links[i];
62             link.spawned = false;
63             link.dying = false;
64         } else {
65             if(linkComponent.status != Component.Ready) {
66                 if(linkComponent.status == Component.Error) 
67                     console.log(linkComponent.errorString());
68                 else
69                     console.log("Still loading linkComponent");
70                 continue;//TODO: Better error handling?
71             }
72             var link = linkComponent.createObject(playfield);
73             link.z = numRows * numColumns + 1 - i;
74             link.type = i == 0 ? 2 : 0;
75             link.spawned = false;
76             link.dying = false;
77             links.push(link);
78         }
79     }
80
81     head = links[0];
82     snake.push(head);
83     head.row = numRows/2 -1;
84     head.column = numColumns/2 -1;
85     head.spawned = true;
86
87     linksToGrow = 5;
88     linksToDie = 0;
89     waitForCookie = 5;
90     score = 0;
91     startHeartbeatTimer.running = true;
92 }
93
94 function endGame()
95 {
96     activeGame = false;
97     for(var i in snake)
98         snake[i].dying = true;
99     if (cookie) {
100         cookie.dying = true;
101         cookie = 0;
102     }
103     lastScore = score;
104     highScores.saveScore(lastScore);
105     state = "";
106 }
107
108 function move() {
109
110     if (!head)
111         return;
112
113     var dir = direction;
114
115     if (scheduledDirections.length) {
116         dir = scheduledDirections.shift();
117     }
118
119     if (state == "starting") {
120         var turn = (dir - headDirection);
121         head.rotation += turn == -3 ? 1 : (turn == 3 ? -1 : turn );
122         headDirection = dir;
123         return;
124     }
125
126     var row = head.row;
127     var column = head.column;
128
129     if (dir == 0) {
130         row = row - 1;
131     } else if (dir == 1) {
132         column = column + 1
133     } else if (dir == 2) {
134         row = row + 1;
135     } else if (dir == 3) {
136         column = column - 1;
137     }
138
139     //validate the new position
140     if (row < 0 || row >= numRows
141         || column < 0 || column >= numColumns
142         || (row == skull.row && column == skull.column)
143         || !isFree(row, column)) {
144         var turn = (dir - headDirection);
145         head.rotation += turn == -3 ? 1 : (turn == 3 ? -1 : turn );
146         headDirection = dir;
147         endGame();
148         return;
149     }
150
151     var newLink;
152     if (linksToGrow > 0) {
153         --linksToGrow;
154         newLink = links[snake.length];
155         newLink.spawned = false;
156         newLink.rotation = snake[snake.length-1].rotation;
157         newLink.type = growType;
158         newLink.dying = false;
159         snake.push(newLink);
160     } else {
161         var lastLink = snake[snake.length-1];
162         board[lastLink.row * numColumns + lastLink.column] = undefined;
163     }
164
165     if (waitForCookie > 0) {
166         if (--waitForCookie == 0)
167             createCookie(cookie? (cookie.value+1) : 1);
168     }
169
170     for (var i = snake.length-1; i > 0; --i) {
171         snake[i].row = snake[i-1].row;
172         snake[i].column = snake[i-1].column;
173         snake[i].rotation = snake[i-1].rotation;
174     }
175
176     if (newLink) {
177         newLink.spawned = true;
178     }
179
180     // move the head
181     head.row = row;
182     head.column = column;
183     board[row * numColumns + column] = head;
184
185     var turn = (dir - headDirection);
186     head.rotation += turn == -3 ? 1 : (turn == 3 ? -1 : turn );
187     headDirection = dir;
188
189     var value = testCookie(row, column);
190     if (value > 0) {
191         linksToGrow += value;
192         score += value;
193     }
194 }
195
196 function isFree(row, column)
197 {
198     return board[row * numColumns + column] == undefined;
199 }
200
201 function isHead(row, column)
202 {
203     return head.column == column && head.row == row;
204 }
205
206 function testCookie(row, column)
207 {
208     if (cookie && !cookie.dying && cookie.row == row && cookie.column == column) {
209         var value = cookie.value;
210         waitForCookie = value;
211         growType = snake[snake.length-1].type == 1 ? 0 : 1;
212         cookie.dying = true;
213         cookie.z = numRows * numColumns + 2;
214         return value;
215     }
216     return 0;
217 }
218
219 function moveSkull()
220 {
221
222     if (linksToDie > 0) {
223         --linksToDie;
224         var link = snake.pop();
225         link.dying = true;
226         board[link.row * numColumns + link.column] = undefined;
227         if (score > 0)
228             --score;
229         if (snake.length == 0) {
230             endGame();
231             return;
232         }
233     }
234
235     var row = skull.row;
236     var column = skull.column;
237     if (isHead(row, column)) {
238         endGame();
239         return;
240     }
241     row +=  skull.verticalMovement;
242     column += skull.horizontalMovement;
243
244     var attempts = 4;
245
246     while (skullMovementsBeforeDirectionChange == 0 || row < 0 || row >= numRows
247         || column < 0 || column >= numColumns
248         || (!isFree(row, column) && !isHead(row, column))) {
249         var d = rand(8);
250         skull.verticalMovement = 0;
251         skull.horizontalMovement = 0;
252         skullMovementsBeforeDirectionChange = rand(20)+1;
253         if (d == 0) {
254             skull.verticalMovement = -1
255         } else if (d == 1) {
256             skull.horizontalMovement = -1;
257         } else if (d == 2) {
258             skull.verticalMovement = 1
259         } else if (d == 3){
260             skull.horizontalMovement = 1;
261         } else if (cookie) {
262             var rd = cookie.row - skull.row;
263             var rc = cookie.column - skull.column;
264             if (Math.abs(rd) > Math.abs(rc)) {
265                 skull.verticalMovement = rd > 0 ? 1 : -1;
266                 skullMovementsBeforeDirectionChange = Math.abs(rd);
267             } else {
268                 skull.horizontalMovement= rc > 0 ? 1 : -1;
269                 skullMovementsBeforeDirectionChange = Math.abs(rc);
270             }
271         }
272         row = skull.row + skull.verticalMovement;
273         column = skull.column + skull.horizontalMovement;
274         if (--attempts == 0)
275             return;
276     }
277
278     skull.row = row;
279     skull.column = column;
280     --skullMovementsBeforeDirectionChange;
281     var value = testCookie(row, column);
282     if (value > 0)
283         linksToDie += value/2;
284
285     if (isHead(row, column))
286         endGame();
287 }
288
289 function createCookie(value) {
290     if (numRows * numColumns - snake.length < 10)
291         return;
292
293     var column = rand(numColumns);
294     var row = rand(numRows);
295     while (!isFree(row, column)) {
296         column++;
297         if (column == numColumns) {
298             column = 0;
299             row++;
300             if (row == numRows)
301                 row = 0;
302         }
303     }
304
305     if(cookieComponent.status != Component.Ready) {
306         if(cookieComponent.status == Component.Error)
307             console.log(cookieComponent.errorString());
308         else
309             console.log("Still loading cookieComponent");
310         return;//TODO: Better error handling?
311     }
312     cookie = cookieComponent.createObject(head.parent);
313     cookie.value = value;
314     cookie.row = row;
315     cookie.column = column;
316 }