/*snake game by Chase last edited 4/5/2018*/
/*lib*/
const getRandomInt=max=>Math.floor(Math.random() * Math.floor(max));
const getBetweenInt=(min, max)=> {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
const posMatch=(pos1,pos2)=>pos1.x==pos2.x&&pos1.y==pos2.y;
const arrayMatch=(array,item)=>{
for(let x of array) if(x.x==item.x&&x.y==item.y) return true;
}
/*initial*/
const multiplier=10;
const speed=200;
const canvas={
offset:{
x:10,
y:10
},
width:myCanvas.width/multiplier,
height:myCanvas.height/multiplier,
penColor:color=>ctx.fillStyle=color,
fill:(x,y)=>ctx.fillRect(x*multiplier,y*multiplier,multiplier,multiplier)
}
const food={
pos:{},
create:_=>{
food.pos={
x:getRandomInt(canvas.width),
y:getRandomInt(canvas.height)
}
if(arrayMatch(snake.body,food.pos)) food.create();
else food.draw(food.pos);
},
draw:({x,y})=>{
canvas.penColor("yellow");
canvas.fill(x,y);
}
};
const snake={
head:{},
getTail:x=>x=snake.body[0],
dir:{
current:"",
pre:""
},
grow:false,
body:[],
length:5,
draw:({x,y})=>{
canvas.penColor("white");
snake.body.push({x,y});
canvas.fill(x,y);
},
erase:({x,y})=>{
canvas.penColor("gray");
snake.body.splice(0,1);
canvas.fill(x,y);
},
next:{}
};
const ctx = myCanvas.getContext("2d");
const dir=["up","down","left","right"];
let move=_=>{
let crash;
switch(snake.dir.current){
case "up":
snake.next={
x:snake.head.x,
y:snake.head.y-1
};
crash=snake.next.y<0;
snake.dir.pre="up";
break;
case "down":
snake.next={
x:snake.head.x,
y:snake.head.y+1
};
crash=snake.next.y==canvas.height;
snake.dir.pre="down";
break;
case "left":
snake.next={
x:snake.head.x-1,
y:snake.head.y
};
crash=snake.next.x<0;
snake.dir.pre="left";
break;
case "right":
snake.next={
x:snake.head.x+1,
y:snake.head.y
};
crash=snake.next.x==canvas.width;
snake.dir.pre="right";
break;
}
if(crash||arrayMatch(snake.body,snake.next)){
clearInterval(intv);
start.disabled="";
return;
};
snake.draw(snake.head=snake.next);
if(snake.grow){
snake.grow=false;
score.innerText=Number(score.innerText)+1;
food.create();
}
else snake.erase(snake.getTail());
}
const directionMapping = {
'up': snake.draw.bind(null, {x:snake.head.x, y:--snake.head.y}),
'down': snake.draw.bind(null, {x:snake.head.x, y:++snake.head.y}),
'left': snake.draw.bind(null, {x:--snake.head.x, y:snake.head.y}),
'right': snake.draw.bind(null, {x:++snake.head.x, y:snake.head.y})
};
const initCreate=_=>{
if (snake.dir.current in directionMapping) {
directionMapping[snake.dir.current]();
}
}
onkeydown=e=>{
switch(e.keyCode){
case 37:
if(snake.dir.pre=="up"||snake.dir.pre=="down") snake.dir.current="left";
break;
case 38:
if(snake.dir.pre=="left"||snake.dir.pre=="right") snake.dir.current="up";
break;
case 39:
if(snake.dir.pre=="up"||snake.dir.pre=="down") snake.dir.current="right";
break;
case 40:
if(snake.dir.pre=="left"||snake.dir.pre=="right") snake.dir.current="down";
break;
}
}
let intv;
start.onclick=_=>{
start.disabled="disabled";
canvas.penColor("gray");
ctx.fillRect(0,0,myCanvas.width,myCanvas.height);
snake.body=[];
snake.head={
x:getBetweenInt(canvas.offset.x,canvas.width-canvas.offset.x),
y:getBetweenInt(canvas.offset.y,canvas.height-canvas.offset.y)
};
snake.dir.current=dir[getRandomInt(dir.length)];
food.create();
for(let i=0;i<snake.length;i++) initCreate();
intv=setInterval(()=>{
if(posMatch(snake.head,food.pos)) snake.grow=true;
move();
},speed);
}
start.click();
<!DOCTYPE html>
<html>
<head>
<title>Snake 0.8</title>
</head>
<body>
<div>
<canvas id="myCanvas" width="300" height="300" style="border:1px solid black;background:gray;"></canvas>
</div>
<div>
<button id="start">Start</button>
<span>Score:<span id="score">0</span></span>
</div>
<script src="js/main.js"></script>
</body>
</html>