snake.js Example File

demos/declarative/snake/qml/snake/content/snake.js
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)
{
    if (state == "starting") {
        direction = dir;
        headDirection = direction;
        head.rotation = headDirection;
    } else if (state == "running"){
        direction = dir;
        if(scheduledDirections[scheduledDirections.length-1]!=direction)
            scheduledDirections.push(direction);
    }
}

function startNewGame()
{
    if (state == "starting") {
        return;
    }

    if (activeGame) {
        endGame();
        startNewGameTimer.running = true;
        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()
{
    activeGame = 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;
}

© 2016 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.