-1

I have a javascript snake game, which was made by following a tutorial. I need help to implement my restart button which I was making on my own

var canvas = document.getElementById('game');
var context = canvas.getContext('2d');
// var startBtn = document.getElementById('startbutton')

var score = 0;

var grid = 16;
var count = 0;

var snake = {
  x: 160,
  y: 160,

  // snake velocity. moves one grid length every frame in either the x or y direction
  dx: grid,
  dy: 0,

  // keep track of all grids the snake body occupies
  cells: [],

  // length of the snake. grows when eating an apple
  maxCells: 4
};
var apple = {
  x: 320,
  y: 320
};

function update(score) {
  document.getElementById("scores").innerHTML = "Score: " + score;

}

// get random whole numbers in a specific range
// @see https://stackoverflow.com/a/1527820/2124254
function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}


// game loop
function loop() {
  update(score)
  requestAnimationFrame(loop);

  // slow game loop to 15 fps instead of 60 (60/15 = 4)
  if (++count < 5) {
    return;

  }


  count = 0;
  context.clearRect(0, 0, canvas.width, canvas.height);

  // move snake by it's velocity
  snake.x += snake.dx;
  snake.y += snake.dy;

  // wrap snake position horizontally on edge of screen
  if (snake.x < 0) {
    snake.x = canvas.width - grid;
  } else if (snake.x >= canvas.width) {
    snake.x = 0;
  }

  // wrap snake position vertically on edge of screen
  if (snake.y < 0) {
    snake.y = canvas.height - grid;
  } else if (snake.y >= canvas.height) {
    snake.y = 0;
  }

  // keep track of where snake has been. front of the array is always the head
  snake.cells.unshift({
    x: snake.x,
    y: snake.y
  });

  // remove cells as we move away from them
  if (snake.cells.length > snake.maxCells) {
    snake.cells.pop();
  }

  // draw apple
  context.fillStyle = 'red';
  context.fillRect(apple.x, apple.y, grid - 1, grid - 1);

  // draw snake one cell at a time
  context.fillStyle = 'green';
  snake.cells.forEach(function(cell, index) {

    // drawing 1 px smaller than the grid creates a grid effect in the snake body so you can see how long it is
    context.fillRect(cell.x, cell.y, grid - 1, grid - 1);

    // snake ate apple
    if (cell.x === apple.x && cell.y === apple.y) {
      snake.maxCells++;
      score++;

      // canvas is 400x400 which is 25x25 grids 
      apple.x = getRandomInt(0, 25) * grid;
      apple.y = getRandomInt(0, 25) * grid;
    }

    // check collision with all cells after this one (modified bubble sort)
    for (var i = index + 1; i < snake.cells.length; i++) {

      // snake occupies same space as a body part. reset game
      if (cell.x === snake.cells[i].x && cell.y === snake.cells[i].y) {
        again()
        snake.x = 160;
        snake.y = 160;
        snake.cells = [];
        snake.maxCells = 4;
        snake.dx = grid;
        snake.dy = 0;

        apple.x = getRandomInt(0, 25) * grid;
        apple.y = getRandomInt(0, 25) * grid;
        score = 0
        // startBtn.style.display: 'none';
        // document.getElementById('start')

      }
    }
  });
}

// listen to keyboard events to move the snake
document.addEventListener('keydown', function(e) {
  // prevent snake from backtracking on itself by checking that it's 
  // not already moving on the same axis (pressing left while moving
  // left won't do anything, and pressing right while moving left
  // shouldn't let you collide with your own body)

  // left arrow key
  if (e.which === 37 && snake.dx === 0) {
    snake.dx = -grid;
    snake.dy = 0;
  }
  // up arrow key
  else if (e.which === 38 && snake.dy === 0) {
    snake.dy = -grid;
    snake.dx = 0;
  }
  // right arrow key
  else if (e.which === 39 && snake.dx === 0) {
    snake.dx = grid;
    snake.dy = 0;
  }
  // down arrow key
  else if (e.which === 40 && snake.dy === 0) {
    snake.dy = grid;
    snake.dx = 0;
  }
});

// start the game
// document.getElementById("scores").innerHTML = score;
function again() {
  document.getElementById("start").addEventListener("click", function restart() {
    requestAnimationFrame(loop);

  })
}
again()
html,
body {
  height: 100%;
  margin: 0;
}

body {
  background: black !important;
  display: flex;
  align-items: center;
  justify-content: center;
}

canvas {
  border: 1px solid white;
}

a {
  align-items: left;
}

#cent {
  position: absolute;
  margin-left: 20px;
  margin-right: 20px;
  margin-bottom: 50px;
  bottom: 0;
}

#startbutton {
  border: none;
  background: none;
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 1;
  transform: translate(-50%, -50%);
  -webkit-transform: translate(-50%, -50%);
  -moz-transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
}

#start {
  border: none;
  background: none;
  position: absolute;
  top: 50%;
  left: 50%;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<title>RBGamez</title>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>

<div id="cent">
  <a href="{{url_for('home')}}"><button type="button" class="btn btn-primary">Return home</button></a>
</div>
<div style="position: absolute; left: 45%; top: 50px; width:200px; height:100px;">
  <h3>
    <p id="scores" style="color: white;"></p>
  </h3>
</div>

<button type="button" class="btn btn-primary" id="start" onclick="requestAnimationFrame(loop)">Restart</button>
<canvas width="400" height="400" id="game"></canvas>
yinsweet
  • 2,823
  • 1
  • 9
  • 21
rishi
  • 643
  • 5
  • 21
  • I would also like to add that what I have currently implemented keeps increasing the snake speed whenever I press the restart button. – rishi Jun 14 '20 at 10:36
  • You should probably do your best to identify exactly what you want to happen and where in the code you want this new feature to do, and then edit your post so that you only include the relevant code. E.g. probably you do not need to include CSS in this question, probably you should only post the relevant parts of the javascript. – mozboz Jun 14 '20 at 13:24

1 Answers1

0

Check this. The fixed the increasing velocity issue by implementing this: https://stackoverflow.com/a/10748750/9487478

On button press the again method is triggered now. Moreover I added initial values for apple and snake, which are used for resetting the object.

var canvas = document.getElementById('game');
var context = canvas.getContext('2d');
// var startBtn = document.getElementById('startbutton')

var requestId;

var score = 0;

var grid = 16;
var count = 0;

var snake;
var snake_init = {
  x: 160,
  y: 160,

  // snake velocity. moves one grid length every frame in either the x or y direction
  dx: grid,
  dy: 0,

  // keep track of all grids the snake body occupies
  cells: [],

  // length of the snake. grows when eating an apple
  maxCells: 4
};

var apple;
var apple_init = {
  x: 320,
  y: 320
};

function update(score) {
  document.getElementById("scores").innerHTML = "Score: " + score;

}

// get random whole numbers in a specific range
// @see https://stackoverflow.com/a/1527820/2124254
function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}

// game loop
function loop() {
  requestId = undefined;
  start();
  update(score)

  // slow game loop to 15 fps instead of 60 (60/15 = 4)
  if (++count < 5) {
    return;

  }


  count = 0;
  context.clearRect(0, 0, canvas.width, canvas.height);

  // move snake by it's velocity
  snake.x += snake.dx;
  snake.y += snake.dy;

  // wrap snake position horizontally on edge of screen
  if (snake.x < 0) {
    snake.x = canvas.width - grid;
  } else if (snake.x >= canvas.width) {
    snake.x = 0;
  }

  // wrap snake position vertically on edge of screen
  if (snake.y < 0) {
    snake.y = canvas.height - grid;
  } else if (snake.y >= canvas.height) {
    snake.y = 0;
  }

  // keep track of where snake has been. front of the array is always the head
  snake.cells.unshift({
    x: snake.x,
    y: snake.y
  });

  // remove cells as we move away from them
  if (snake.cells.length > snake.maxCells) {
    snake.cells.pop();
  }

  // draw apple
  context.fillStyle = 'red';
  context.fillRect(apple.x, apple.y, grid - 1, grid - 1);

  // draw snake one cell at a time
  context.fillStyle = 'green';
  snake.cells.forEach(function(cell, index) {

    // drawing 1 px smaller than the grid creates a grid effect in the snake body so you can see how long it is
    context.fillRect(cell.x, cell.y, grid - 1, grid - 1);

    // snake ate apple
    if (cell.x === apple.x && cell.y === apple.y) {
      snake.maxCells++;
      score++;

      // canvas is 400x400 which is 25x25 grids 
      apple.x = getRandomInt(0, 25) * grid;
      apple.y = getRandomInt(0, 25) * grid;
    }

    // check collision with all cells after this one (modified bubble sort)
    for (var i = index + 1; i < snake.cells.length; i++) {

      // snake occupies same space as a body part. reset game
      if (cell.x === snake.cells[i].x && cell.y === snake.cells[i].y) {
        again()
        snake.x = 160;
        snake.y = 160;
        snake.cells = [];
        snake.maxCells = 4;
        snake.dx = grid;
        snake.dy = 0;

        apple.x = getRandomInt(0, 25) * grid;
        apple.y = getRandomInt(0, 25) * grid;
        score = 0
        // startBtn.style.display: 'none';
        // document.getElementById('start')

      }
    }
  });
}

// listen to keyboard events to move the snake
document.addEventListener('keydown', function(e) {
  // prevent snake from backtracking on itself by checking that it's 
  // not already moving on the same axis (pressing left while moving
  // left won't do anything, and pressing right while moving left
  // shouldn't let you collide with your own body)

  // left arrow key
  if (e.which === 37 && snake.dx === 0) {
    snake.dx = -grid;
    snake.dy = 0;
  }
  // up arrow key
  else if (e.which === 38 && snake.dy === 0) {
    snake.dy = -grid;
    snake.dx = 0;
  }
  // right arrow key
  else if (e.which === 39 && snake.dx === 0) {
    snake.dx = grid;
    snake.dy = 0;
  }
  // down arrow key
  else if (e.which === 40 && snake.dy === 0) {
    snake.dy = grid;
    snake.dx = 0;
  }
});

function start() {
  if (!requestId) {
    requestId = window.requestAnimationFrame(loop);
  }
}

function stop() {
  if (requestId) {
    window.cancelAnimationFrame(requestId);
    requestId = undefined;
  }
}

// start the game
function again() {
  document.getElementById("start").addEventListener("click", function restart() {
    // -----------------
    // Reset all values.
    // -----------------

    // Let's make a deep copy of snake_init for resetting.
    snake = JSON.parse(JSON.stringify(snake_init));
    apple = { ...apple_init };
    score = 0;
    count = 0;
    stop();
    start();
  })
}
again()
<title></title><style>html,
body {
  height: 100%;
  margin: 0;
}

body {
  background: black !important;
  display: flex;
  align-items: center;
  justify-content: center;
}

canvas {
  border: 1px solid white;
}

a {
  align-items: left;
}

#cent {
  position: absolute;
  margin-left: 20px;
  margin-right: 20px;
  margin-bottom: 50px;
  bottom: 0;
}

#startbutton {
  border: none;
  background: none;
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 1;
  transform: translate(-50%, -50%);
  -webkit-transform: translate(-50%, -50%);
  -moz-transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
}

#start {
  border: none;
  background: none;
  position: absolute;
  top: 50%;
  left: 50%;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<title>RBGamez</title>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>

<div id="cent">
  <a href="{{url_for('home')}}"><button type="button" class="btn btn-primary">Return home</button></a>
</div>
<div style="position: absolute; left: 45%; top: 50px; width:200px; height:100px;">
  <h3>
    <p id="scores" style="color: white;"></p>
  </h3>
</div>

<button type="button" class="btn btn-primary" id="start" onclick="again">Restart</button>
<canvas width="400" height="400" id="game"></canvas>
Paul
  • 2,086
  • 1
  • 8
  • 16