Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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!

share|improve this question
1  
You can convert this into Stack Snippets in your post. – Joseph the Dreamer Jan 27 at 18:40
    
@JosephtheDreamer i did that but now the controls don't work ): – LVsuper Jan 27 at 19:01

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

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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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