UNPKG

@deveckad/snakegame

Version:

The snake game.

309 lines (259 loc) 7.15 kB
const socket = io() const BG_COLOUR = '#231f20' const SNAKE_COLOUR = '#c2c2c2' const FOOD_COLOUR = '#e66916' const canvas = document.querySelector('canvas') const msgDisplay = document.querySelector('.msg-display') const ctx = canvas.getContext('2d') var pos, vel, tail, food, score, hiscore var keyPressed = false var gameRunning = false var gameStarted = false canvas.width = canvas.height = 550 const GRID_SIZE = 22 const TILE_SIZE = canvas.width / GRID_SIZE const FR = 7 socket.on('hiscore', (hiscr) => { hiscore = hiscr }) function init() { gameStarted = gameRunning = false msgDisplay.innerText = 'Press any key to start...' pos = { x: 10, y: 10 } vel = { x: 1, y: 0 } tail = [ { x: 8, y: 10 }, { x: 9, y: 10 }, { x: 10, y: 10 } ] score = 0 randomFood() paintGame() } init() setInterval(() => { requestAnimationFrame(gameLoop) }, 1000 / FR) function randomFood() { food = { x: Math.floor(Math.random() * TILE_SIZE), y: Math.floor(Math.random() * TILE_SIZE) } for (const cell of tail) { if (food.x === cell.x && food.y === cell.y) { randomFood() } } } function gameLoop() { if (gameRunning) { keyPressed = false paintGame() pos.x += vel.x pos.y += vel.y if (food.x === pos.x && food.y === pos.y) { score++ refreshMsgDisplay() tail.push({ ...pos }) pos.x += vel.x pos.y += vel.y randomFood() } if (pos.x < 0 || pos.x > TILE_SIZE || pos.y < 0 || pos.y > TILE_SIZE) { gameOver() } if (vel.x || vel.y) { for (const cell of tail) { if (pos.x === cell.x && pos.y === cell.y) { return gameOver() } } tail.push({ ...pos }) tail.shift() } } } document.addEventListener('keydown', keydown) function keydown(e) { if (!gameStarted) { gameStarted = gameRunning = true refreshMsgDisplay() } var vel2 switch (e.keyCode) { case 37: { vel2 = { x: -1, y: 0 } break } case 38: { vel2 = { x: 0, y: -1 } break } case 39: { vel2 = { x: 1, y: 0 } break } case 40: { vel2 = { x: 0, y: 1 } break } default: return } if (!isOpposite(vel, vel2) && !keyPressed) { vel = vel2 } keyPressed = true } function isOpposite(firstDir, secondDir) { // console.log("Opposite: " + firstDir + " " + secondDir) return !( !(firstDir.x + secondDir.x == 0 && firstDir.y + secondDir.y == 0) // || (firstDir.x == 0 && firstDir.y == 0) ) } function gameOver() { gameRunning = false socket.emit('gethiscore') socket.on('rethiscore', (hiscore) => { var msg = `Game Over! Your score is ${score}` var hiscoreMsg = ` and hi-score is ${hiscore.score}, maked by ${hiscore.name}!` var resultMsg if (score > hiscore.score) { hiscoreMsg = ' and it is hi-score! Enter name to save it:' resultMsg = msg + hiscoreMsg var name = prompt(resultMsg) socket.emit('newhiscore', JSON.stringify({ name, score })) } else { var resultMsg = msg + hiscoreMsg alert(resultMsg) } init() }) } function refreshMsgDisplay() { msgDisplay.innerText = `Score: ${score}` } function paintGame() { ctx.fillStyle = BG_COLOUR ctx.fillRect(0, 0, canvas.width, canvas.height) ctx.fillStyle = SNAKE_COLOUR for (const cell of tail) { ctx.fillRect(cell.x * GRID_SIZE, cell.y * GRID_SIZE, GRID_SIZE, GRID_SIZE) } ctx.fillStyle = FOOD_COLOUR ctx.fillRect(food.x * GRID_SIZE, food.y * GRID_SIZE, GRID_SIZE, GRID_SIZE) } // old version // const socket = io() // const BG_COLOR = '#231f20'; // const SNAKE_COLOR = '#c2c2c2'; // const FOOD_COLOR = '#e66916'; // const GRID_SIZE = 22 // const SCREEN_SIZE = 550 // const TILE_SIZE = SCREEN_SIZE / GRID_SIZE // const FR = 10 // const canvas = document.querySelector('canvas') // const ctx = canvas.getContext('2d') // var gameState // canvas.width = canvas.height = SCREEN_SIZE // document.addEventListener('keydown', keyDown) // init() // function keyDown(e) { // switch (e.keyCode) { // case 37: { // console.log('right'); // break; // } // case 38: { // console.log('up'); // break; // } // case 39: { // console.log('left'); // break; // } // case 40: { // console.log('down'); // break; // } // } // } // function init() { // gameState = { // player: { // pos: { // x: 5, // x: 5, // }, // vel: { // x: 0, // x: 0, // }, // tail: [], // initLength: 3 // }, // food: { // x: 0, // y: 0, // }, // score: 0 // } // initTail() // console.log(gameState.player.tail) // randomFood() // gameLoop() // } // function initTail() { // for (var i = 0; i < gameState.player.initLength; i++) { // gameState.player.tail.push({x: gameState.player.pos.x - i - 1, y: gameState.player.pos.y}) // } // gameState.player.tail.reverse() // } // function randomFood() { // if (gameState.score + gameState.player.initLength >= GRID_SIZE * GRID_SIZE) { // gameOver() // } // gameState.food.x = Math.floor(Math.random() * GRID_SIZE) // gameState.food.y = Math.floor(Math.random() * GRID_SIZE) // gameState.player.tail.forEach(cell => { // if (gameState.food.x == cell.x && gameState.food.y == cell.y) { // randomFood() // } // }) // } // function gameLoop() { // ctx.fillStyle = BG_COLOR // ctx.fillRect(0, 0, SCREEN_SIZE, SCREEN_SIZE) // ctx.fillStyle = SNAKE_COLOR // gameState.player.tail.forEach(cell => { // ctx.fillRect(cell.x * TILE_SIZE, cell.y * TILE_SIZE, TILE_SIZE, TILE_SIZE) // }) // ctx.fillStyle = FOOD_COLOR // ctx.fillRect(gameState.food.x * TILE_SIZE, gameState.food.y * TILE_SIZE, TILE_SIZE, TILE_SIZE) // gameState.player.pos.x += gameState.player.vel.x // gameState.player.pos.y += gameState.player.vel.y // if (gameState.player.vel.x || gameState.player.vel.y) { // if (gameState.player.pos.x == gameState.food.x && gameState.player.pos.y == gameState.food.y) { // gameState.score++ // gameState.player.tail.push({ ...gameState.player.pos }) // gameState.player.pos.x += gameState.player.vel.x // gameState.player.pos.y += gameState.player.vel.y // } // if (gameState.player.pos.x <= 0 || gameState.player.pos.y <= 0 || gameState.player.pos.x > GRID_SIZE || gameState.player.pos.y > GRID_SIZE) { // gameOver() // } // gameState.player.tail.forEach(cell => { // if (cell.x == gameState.player.pos.x && cell.y == gameState.player.pos.y) { // gameOver() // } // }) // gameState.player.tail.push({ ...gameState.player.pos }) // snake.shift() // } // setTimeout(() => requestAnimationFrame(gameLoop), 1000 / FR) // } // function gameOver() { // alert('Game Over!') // init() // }