├── README.md ├── index.html ├── script.js └── styles.css /README.md: -------------------------------------------------------------------------------- 1 | # snake 2 | Juego Snake con JS creado en este tutorial: https://youtu.be/pyas0IREz-o 3 | 4 | Screen Shot 2021-10-16 at 16 11 45 5 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Snake 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 |
16 | Score:
17 |
18 | 19 |
20 |
Game Over
21 | 22 | -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | // HTML Elements 2 | const board = document.getElementById('board'); 3 | const scoreBoard = document.getElementById('scoreBoard'); 4 | const startButton = document.getElementById('start'); 5 | const gameOverSign = document.getElementById('gameOver'); 6 | 7 | // Game settings 8 | const boardSize = 10; 9 | const gameSpeed = 100; 10 | const squareTypes = { 11 | emptySquare: 0, 12 | snakeSquare: 1, 13 | foodSquare: 2 14 | }; 15 | const directions = { 16 | ArrowUp: -10, 17 | ArrowDown: 10, 18 | ArrowRight: 1, 19 | ArrowLeft: -1, 20 | }; 21 | 22 | // Game variables 23 | let snake; 24 | let score; 25 | let direction; 26 | let boardSquares; 27 | let emptySquares; 28 | let moveInterval; 29 | 30 | const drawSnake = () => { 31 | snake.forEach( square => drawSquare(square, 'snakeSquare')); 32 | } 33 | 34 | // Rellena cada cuadrado del tablero 35 | // @params 36 | // square: posicion del cuadrado, 37 | // type: tipo de cuadrado (emptySquare, snakeSquare, foodSquare) 38 | const drawSquare = (square, type) => { 39 | const [ row, column ] = square.split(''); 40 | boardSquares[row][column] = squareTypes[type]; 41 | const squareElement = document.getElementById(square); 42 | squareElement.setAttribute('class', `square ${type}`); 43 | 44 | if(type === 'emptySquare') { 45 | emptySquares.push(square); 46 | } else { 47 | if(emptySquares.indexOf(square) !== -1) { 48 | emptySquares.splice(emptySquares.indexOf(square), 1); 49 | } 50 | } 51 | } 52 | 53 | const moveSnake = () => { 54 | const newSquare = String( 55 | Number(snake[snake.length - 1]) + directions[direction]) 56 | .padStart(2, '0'); 57 | const [row, column] = newSquare.split(''); 58 | 59 | 60 | if( newSquare < 0 || 61 | newSquare > boardSize * boardSize || 62 | (direction === 'ArrowRight' && column == 0) || 63 | (direction === 'ArrowLeft' && column == 9 || 64 | boardSquares[row][column] === squareTypes.snakeSquare) ) { 65 | gameOver(); 66 | } else { 67 | snake.push(newSquare); 68 | if(boardSquares[row][column] === squareTypes.foodSquare) { 69 | addFood(); 70 | } else { 71 | const emptySquare = snake.shift(); 72 | drawSquare(emptySquare, 'emptySquare'); 73 | } 74 | drawSnake(); 75 | } 76 | } 77 | 78 | const addFood = () => { 79 | score++; 80 | updateScore(); 81 | createRandomFood(); 82 | } 83 | 84 | const gameOver = () => { 85 | gameOverSign.style.display = 'block'; 86 | clearInterval(moveInterval) 87 | startButton.disabled = false; 88 | } 89 | 90 | const setDirection = newDirection => { 91 | direction = newDirection; 92 | } 93 | 94 | const directionEvent = key => { 95 | switch (key.code) { 96 | case 'ArrowUp': 97 | direction != 'ArrowDown' && setDirection(key.code) 98 | break; 99 | case 'ArrowDown': 100 | direction != 'ArrowUp' && setDirection(key.code) 101 | break; 102 | case 'ArrowLeft': 103 | direction != 'ArrowRight' && setDirection(key.code) 104 | break; 105 | case 'ArrowRight': 106 | direction != 'ArrowLeft' && setDirection(key.code) 107 | break; 108 | } 109 | } 110 | 111 | const createRandomFood = () => { 112 | const randomEmptySquare = emptySquares[Math.floor(Math.random() * emptySquares.length)]; 113 | drawSquare(randomEmptySquare, 'foodSquare'); 114 | } 115 | 116 | const updateScore = () => { 117 | scoreBoard.innerText = score; 118 | } 119 | 120 | const createBoard = () => { 121 | boardSquares.forEach( (row, rowIndex) => { 122 | row.forEach( (column, columnndex) => { 123 | const squareValue = `${rowIndex}${columnndex}`; 124 | const squareElement = document.createElement('div'); 125 | squareElement.setAttribute('class', 'square emptySquare'); 126 | squareElement.setAttribute('id', squareValue); 127 | board.appendChild(squareElement); 128 | emptySquares.push(squareValue); 129 | }) 130 | }) 131 | } 132 | 133 | const setGame = () => { 134 | snake = ['00', '01', '02', '03']; 135 | score = snake.length; 136 | direction = 'ArrowRight'; 137 | boardSquares = Array.from(Array(boardSize), () => new Array(boardSize).fill(squareTypes.emptySquare)); 138 | console.log(boardSquares); 139 | board.innerHTML = ''; 140 | emptySquares = []; 141 | createBoard(); 142 | } 143 | 144 | const startGame = () => { 145 | setGame(); 146 | gameOverSign.style.display = 'none'; 147 | startButton.disabled = true; 148 | drawSnake(); 149 | updateScore(); 150 | createRandomFood(); 151 | document.addEventListener('keydown', directionEvent); 152 | moveInterval = setInterval( () => moveSnake(), gameSpeed); 153 | } 154 | 155 | startButton.addEventListener('click', startGame); -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- 1 | * { 2 | font-family: 'Share Tech Mono', monospace; 3 | } 4 | 5 | #board, .boardInfo { 6 | max-width: 500px; 7 | } 8 | 9 | #board { 10 | display: grid; 11 | grid-template-columns: repeat(10, 1fr); 12 | } 13 | 14 | #start, .boardInfo { 15 | font-size: 25px; 16 | } 17 | 18 | #gameOver { 19 | display: none; 20 | } 21 | 22 | .boardInfo { 23 | display: flex; 24 | justify-content: space-between; 25 | margin-top: 10px; 26 | } 27 | 28 | #start { 29 | background-color: #f35a69; 30 | border: none; 31 | color: white; 32 | } 33 | 34 | #scoreBoard { 35 | display: inline-flex; 36 | } 37 | 38 | .square { 39 | aspect-ratio: 1; 40 | } 41 | 42 | .emptySquare { 43 | background-color: #6d71b5; 44 | } 45 | 46 | .snakeSquare { 47 | background-color: #e3e773; 48 | border: 1px solid #000; 49 | } 50 | 51 | .foodSquare { 52 | background-color: #55e7e7; 53 | border: 1px solid #000; 54 | } --------------------------------------------------------------------------------