From cb1db4770400ae838afddb0b398f6e00b689c792 Mon Sep 17 00:00:00 2001 From: Jonathan Bernard Date: Fri, 12 Dec 2014 05:02:18 -0600 Subject: [PATCH] Added variable growth factor and groundwork for victory conditions. --- snake/snake.js | 81 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 22 deletions(-) diff --git a/snake/snake.js b/snake/snake.js index 7a7ffc8..1095691 100644 --- a/snake/snake.js +++ b/snake/snake.js @@ -16,11 +16,17 @@ // The starting game board. var startBoard; + var startGrowthFactor = 2; // When we eat food, how many turns do we grow? + var startGFIncrease=0; // When we eat, how much should the GF increase? + var targetScore = 0; // How many pieces of food must we eat to win? - var body = new Array(); - var headCur; - var direction = 1; - var foodEaten = false; + var body = new Array(); // Queue of body indices. + var headCur; // Index of the head's current position. + var direction = 1; // Current movement direction. + var foodEaten = false; // Did we eat food this turn? + var growthFactor // When we eat food, how many turns do we grow? + var growthCounter; // How many remaining turns should we grow? + var score = 0; // How many pieces of food have we eaten? // HTML Elements var canvas; @@ -49,6 +55,8 @@ function initialize(options) { + if (!options) options = {}; + // Store our own copy of the canvas and get a 2D graphics context. if (options.canvas) canvas = options.canvas; else canvas = document.getElementsByTagName("canvas")[0]; @@ -75,14 +83,32 @@ else startBoard[i] = SPACE; } } // Figure out how big each game tile is. - tileWidth = canvas.width / COLS; - tileHeight = canvas.height / ROWS; + tileWidth = Math.ceil(canvas.width / COLS); + tileHeight = Math.ceil(canvas.height / ROWS); + console.log("canvas.width: " + canvas.width); + console.log("canvas.height: " + canvas.height); + console.log("ROWS: " + ROWS); + console.log("COLS: " + COLS); + console.log("Tile Width: " + tileWidth); + console.log("Tile Height: " + tileHeight); // Mark the player as dead. This is primarily for the case where a // player re-initializes the board during a game in progress. It // causes any scheduled logic to quit without affecting out game state. dead = true; + // Read in the growth factor and increase. + if (options.growthFactor) startGrowthFactor = options.growthFactor; + else startGrowthFactor = 2; + + if (options.growthFactorIncrease) + startGFIncrease = options.growthFactorIncrease; + else startGFIncrease = 1; + + // Check for a target score to consider this level "won." + if (options.targetScore) targetScore = option.targetScore; + else options.targetScore = 0; // 0 = no target, play indefinitely. + // Check to see if they want to use the editor or the game. editor = Boolean(options.editor); @@ -96,7 +122,7 @@ g.font = "24px sans-serif"; g.fillStyle = "black"; - g.fillText("Press Enter to begin.", 50, Math.floor(canvas.height/2), canvas.width - 100); + g.fillText("Press Space to begin.", 50, Math.floor(canvas.height/2), canvas.width - 100); if (options.fps) skipTicks = Math.ceil(1000 / options.fps); else skipTicks = 150; } @@ -113,26 +139,30 @@ canvas.focus(); } - function startGame() { while (body.length > 0) body.pop(); while (cmdQueue.length > 0) cmdQueue.pop(); - headCur = coord2idx(Math.floor((ROWS - 1) / 2), Math.floor((COLS - 1) / 2)); direction = 1; dead = pause = false; + score = growthCounter = 0; nextGameTick = (new Date).getTime() + skipTicks; - - body.push(headCur); + growthFactor = startGrowthFactor; + growthFactorIncrease = startGFIncrease; // Copy over a fresh board. board = new Array(startBoard.length); for (var i = 0; i < board.length; i++) board[i] = startBoard[i]; // Create a new food item and add it to the board. - board[newFoodLocation()] = FOOD; + board[randomEmptySpace()] = FOOD; - // Write the initial body segment onto the board. + // Find or write the initial body segment onto the board. + for (headCur = -1, i = 0; i < board.length; i++) + if (board[i] == SNAKE) headCur = i; + if (headCur < 0) headCur = randomEmptySpace(); + + body.push(headCur); board[headCur] = SNAKE; // Draw the board @@ -195,13 +225,17 @@ // 3. First check to see if we've eaten food (since it will affect // collision detection for the body). This is also where growth // happens via not moving the tail. - if (board[headCur] == FOOD) foodEaten = true; + if (board[headCur] == FOOD) { + foodEaten = true; + growthCounter += growthFactor; + growthFactor += growthFactorIncrease; } // 4. Remove the tail. - if (!foodEaten) { + if (growthCounter == 0) { var tailIdx = body.shift(); board[tailIdx] = SPACE paintIdx(tailIdx); } + else growthCounter -= 1; // 5. Detect wall and snake collisions if (board[headCur] == WALL || board[headCur] == SNAKE) { @@ -214,12 +248,12 @@ // 7. Create more food if needed. if (foodEaten) { - var foodLoc = newFoodLocation(); + var foodLoc = randomEmptySpace(); board[foodLoc] = FOOD; paintIdx(foodLoc); } } // Find a new location for a piece of food. - function newFoodLocation() { + function randomEmptySpace() { // Find all the spaces on the board that are not occupied var emptySpaces = new Array(); for (var i = 0; i < board.length; i++) @@ -236,7 +270,7 @@ g.font = "24px sans-serif"; g.fillStyle = "red"; - g.fillText("Press Enter to retry.", 50, Math.floor(canvas.height/2), canvas.width - 100); } + g.fillText("Press Space to retry.", 50, Math.floor(canvas.height/2), canvas.width - 100); } function handleGameKey(ke) { var key = ke.keyCode ? ke.keyCode : ke.which; @@ -245,8 +279,8 @@ // worrying about the game becoming a black-hole for events. var dontCare = false; - // Enter, start a new game. - if (key == 13) { + // Space, start a new game. + if (key == 32) { dead = true; requestAnimationFrame(startGame); } @@ -279,8 +313,8 @@ var dontCare = false; switch (key) { - // Enter: place a tile. - case 13: board[cursorIdx] = cursorBlock; break; + // Space or Enter: place a tile. + case 32: case 13: board[cursorIdx] = cursorBlock; break; // Direction keys: move the cursor. case 37: cursorIdx -= 1; break; // Left @@ -323,6 +357,9 @@ board: board, rows: ROWS, cols: COLS, + growthFactor: startGrowthFactor, + growthFactorIncrease: startGFIncrease, + targetScore: targetScore, fps: Math.ceil(1000 / skipTicks)}); } // Load the editor data as a JSON string from the textarea.