├── .gitignore ├── README.md ├── events.js ├── img ├── name.png ├── play.png └── game-over.png ├── sounds └── intro.mp3 ├── food.js ├── style.css ├── preload.js ├── sketch.js ├── game.js ├── index.html ├── screens ├── intro.js └── playground.js └── snake.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | The Snake Game 2 | --- 3 | -------------------------------------------------------------------------------- /events.js: -------------------------------------------------------------------------------- 1 | function keyPressed() { 2 | game.keyPressed(keyCode) 3 | } 4 | -------------------------------------------------------------------------------- /img/name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitbbhayani/snake/HEAD/img/name.png -------------------------------------------------------------------------------- /img/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitbbhayani/snake/HEAD/img/play.png -------------------------------------------------------------------------------- /sounds/intro.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitbbhayani/snake/HEAD/sounds/intro.mp3 -------------------------------------------------------------------------------- /img/game-over.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitbbhayani/snake/HEAD/img/game-over.png -------------------------------------------------------------------------------- /food.js: -------------------------------------------------------------------------------- 1 | function Food(x, y, wx, wy) { 2 | this.x = x 3 | this.y = y 4 | 5 | this.draw = function() { 6 | fill(255, 0, 0); 7 | rect(this.x * wx, this.y * wy, wx, wy); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | height: 100%; 3 | background: #000; 4 | } 5 | 6 | body { 7 | margin: 0; 8 | display: flex; 9 | justify-content: center; 10 | align-items: center; 11 | } 12 | 13 | #sketch { 14 | border: 1px solid #fff; 15 | } -------------------------------------------------------------------------------- /preload.js: -------------------------------------------------------------------------------- 1 | var introMusic = null; 2 | var nameImage = null; 3 | var playImage = null; 4 | var gameOverImage = null; 5 | 6 | function preload() { 7 | introMusic = loadSound('/sounds/intro.mp3'); 8 | nameImage = loadImage('/img/name.png'); 9 | playImage = loadImage('/img/play.png'); 10 | gameOverImage = loadImage('/img/game-over.png'); 11 | } 12 | -------------------------------------------------------------------------------- /sketch.js: -------------------------------------------------------------------------------- 1 | p5.disableFriendlyErrors = true; // disables FES 2 | 3 | var game = null; 4 | var gameCanvas = null; 5 | 6 | var screenProperties = { 7 | width: 640, 8 | height: 480, 9 | } 10 | 11 | function setup() { 12 | var size = min(windowWidth - 10, windowHeight - 10, 640) 13 | screenProperties.width = size; 14 | screenProperties.height = size; 15 | gameCanvas = createCanvas(screenProperties.width, screenProperties.height); 16 | gameCanvas.parent('sketch'); 17 | game = new Game(screenProperties); 18 | } 19 | 20 | function windowResized() { 21 | resizeCanvas(windowWidth, windowHeight); 22 | } 23 | 24 | function draw() { 25 | game.run() 26 | } 27 | -------------------------------------------------------------------------------- /game.js: -------------------------------------------------------------------------------- 1 | function Game(screenProperties) { 2 | this.introScreen = new IntroScreen(screenProperties, this) 3 | this.playgroundScreen = new PlaygroundScreen(screenProperties, this) 4 | 5 | this.currentScreen = this.introScreen; 6 | 7 | this.run = function() { 8 | frameRate(10) 9 | this.currentScreen.draw() 10 | } 11 | 12 | this.changeScreen = function(name) { 13 | if (name === 'PlaygroundScreen') { 14 | this.currentScreen = this.playgroundScreen; 15 | } else { 16 | this.introScreen = this.introScreen; 17 | } 18 | } 19 | 20 | this.keyPressed = function(keyCode) { 21 | if (this.currentScreen.keyPressed) { 22 | this.currentScreen.keyPressed(keyCode) 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /screens/intro.js: -------------------------------------------------------------------------------- 1 | function IntroScreen(screenProperties, gameInstance) { 2 | noLoop(); 3 | 4 | introMusic.play(); 5 | introMusic.loop(); 6 | 7 | this._gotoPlaygroundScreen = function() { 8 | clear() 9 | introMusic.stop(); 10 | gameInstance.changeScreen('PlaygroundScreen'); 11 | }.bind(this) 12 | 13 | this._drawNameImage = function() { 14 | var width = min(600, screenProperties.width/2); 15 | var height = (nameImage.height / nameImage.width) * width; 16 | var x = screenProperties.width/2 - width/2; 17 | var y = max(screenProperties.height/2 - height, 0); 18 | 19 | image(nameImage, x, y, width, height); 20 | } 21 | 22 | this._drawPlayImage = function() { 23 | var width = min(200, screenProperties.width/2); 24 | var height = (playImage.height / playImage.width) * width; 25 | var x = screenProperties.width/2 - width/2; 26 | var y = max(screenProperties.height/2, 0); 27 | 28 | image(playImage, x, y, width, height); 29 | } 30 | 31 | this.keyPressed = function(keyCode) { 32 | if (keyCode === ENTER) { 33 | this._gotoPlaygroundScreen() 34 | } 35 | } 36 | 37 | this.draw = function() { 38 | background(0, 0, 0); 39 | this._drawNameImage(); 40 | this._drawPlayImage(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /snake.js: -------------------------------------------------------------------------------- 1 | function SnakeBody(x, y, wx, wy) { 2 | this.x = x 3 | this.y = y 4 | 5 | this.draw = function() { 6 | fill(255, 255, 255); 7 | rect(this.x * wx, this.y * wy, wx, wy); 8 | } 9 | } 10 | 11 | function Snake(rows, cols, wx, wy) { 12 | this.directionX = 1; 13 | this.directionY = 0; 14 | 15 | var head = new SnakeBody(10, 10, wx, wy); // center 16 | var tail = new SnakeBody(9, 10, wx, wy); // one behind 17 | 18 | this.elements = [ 19 | head, 20 | tail, 21 | ] 22 | 23 | this.move = function() { 24 | var head = this.elements[0]; 25 | var tail = this.elements[this.elements.length - 1] 26 | 27 | tail.x = head.x + this.directionX; 28 | tail.y = head.y + this.directionY; 29 | 30 | this.elements.unshift(this.elements.pop()) 31 | }.bind(this) 32 | 33 | this.changeDirection = function(dirX, dirY) { 34 | if (dirX && dirX === this.directionX * -1) { 35 | return 36 | } 37 | if (dirY && dirY === this.directionY * -1) { 38 | return 39 | } 40 | this.directionX = dirX; 41 | this.directionY = dirY; 42 | } 43 | 44 | this.collided = function() { 45 | var head = this.elements[0]; 46 | if (head.x < 0 || head.y < 0 || head.x >= rows || head.y >= cols) { 47 | return true; 48 | } 49 | return this.elements.slice(1).find(x => x.x === head.x && x.y === head.y) 50 | } 51 | 52 | this.eat = function(food) { 53 | var head = this.elements[0]; 54 | if (head.x === food.x && head.y === food.y) { 55 | this.elements.splice(1, 0, new SnakeBody(head.x, head.y, wx, wy)); 56 | head.x += this.directionX; 57 | head.y += this.directionY; 58 | return true; 59 | } 60 | return false; 61 | }.bind(this) 62 | 63 | this.isSnakeCell = function(x, y) { 64 | return this.elements.find(e => e.x === x && e.y === y); 65 | }.bind(this) 66 | 67 | this.stop = function() { 68 | this.directionX = 0; 69 | this.directionY = 0; 70 | } 71 | 72 | this.draw = function() { 73 | this.elements.forEach(x => x.draw()) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /screens/playground.js: -------------------------------------------------------------------------------- 1 | function PlaygroundScreen(screenProperties, gameInstance) { 2 | this.isGameOn = false; 3 | this.snake = null; 4 | this.food = null 5 | this.rows = 50; 6 | this.cols = 50; 7 | this.wx = int(screenProperties.width/this.rows) 8 | this.wy = int(screenProperties.height/this.cols) 9 | this.score = 0; 10 | 11 | gameCanvas.resize(this.rows * this.wx, this.cols * this.wy) 12 | 13 | this._startGame = function() { 14 | this.snake = new Snake(this.rows, this.cols, this.wx, this.wy) 15 | this._spawnFood(); 16 | this.isGameOn = true; 17 | this.score = 0; 18 | loop(); 19 | }.bind(this) 20 | 21 | this._spawnFood = function() { 22 | var x = 0, y = 0; 23 | do { 24 | x = int(Math.random() * this.rows); 25 | y = int(Math.random() * this.cols); 26 | } while(this.snake.isSnakeCell(x, y)); 27 | this.food = new Food(x, y, this.wx, this.wy); 28 | }.bind(this) 29 | 30 | this.keyPressed = function(keyCode) { 31 | if (keyCode === UP_ARROW) { 32 | this.snake.changeDirection(0, -1); 33 | } else if (keyCode === DOWN_ARROW) { 34 | this.snake.changeDirection(0, 1); 35 | } else if (keyCode === LEFT_ARROW) { 36 | this.snake.changeDirection(-1, 0); 37 | } else if (keyCode === RIGHT_ARROW) { 38 | this.snake.changeDirection(1, 0); 39 | } else if (keyCode === ENTER) { 40 | if (!this.isGameOn) { 41 | this._startGame(); 42 | } 43 | } 44 | } 45 | 46 | this._drawGameOver = function() { 47 | var width = min(600, screenProperties.width/2); 48 | var height = (gameOverImage.height / gameOverImage.width) * width; 49 | var x = screenProperties.width/2 - width/2; 50 | var y = max(screenProperties.height/2 - height, 0); 51 | 52 | image(gameOverImage, x, y, width, height); 53 | } 54 | 55 | this._drawPlayButton = function() { 56 | var width = min(200, screenProperties.width/2); 57 | var height = (playImage.height / playImage.width) * width; 58 | var x = screenProperties.width/2 - width/2; 59 | var y = max(screenProperties.height/2, 0); 60 | 61 | image(playImage, x, y, width, height); 62 | }.bind(this) 63 | 64 | this._drawScore = function() { 65 | textSize(24); 66 | textFont('monospace'); 67 | text(this.score, 10, 30); 68 | fill(255, 255, 255); 69 | }.bind(this) 70 | 71 | this.draw = function() { 72 | background(0, 0, 0); 73 | this.snake.move(); 74 | this.snake.draw(); 75 | this._drawScore(); 76 | 77 | if (this.snake.collided()) { 78 | this.isGameOn = false; 79 | this.snake.stop(); 80 | this._drawGameOver(); 81 | this._drawPlayButton(); 82 | noLoop(); 83 | } 84 | 85 | if (this.snake.eat(this.food)) { 86 | this._spawnFood() 87 | this.score+=1; 88 | } 89 | 90 | this.food.draw(); 91 | }.bind(this) 92 | 93 | this._startGame(); 94 | } 95 | --------------------------------------------------------------------------------