var snake = new Array; var board = new Array; var links = new Array; var scheduledDirections = new Array; var numRows = 1; var numColumns = 1; var linkComponent = Qt.createComponent("content/Link.qml"); // XXX should resolve relative to script, not component var cookieComponent = Qt.createComponent("content/Cookie.qml"); var cookie; var linksToGrow = 0; var linksToDie = 0; var waitForCookie = 0; var growType = 0; var skullMovementsBeforeDirectionChange = 0; function rand(n) { return (Math.floor(Math.random() * n)); } function scheduleDirection(dir) { direction = dir; if(scheduledDirections[scheduledDirections.length-1]!=direction) scheduledDirections.push(direction); } function startNewGame() { if (state == "starting") return; if (heartbeat.running) { endGame(); startNewGameTimer.running = true; state = ""; return; } state = "starting"; numRows = numRowsAvailable; numColumns = numColumnsAvailable; board = new Array(numRows * numColumns); snake = new Array; scheduledDirections = new Array; growType = 0; skull.z = numRows * numColumns + 1; for (var i = 0; i < numRows * numColumns; ++i) { if (i < links.length) { var link = links[i]; link.spawned = false; link.dying = false; } else { if(linkComponent.status != Component.Ready) { if(linkComponent.status == Component.Error) console.log(linkComponent.errorString()); else console.log("Still loading linkComponent"); continue;//TODO: Better error handling? } var link = linkComponent.createObject(playfield); link.z = numRows * numColumns + 1 - i; link.type = i == 0 ? 2 : 0; link.spawned = false; link.dying = false; links.push(link); } } head = links[0]; snake.push(head); head.row = numRows/2 -1; head.column = numColumns/2 -1; head.spawned = true; linksToGrow = 5; linksToDie = 0; waitForCookie = 5; score = 0; startHeartbeatTimer.running = true; } function endGame() { heartbeat.running = false; for(var i in snake) snake[i].dying = true; if (cookie) { cookie.dying = true; cookie = 0; } lastScore = score; highScores.saveScore(lastScore); state = ""; } function move() { if (!head) return; var dir = direction; if (scheduledDirections.length) { dir = scheduledDirections.shift(); } if (state == "starting") { var turn = (dir - headDirection); head.rotation += turn == -3 ? 1 : (turn == 3 ? -1 : turn ); headDirection = dir; return; } var row = head.row; var column = head.column; if (dir == 0) { row = row - 1; } else if (dir == 1) { column = column + 1 } else if (dir == 2) { row = row + 1; } else if (dir == 3) { column = column - 1; } //validate the new position if (row < 0 || row >= numRows || column < 0 || column >= numColumns || (row == skull.row && column == skull.column) || !isFree(row, column)) { var turn = (dir - headDirection); head.rotation += turn == -3 ? 1 : (turn == 3 ? -1 : turn ); headDirection = dir; endGame(); return; } var newLink; if (linksToGrow > 0) { --linksToGrow; newLink = links[snake.length]; newLink.spawned = false; newLink.rotation = snake[snake.length-1].rotation; newLink.type = growType; newLink.dying = false; snake.push(newLink); } else { var lastLink = snake[snake.length-1]; board[lastLink.row * numColumns + lastLink.column] = undefined; } if (waitForCookie > 0) { if (--waitForCookie == 0) createCookie(cookie? (cookie.value+1) : 1); } for (var i = snake.length-1; i > 0; --i) { snake[i].row = snake[i-1].row; snake[i].column = snake[i-1].column; snake[i].rotation = snake[i-1].rotation; } if (newLink) { newLink.spawned = true; } // move the head head.row = row; head.column = column; board[row * numColumns + column] = head; var turn = (dir - headDirection); head.rotation += turn == -3 ? 1 : (turn == 3 ? -1 : turn ); headDirection = dir; var value = testCookie(row, column); if (value > 0) { linksToGrow += value; score += value; } } function isFree(row, column) { return board[row * numColumns + column] == undefined; } function isHead(row, column) { return head.column == column && head.row == row; } function testCookie(row, column) { if (cookie && !cookie.dying && cookie.row == row && cookie.column == column) { var value = cookie.value; waitForCookie = value; growType = snake[snake.length-1].type == 1 ? 0 : 1; cookie.dying = true; cookie.z = numRows * numColumns + 2; return value; } return 0; } function moveSkull() { if (linksToDie > 0) { --linksToDie; var link = snake.pop(); link.dying = true; board[link.row * numColumns + link.column] = undefined; if (score > 0) --score; if (snake.length == 0) { endGame(); return; } } var row = skull.row; var column = skull.column; if (isHead(row, column)) { endGame(); return; } row += skull.verticalMovement; column += skull.horizontalMovement; var attempts = 4; while (skullMovementsBeforeDirectionChange == 0 || row < 0 || row >= numRows || column < 0 || column >= numColumns || (!isFree(row, column) && !isHead(row, column))) { var d = rand(8); skull.verticalMovement = 0; skull.horizontalMovement = 0; skullMovementsBeforeDirectionChange = rand(20)+1; if (d == 0) { skull.verticalMovement = -1 } else if (d == 1) { skull.horizontalMovement = -1; } else if (d == 2) { skull.verticalMovement = 1 } else if (d == 3){ skull.horizontalMovement = 1; } else if (cookie) { var rd = cookie.row - skull.row; var rc = cookie.column - skull.column; if (Math.abs(rd) > Math.abs(rc)) { skull.verticalMovement = rd > 0 ? 1 : -1; skullMovementsBeforeDirectionChange = Math.abs(rd); } else { skull.horizontalMovement= rc > 0 ? 1 : -1; skullMovementsBeforeDirectionChange = Math.abs(rc); } } row = skull.row + skull.verticalMovement; column = skull.column + skull.horizontalMovement; if (--attempts == 0) return; } skull.row = row; skull.column = column; --skullMovementsBeforeDirectionChange; var value = testCookie(row, column); if (value > 0) linksToDie += value/2; if (isHead(row, column)) endGame(); } function createCookie(value) { if (numRows * numColumns - snake.length < 10) return; var column = rand(numColumns); var row = rand(numRows); while (!isFree(row, column)) { column++; if (column == numColumns) { column = 0; row++; if (row == numRows) row = 0; } } if(cookieComponent.status != Component.Ready) { if(cookieComponent.status == Component.Error) console.log(cookieComponent.errorString()); else console.log("Still loading cookieComponent"); return;//TODO: Better error handling? } cookie = cookieComponent.createObject(head.parent); cookie.value = value; cookie.row = row; cookie.column = column; }