demos/declarative/snake/content/snake.js
changeset 30 5dc02b23752f
child 33 3e2da88830cd
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
       
     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 }