2
\$\begingroup\$

I recently followed a tutorial on a JavaScript snake game. I tried to improve that game by adding bad fruit which will make your snakes tail incredibly long.

//constants
var COLS = 26,
  ROWS = 26;
//IDs
var EMPTY = 0,
  SNAKE = 1,
  FRUIT = 2,
  BADFRUIT = 3;
//direction
var LEFT = 0,
  UP = 1,
  RIGHT = 2,
  DOWN = 3;
//game objects
var canvas, ctx, keystate, frames;
// Key Codes
var KEY_LEFT = 37,
  KEY_UP = 38,
  KEY_RIGHT = 39,
  KEY_DOWN = 40


var grid = {
  width: null,
  height: null,
  _grid: null,

  init: function(d, c, r) {
    this.width = c;
    this.height = r;
    this._grid = [];

    for (var x = 0; x < c; x++) {
      this._grid.push([]);
      for (var y = 0; y < r; y++) {
        this._grid[x].push(d);
      }
    }
  },


  set: function(val, x, y) {
    this._grid[x][y] = val;

  },

  get: function(x, y) {
    return this._grid[x][y]

  },
}
var snake = {
  direction: null,
  last: null,

  _queue: null,

  init: function(d, x, y) {
    this.direction = d;

    this._queue = [];
    this.insert(x, y);
  },

  insert: function(x, y) {
    // unshift prepends an element to an array
    this._queue.unshift({
      x: x,
      y: y
    });
    this.last = this._queue[0];
  },

  remove: function() {
    return this._queue.pop();
  },
}

function setAlwaysBadFood() {
  var empty = [];
  for (var x = 0; x < grid.width; x++) {
    for (var y = 0; y < grid.height; y++) {
      if (grid.get(x, y) === EMPTY) {
        empty.push({
          x: x,
          y: y
        });
      }
    }
  }

  var randpos = empty[Math.round(Math.random() * (empty.length - 1))];
  grid.set(BADFRUIT, randpos.x, randpos.y);

}

function setBadFood() {
  var randomBadFruit = Math.round(Math.random() * 10)
  console.log(randomBadFruit)
  console.log("WHY ARE YOU LOOKING HERE!   >:(")
  if (randomBadFruit === 9 || randomBadFruit === 8) {
    var empty = [];
    for (var x = 0; x < grid.width; x++) {
      for (var y = 0; y < grid.height; y++) {
        if (grid.get(x, y) === EMPTY) {
          empty.push({
            x: x,
            y: y
          });
        }
      }
    }

    var randpos = empty[Math.round(Math.random() * (empty.length - 1))];
    grid.set(BADFRUIT, randpos.x, randpos.y);
    console.log(randomBadFruit)
  }
}

function setFood() {
  var empty = [];
  for (var x = 0; x < grid.width; x++) {
    for (var y = 0; y < grid.height; y++) {
      if (grid.get(x, y) === EMPTY) {
        empty.push({
          x: x,
          y: y
        });
      }
    }
  }

  var randpos = empty[Math.round(Math.random() * (empty.length - 1))];
  grid.set(FRUIT, randpos.x, randpos.y);

}




function main() {
  canvas = document.createElement("canvas");
  canvas.width = COLS * 35;
  canvas.height = ROWS * 35;
  ctx = canvas.getContext("2d");
  document.body.appendChild(canvas);

  frames = 0
  keystate = {};

  document.addEventListener("keydown", function(evt) {
    keystate[evt.keyCode] = true;
  });
  document.addEventListener("keyup", function(evt) {
    delete keystate[evt.keyCode];
  });
  init();
  loop();
}

function init() {
  grid.init(EMPTY, COLS, ROWS);

  var sp = {
    x: Math.floor(COLS / 2),
    y: ROWS - 1
  };
  snake.init(UP, sp.x, sp.y);
  grid.set(SNAKE, sp.x, sp.y);

  setBadFood();
  setFood();

}

function loop() {
  update();
  draw();

  window.requestAnimationFrame(loop, canvas);
}

function update() {
  frames++;

  if (keystate[KEY_LEFT] && snake.direction !== RIGHT) {
    snake.direction = LEFT;
  }
  if (keystate[KEY_UP] && snake.direction !== DOWN) {
    snake.direction = UP;
  }
  if (keystate[KEY_RIGHT] && snake.direction !== LEFT) {
    snake.direction = RIGHT;
  }
  if (keystate[KEY_DOWN] && snake.direction !== UP) {
    snake.direction = DOWN;
  }
  if (frames % 5 === 0) {
    var nx = snake.last.x
    var ny = snake.last.y

    switch (snake.direction) {
      case LEFT:
        nx--;
        break;
      case UP:
        ny--;
        break;
      case RIGHT:
        nx++;
        break;
      case DOWN:
        ny++;
        break;


    }

    if (0 > nx || nx > grid.width - 1 ||
      0 > ny || ny > grid.height - 1 ||
      grid.get(nx, ny) === SNAKE
    ) {
      return init();
    }
    if (grid.get(nx, ny) === BADFRUIT) {
      var tail = {
        x: nx,
        y: ny
      };
      for (var i = 0; i < 50; i++) {
        snake.insert(tail.x, tail.y);
      }
      for (var i = 0; i < 10; i++) {
        setAlwaysBadFood();
      }

    }

    if (grid.get(nx, ny) === FRUIT) {
      var tail = {
        x: nx,
        y: ny
      };
      snake.insert(tail.x, tail.y);
      snake.insert(tail.x, tail.y);
      snake.insert(tail.x, tail.y);
      setFood();
      setBadFood();
      setAlwaysBadFood();


    } else {
      var tail = snake.remove();
      grid.set(EMPTY, tail.x, tail.y);
      tail.x = nx;
      tail.y = ny;
    }


    grid.set(SNAKE, tail.x, tail.y);

    snake.insert(tail.x, tail.y);


  }
}


function draw() {
  // calculate tile-width and -height
  var tw = canvas.width / grid.width;
  var th = canvas.height / grid.height;
  // iterate through the grid and draw all cells
  for (var x = 0; x < grid.width; x++) {
    for (var y = 0; y < grid.height; y++) {
      // sets the fillstyle depending on the id of
      // each cell
      switch (grid.get(x, y)) {
        case EMPTY:
          ctx.fillStyle = "#fff";
          break;
        case SNAKE:
          ctx.fillStyle = "#0ff";
          break;
        case FRUIT:
          ctx.fillStyle = "#f00";
          break;
        case BADFRUIT:
          ctx.fillStyle = "#000066"
      }
      ctx.fillRect(x * tw, y * th, tw, th);
    }
  }
}


// start and run the game
main();
<!doctype html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Simple Snake Game</title>
  <style>
    canvas {
      display: block;
      position: absolute;
      border: 1px solid #000;
      margin: 0;
      top: 0 bottom: 0 right: 0 left: 0;
    }
  </style>
</head>

<body>
  <script>
  </script>
</body>

What do you think? I'm trying to make the snake go faster but I can't do that. I don't know what happend but the controls do not work in the stack snippet sorry for that!

\$\endgroup\$
  • 1
    \$\begingroup\$ You can convert this into Stack Snippets in your post. \$\endgroup\$ – Joseph Jan 27 '16 at 18:40
  • \$\begingroup\$ @JosephtheDreamer i did that but now the controls don't work ): \$\endgroup\$ – LVsuper Jan 27 '16 at 19:01
-1
\$\begingroup\$

i would use let instead of var, and the syntax update(){} instead of function: update(){} (considering the ES6 standard).

\$\endgroup\$
  • \$\begingroup\$ There is nothing in this question indicating that the author is targeting ECMAScript 6. \$\endgroup\$ – 200_success Jan 29 '16 at 17:57
  • \$\begingroup\$ i'm new to SO, this type of answers is wrong? It's a way of improve his code isn't? @200_success \$\endgroup\$ – Josenberg Jan 29 '16 at 18:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.