var w,h,el,g,my={};var snake;function snakeMain(mode){my.version='0.64';my.typ=typeof mode!=='undefined'?mode:'bla';my.hdrHt=40 w=Math.min(500,window.innerWidth-20,window.innerHeight-my.hdrHt) h=w my.xN=20 my.sz=w/my.xN my.wmax=Math.floor(w/my.sz)-1 my.hmax=Math.floor(h/my.sz)-1 my.hz=10 my.millisecs=1000/my.hz my.bgClr='hsla(0,0%,15%,1)' my.edgeTypes=['right','left','wrap','bounce','reset'] my.edgeType=my.edgeTypes[0];my.bgs=['black','coords'] my.food=new Pt(0,0) my.prevFood=new Pt(0,0) my.soundQ=true my.hiScore=0 console.log('my',my) my.dummy=[playToggle] var s='';my.sndHome=(document.domain=='localhost')?'/mathsisfun/images/sounds/':'/images/sounds/' s+='';s+='';my.snds=[];s+='
';s+='
';s+='
Press Play to Start
' s+='';s+='';s+=' ' s+=playHTML(36) s+='
';s+='
';s+='';s+='
';s+=optPopHTML() s+='
© 2019 MathsIsFun.com v'+my.version+'
';s+='
' document.write(s);el=document.getElementById('canvas1');var ratio=3;el.width=w*ratio;el.height=h*ratio;el.style.width=w+"px";el.style.height=h+"px";g=el.getContext("2d");g.setTransform(ratio,0,0,ratio,0,0);this.clrs=[["Blue",'#0000FF'],["Red",'#FF0000'],["Black",'#000000'],["Green",'#00cc00'],["Orange",'#FFA500'],["Slate Blue",'#6A5ACD'],["Lime",'#00FF00'],["Spring Green",'#00FF7F'],["Teal",'#008080'],["Gold",'#ffd700'],["Med Purple",'#aa00aa'],["Light Blue",'#ADD8E6'],["Navy",'#000080'],["Purple",'#800080'],["Dark SeaGreen",'#8FBC8F']];console.log("my.typ",my.typ);window.addEventListener("keydown",key,false);el.addEventListener("touchstart",touchStart,false) el.addEventListener("mousedown",mouseDown,false) snake=new Snake();foodLocn() radioPress('edge',0) my.playQ=false playToggle() playToggle()} function anim(){if(my.playQ){draw() requestAnimationFrame(anim);}} function gameNew(){draw()} function key(ev){var keyCode=ev.keyCode;console.log("key",keyCode);switch(keyCode){case 37:case 65:case 100:case 52:snake.dir(-1,0) ev.preventDefault();break;case 39:case 68:case 102:case 54:snake.dir(1,0) ev.preventDefault();break;case 38:case 87:case 104:case 56:snake.dir(0,-1) ev.preventDefault();break;case 40:case 83:case 98:case 50:snake.dir(0,1) ev.preventDefault();break;case 32:playToggle() ev.preventDefault();break;default:}} function touchStart(ev){var touch=ev.targetTouches[0];ev.clientX=touch.clientX;ev.clientY=touch.clientY;ev.touchQ=true;mouseDown(ev)} function mouseDown(ev){var bRect=el.getBoundingClientRect();var mousex=ev.clientX-bRect.left var mousey=ev.clientY-bRect.top var dx=mousex-(snake.x+0.5)*my.sz var dy=mousey-(snake.y+0.5)*my.sz if(Math.abs(dx)>Math.abs(dy)){snake.dir(dx/Math.abs(dx),0)}else{snake.dir(0,dy/Math.abs(dy))}} function foodLocn(){my.prevFood={x:my.food.x,y:my.food.y} do{my.food=new Pt(randomInt(0,my.wmax),randomInt(0,my.hmax));}while(my.food.x==my.prevFood.x||my.food.y==my.prevFood.y) console.log('food',my.sz,my.food)} function randomInt(min,max){return Math.floor(Math.random()*(max-min+1))+min;} function Pt(x,y){this.x=x;this.y=y;return this;} function draw(){g.clearRect(0,0,g.canvas.width,g.canvas.height) g.fillStyle=my.bgClr g.beginPath() g.rect(0,0,g.canvas.width,g.canvas.height);g.fill();g.fillStyle='rgba(255,255,255,0.02)' for(var i=0;i=1){my.prev+=Math.floor(delta)*my.millisecs snake.update();if(snake.eat(my.food)){foodLocn();} snake.touched();} snake.show();g.fillStyle='lightgreen' g.beginPath() g.arc((my.food.x+0.5)*my.sz,(my.food.y+0.5)*my.sz,my.sz/2,0,2*Math.PI);g.fill();g.fillStyle='white' g.beginPath() g.arc((my.food.x+0.25)*my.sz,(my.food.y+0.335)*my.sz,my.sz*0.1,0,2*Math.PI);g.arc((my.food.x+0.3)*my.sz,(my.food.y+0.275)*my.sz,my.sz*0.1,0,2*Math.PI);g.arc((my.food.x+0.35)*my.sz,(my.food.y+0.245)*my.sz,my.sz*0.1,0,2*Math.PI);g.arc((my.food.x+0.4)*my.sz,(my.food.y+0.215)*my.sz,my.sz*0.1,0,2*Math.PI);g.fill();g.beginPath() g.fillStyle='black' g.strokeStyle='white' g.arc(my.food.x*my.sz,(my.food.y+1)*my.sz,2,0,2*Math.PI) g.fill();g.stroke() g.beginPath() g.textAlign='left' g.fillStyle='white' var s=my.food.x+', '+(my.hmax-my.food.y) var x=(my.food.x)*my.sz var y=(my.food.y+1)*my.sz+12 if(my.food.y==my.hmax){g.textAlign='left' x=(my.food.x+1)*my.sz+3 y=(my.food.y+0.5)*my.sz+4 if(my.food.x==my.wmax){g.textAlign='right' x=my.food.x*my.sz-3}} g.font='10px Arial' g.fillText(s,x,y);g.fill();} function Snake(){this.x=0;this.y=0;this.speed={x:1,y:0} this.prevSpeed={x:1,y:0} this.total=0;this.tail=[];this.eat=function(pos){if(this.x==pos.x&&this.y==pos.y){this.total++;scoreUpdate(this.total+1) soundPlay('sndEat') return true;}else{return false;}} this.dir=function(x,y){this.prevSpeed.x=this.speed.x this.prevSpeed.y=this.speed.y this.speed.x=x this.speed.y=y} this.touched=function(){if(this.speed.x*this.prevSpeed.x==-1)return if(this.speed.y*this.prevSpeed.y==-1)return for(var i=0;i=1){this.tail[this.total-1]=new Pt(this.x,this.y);} this.x+=this.speed.x this.y+=this.speed.y var lr=1 if(my.edgeType=='left')lr=-1 if(my.edgeType=='left or right'&&Math.random()>0.5)lr=-1 if(this.x>my.wmax){switch(my.edgeType){case 'left':case 'right':case 'left or right':case 'reset':if(my.edgeType=='reset')this.reset() this.x=my.wmax this.dir(0,lr) this.y+=this.speed.y;break case 'bounce':this.dir(-1,0) break case 'wrap':this.x=0 break}} if(this.x<0){switch(my.edgeType){case 'left':case 'right':case 'left or right':case 'reset':if(my.edgeType=='reset')this.reset() this.x=0 this.dir(0,-lr) this.y+=this.speed.y;break case 'bounce':this.dir(1,0) break case 'wrap':this.x=my.wmax break}} if(this.y>my.hmax){switch(my.edgeType){case 'left':case 'right':case 'left or right':case 'reset':if(my.edgeType=='reset')this.reset() this.y=my.hmax this.dir(-lr,0) this.x+=this.speed.x;break case 'bounce':this.dir(0,-1) break case 'wrap':this.y=0 break}} if(this.y<0){switch(my.edgeType){case 'left':case 'right':case 'left or right':case 'reset':if(my.edgeType=='reset')this.reset() this.y=0 this.dir(lr,0) this.x+=this.speed.x;break case 'bounce':this.dir(0,1) break case 'wrap':this.y=my.hmax break}}} this.show=function(){g.strokeStyle='black' g.fillStyle='yellow' g.font='14px Arial' g.textAlign='center' var len=this.tail.length for(var i=0;i<=len;i++){var bit=this if(imy.hiScore){my.hiScore=n var div=document.getElementById('hiscore') div.innerHTML='High Score = '+n}} function onHzChg(n,v){v=Number(v);my.hz=v my.millisecs=1000/my.hz document.getElementById('hz').innerHTML=v+' per sec'} function onXNChg(n,v){v=Number(v);my.xN=v my.sz=w/my.xN my.wmax=Math.floor(w/my.sz)-1 my.hmax=Math.floor(h/my.sz)-1 foodLocn() document.getElementById('xN').innerHTML=v+' squares' draw()} function onEdgeChg(n){my.edgeType=my.edgeTypes[n];} function playHTML(w){var s='';s+='';s+='';return s;} function playToggle(){var btn='playBtn';if(my.playQ){my.playQ=false;document.getElementById(btn).classList.add("play");document.getElementById(btn).classList.remove("pause");}else{my.playQ=true;document.getElementById(btn).classList.add("pause");document.getElementById(btn).classList.remove("play");my.prev=performance.now() anim();}} function soundBtnHTML(){var s='' s+='' s+='
' return s} function soundToggle(){var btn='sound' if(my.soundQ){my.soundQ=false document.getElementById(btn).classList.add("mute")}else{my.soundQ=true document.getElementById(btn).classList.remove("mute")}} function soundPlay(id,simulQ){if(!my.soundQ)return simulQ=typeof simulQ!=='undefined'?simulQ:false if(simulQ){if(id.length>0)document.getElementById(id).play()}else{my.snds.push(id) soundPlayQueue(id)}} function soundPlayQueue(id){var div=document.getElementById(my.snds[0]) div.play() div.onended=function(){my.snds.shift();if(my.snds.length>0)soundPlayQueue(my.snds[0]);};} function optPopHTML(){var s='';s+='
';my.soundQ=true s+=' ' s+=soundBtnHTML() s+='
';s+='
Speed:
' s+='';s+='
'+my.hz+' per sec
';s+='
Size:
' s+='';s+='
'+my.xN+' squares
';s+=radioHTML('Edge Type','edge',my.edgeTypes,'onEdgeChg') s+='
';s+='
';s+='';s+='';s+='
';s+='
';return s;} function optPop(){var pop=document.getElementById('optpop');pop.style.transitionDuration="0.3s";pop.style.opacity=1;pop.style.zIndex=12;pop.style.left='10px';} function optYes(){var pop=document.getElementById('optpop');pop.style.opacity=0;pop.style.zIndex=1;pop.style.left='-999px';gameNew();} function optNo(){var pop=document.getElementById('optpop');pop.style.opacity=0;pop.style.zIndex=1;pop.style.left='-999px';} function radioHTML(prompt,id,lbls,func){var s='';s+='
';s+=prompt+':';s+='
';for(var i=0;i';s+='';} s+='
';return s;} function radioPress(id,n){var div=document.getElementById(id+n);div.checked=true;}