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