3
\$\begingroup\$

My most recent project is this simple Snake game, and I would like to know what you think of it and if you have any suggestions.

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var keys = new Array([]);
var body = [ //Body of snake
	{
		"x": 6,
		"y": 0
	},
	{
		"x": 5,
		"y": 0
	},
	{
		"x": 4,
		"y": 0
	},
	{
		"x": 3,
		"y": 0
	},
	{
		"x": 2,
		"y": 0
	},
	{
		"x": 1,
		"y": 0
	}
];

var food = [ //I put this in an array in case I decide to have multiple apples on screen or multiple types of apples
	{
		"x":15,
		"y":15
	}
];

var snake = new Object({});
snake.allowedWhen = 1; //When snake.allowedCount reaches this number, the snake will move once
snake.allowedCount = 0;
snake.direction = "right";
snake.points = 0;
snake.startLength = 6;

var boardX = 1;
var boardY = 0;
var board = [];

var opacity = 1;

var Interval;

var graphicalDecay = false;
var rotCount = 0;

for (var load = 0;load < (40*40);load++){ //Generates board in board array
	if (boardY < 41){
		board.push(boardX + "x" + boardY);
		if (boardX == 40){
			boardY ++;
			boardX = 0;
		}
		boardX ++;
	}
}

function main(){
	//VIEW HANDLING
	Interval = setInterval(function(){
		
		for (var i = 0;i < board.length;i++){ //Draws board

		  ctx.fillStyle = "rgba(211,211,211,"+ opacity +")";
		  if (board[i]){
			  ctx.fillRect((board[i].split("x")[board[i].split("x").length - 2] * 15) - 1 ,(board[i].split("x")[board[i].split("x").length - 1] * 15) + 1,-14,14);
			  
		  }
			  
		}
		
		ctx.fillStyle = "black";
		for (var x = 0; x < body.length; x++){ //Draws snake
			if (body[x]){
				ctx.fillRect((body[x].x * 15) - 1 ,(body[x].y * 15) + 1,-14,14);
			}
		}
		
		ctx.fillStyle = "red";
		if (food[0]){ //Draws food
				ctx.fillRect((food[0].x * 15) - 1 ,(food[0].y * 15) + 1,-14,14);
			}
			
		if (body[0].x == food[0].x && body[0].y == food[0].y){ //Adds two segments after feeding
			body.push({
				"x": body[body.length - 1].x,
				"y": body[body.length - 1].y
			});
			body.push({
				"x": body[body.length - 1].x,
				"y": body[body.length - 1].y
			});
			snake.points++;
			if (opacity > 0.2){
				opacity -= 0.05;
				if (graphicalDecay){
					ctx.rotate(0.001);
					rotCount++;
				}	
			}
			document.getElementById("points").innerHTML = "Score: " + snake.points + "<br />Snake length: " + body.length; //Updates "score board"
			setFood();
		}
		
		for (var h = 2;h < body.length;h++){ //Loss message and food resetter (Yes I am thinking about just making a loss function)
			if (body[0].x == body[h].x && body[0].y == body[h].y){
				clearInterval(Interval);
				alert("You lost with a score of " + snake.points + " and a length of " + body.length);
			}
			if (food[0].x == body[h].x && food[0].y == body[h].y){
				setFood();
			}
		}
		
		if ((body[0].x > 40 || body[0].x < 1) || (body[0].y > 39 || body[0].y < 0)){ //Other loss message
			clearInterval(Interval);
			alert("You lost with a score of " + snake.points + " and a length of " + body.length);
		}
		
		snake.allowedCount ++;
		if (snake.allowedCount > snake.allowedWhen){ //Allows controlled intervals of snake movement
			move(snake.direction);
			snake.allowedCount = 0;
		}
	}, 32);
	
	function setFood(){ //Does what the function name suggests
		var x = Math.floor(Math.random() * 40),y = Math.floor(Math.random() * 40);
		if ((x > 40 || y > 40) || (x < 1 || y < 1)){
			x = 15, y = 15;
		}
		food[0].x = x;
		food[0].y = y;
	}
	
	function move(direction){ //Controls movement
		switch(direction){ //Pushes every object in the body array down and then removes the last object
			case "up":
				body.unshift(
				{
					"x": (body[0].x),
					"y": (body[0].y - 1)
				}
				);
				body.pop();
				break;
			case "down":
				body.unshift({
					"x": (body[0].x),
					"y": (body[0].y + 1)
				});
				body.pop();
				break;
			case "left":
				body.unshift({
					"x": (body[0].x - 1),
					"y": (body[0].y)
				});
				body.pop();
				break;
			case "right":
				body.unshift({
					"x": (body[0].x + 1),
					"y": (body[0].y)
				});
				body.pop();
				break;
		}
	}
	
	function doKeyDown(e){ //Keyboard input
	  keys[e.keyCode] = true;
	  input();
	}
					
	function doKeyUp(e){keys[e.keyCode] = false;}
	
	function setDir(direction){ //Prevents one from backslithering into one's self
		if (snake.direction == "right" && direction != "left")
			snake.direction = direction;
		if (snake.direction == "left" && direction != "right")
			snake.direction = direction;
		if (snake.direction == "up" && direction != "down")
			snake.direction = direction;
		if (snake.direction == "down" && direction != "up")
			snake.direction = direction;
	}
	
	function input(){ //Handles ur darn keystrokes, makes em' nice n' legible
		if (87 in keys && keys[87]) //up
			setDir("up");
		if (83 in keys && keys[83]) //down
			setDir("down");
		if (65 in keys && keys[65]) //left
			setDir("left");
		if (68 in keys && keys[68]) //right
			setDir("right");
	}
		
	window.addEventListener("keydown", doKeyDown, true);
	window.addEventListener("keyup", doKeyUp, true);
}
<!DOCTYPE HTML>
<html>
<head>
  <title>Snake</title>
	<style>
    body {
	  background:gray;
    }
	#points {
		float:right;
		font-size:2em;
	}
	</style>
	
	
	<body>
	  
	  <canvas id="canvas" style="margin-left:15%;border:2px solid blue;" width="600" height="600"></canvas>
	  <h2 id="points"><button onclick="main();this.style.opacity = 0;document.getElementById('points').innerHTML = 'Score: ' + snake.points + '<br />Snake length: ' + snake.startLength;">Start</button></h2>
	  <button onclick="location.reload();">Restart</button><button onclick="graphicalDecay = !graphicalDecay;">Enable graphical decay</button>
	  
	  
	</body>
	
	<script src="js/snake.js"></script>


</html>

\$\endgroup\$
  • \$\begingroup\$ I didn't found how to play, even though the code suggest using arrow keys. Is it a limitation of stackexchange snippets? Also hitting the restart button gave me Error {"message": "uncaught exception: out of memory", "filename": "", "lineno": 0, "colno": 0} \$\endgroup\$ – Mathias Ettinger Jul 4 '16 at 7:41
  • \$\begingroup\$ You use W,A,S,D to move and the restart button works fine for me. \$\endgroup\$ – Confettimaker Jul 5 '16 at 0:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.