F diff --git a/snek.js b/snek.js --- a/snek.js +++ b/snek.js+ let cursor = {+ 'x' : 0,+ 'y' : 0+ };+let canvas;let context;+let mice;+ let explosions;let drawInterval=20/1000;let normalMouseSpeed=3;let normalMouseSize=1;+ let maxNumberOfExplosionParticles=20;+ let minNumberOfExplosionParticles=5;+ let maxParticleSize=50;+ let maxExplosionAge=100;+let lastTimeStamp;++ let snake = {+ 'x':window.innerWidth/2,+ 'y':window.innerHeight/2+ };++ let health=10;++ let frameId;+function draw(timeStamp){let timeElapsed;context.clearRect(0, 0, canvas.width, canvas.height);+ drawExplosions(timeElapsed);drawMice(timeElapsed);+ drawSnake(timeElapsed);- window.requestAnimationFrame(draw);+ frameId=window.requestAnimationFrame(draw);}function createMouse(x,y,direction,speed,size){- return { 'x':x, 'y':y, 'direction':direction, 'speed':speed,'size':size ,'tailLag':0, 'animation':0, 'animationCounter':0 };+ return { 'x':x, 'y':y, 'direction':direction, 'speed':speed,'size':size ,'tailLag':0, 'animation':0, 'animationCounter':0, 'hitbox':size*90 };}function main(){initialise();- window.requestAnimationFrame(draw);+ frameId=window.requestAnimationFrame(draw);setInterval(spawnMouse,1000/micePerSecond);setInterval(cleanUpMice,100);+ setInterval(cleanUpBlood,maxExplosionAge);}function spawnMouse()canvas=document.getElementById("canvas1");context=canvas.getContext("2d");+ canvas.addEventListener('mousemove', e => { cursor.x=e.offsetX; cursor.y=e.offsetY; });mice=[];mice.push(createMouse(200,100,1,normalMouseSpeed,normalMouseSize));+ explosions=[];}function cleanUpMice()if(mice[i].y<-200 || mice[i].y>window.innerHeight+300 || mice[i].x<-100 || mice[i].x>window.innerWidth+300){mice.splice(i,1);+ --health;+ if(health==0)+ {+ window.cancelAnimationFrame(frameId);+ alert("Too many of the filthy rats escaped! Your snake died of despair.");+ }}+ else if(mice[i].x-mice[i].hitbox<snake.x && mice[i].x+mice[i].hitbox>snake.x && mice[i].y+mice[i].hitbox>snake.y && mice[i].y-mice[i].hitbox<snake.y)+ explosions.push( makeExplosion(mice.splice(i,1)[0]));+ }+ }+ function cleanUpBlood()+ {+ let i=0;+ for(i;i<explosions.length;++i)+ {+ if(explosions[i].animation>maxExplosionAge)+ explosions.splice(i,1);+ }+ }+ /*it is clear that I am bad at geometry :P*/+ function drawSnake(timeElapsed)+ {+ let distance;+ let vx;+ let vy;+ let wx;+ let wy;++ distance=Math.sqrt(Math.pow(window.innerWidth/2-snake.x,2) + Math.pow(window.innerHeight/2-snake.y,2));+ vx=(window.innerWidth/2-snake.x)/distance;+ vy=(window.innerHeight/2-snake.y)/distance;++ gravitate(snake,cursor,true,10000*(timeElapsed/drawInterval),100);+++ /*body*/+ context.beginPath();+ context.strokeStyle="#00FF00";+ context.moveTo(window.innerWidth/2,-10);+ context.bezierCurveTo(+ window.innerWidth/2,+ window.innerHeight/4,+ snake.x+vx*300,+ snake.y+vy*100,+ snake.x,+ snake.y+ );+ context.lineWidth=40;+ context.stroke();+ context.closePath();+++ /*head*/+ distance=Math.sqrt(Math.pow(vx*300,2) + Math.pow(vy*100,2));+ wx=(vx*300)/distance;+ wy=(vy*100)/distance;++ context.save();+++ context.translate(snake.x,snake.y);+ if(wx>0)+ {+ context.rotate(Math.PI-Math.acos(wy));+ }else+ {+ context.rotate(Math.PI+Math.acos(wy));+ }++ context.beginPath();+ context.ellipse(0,50,30,70,0,0,3*Math.PI);+ context.fillStyle = "#00FF00";+ context.fill();+ context.stroke();+ context.closePath();++ /*right eye*/+ context.beginPath();+ context.fillStyle="#FF0000"+ context.moveTo(20,80);+ context.lineTo(30,80);+ context.lineTo(15,100);+ context.fill();+ context.closePath();++ /*right eye*/+ context.beginPath();+ context.fillStyle="#FF0000"+ context.moveTo(-20,80);+ context.lineTo(-30,80);+ context.lineTo(-15,100);+ context.fill();+ context.closePath();+++ context.restore();++ }++ function drawExplosions(timeElapsed)+ {+ let i=0;+ for(i;i<explosions.length;++i)+ {+ drawExplosion(explosions[i],timeElapsed);+ }+ }+ function drawExplosion(explosion,timeElapsed)+ {+ let i=0;+ explosion.animation+=timeElapsed/drawInterval;+ for(i;i<explosion.particles.length;++i)+ {+ explosion.particles[i].x+=(1000/explosion.animation)*0.1*Math.cos(explosion.particles[i].direction);+ explosion.particles[i].y+=(1000/explosion.animation)*0.1*Math.sin(explosion.particles[i].direction);+++ context.fillStyle=`rgb(+ 255,+ ${Math.floor(255*(explosion.animation/(maxExplosionAge+30)))},+ ${Math.floor(255*(explosion.animation/(maxExplosionAge+30)))}++ )`;+ context.rect(+ explosion.particles[i].x,+ explosion.particles[i].y,+ maxParticleSize*explosion.particles[i].size,+ maxParticleSize*explosion.particles[i].size,+ );+ context.fill();}}function drawMice(timeElapsed)mouse.animationCounter+=drawInterval;mouse.x+=mouse.speed*(timeElapsed/drawInterval)*Math.cos(mouse.direction);mouse.y+=mouse.speed*(timeElapsed/drawInterval)*Math.sin(mouse.direction);- mouse.animation+=0.8*(timeElapsed/drawInterval);+ mouse.animation+=0.4*(timeElapsed/drawInterval);/*mouse.direction+=0.1;context.restore();}+ function gravitate(subject,gravitas,doesItPull,pullStrength,nearDistance)+ {+ let distance=Math.sqrt( (subject.x-gravitas.x)*(subject.x-gravitas.x) + (subject.y-gravitas.y)*(subject.y-gravitas.y));++ if(distance==0)+ {+ return ;+ }++ if(doesItPull==false)+ {+ subject.x+=(((subject.x-gravitas.x)*pullStrength)/(distance*distance));+ subject.y+=(((subject.y-gravitas.y)*pullStrength)/(distance*distance));+ }else+ {+ if(distance<=nearDistance)+ {+ subject.x=gravitas.x;+ subject.y=gravitas.y;+ }else+ {+ subject.x-=(((subject.x-gravitas.x)*pullStrength)/(distance*distance));+ subject.y-=(((subject.y-gravitas.y)*pullStrength)/(distance*distance));+ }++ }+ }+ function makeExplosion(mouse)+ {+ let ret={ 'mouse': mouse, 'animation':0, 'particles':[] };+ let numberOfParticles=Math.floor(Math.random()*(maxNumberOfExplosionParticles-minNumberOfExplosionParticles))+minNumberOfExplosionParticles;+ let i=0;++ for(i;i<numberOfParticles;++i)+ {+ ret.particles.push({ 'x':mouse.x , 'y':mouse.y, 'direction':Math.random()*2*Math.PI, 'size':Math.random() });+ }++ return ret;+ }F diff --git a/tags b/tags --- a/tags +++ b/tags!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/!_TAG_PROGRAM_URL https://ctags.io/ /official site/!_TAG_PROGRAM_VERSION 0.0.0 //- #canvas2 snek.css /^#canvas2 {$/;" i+ animation snek.js /^ let ret={ 'mouse': mouse, 'animation':0, 'particles':[] };$/;" p class:makeExplosion.retcanvas snek.js /^let canvas;$/;" vcanvas1 snek.html /^ <canvas id="canvas1"><\/canvas>$/;" I- canvas2 snek.html /^ <canvas id="canvas2"><\/canvas>$/;" I+ cleanUpBlood snek.js /^function cleanUpBlood()$/;" f signature:()+ cleanUpMice snek.js /^function cleanUpMice()$/;" f signature:()context snek.js /^let context;$/;" vcreateMouse snek.js /^function createMouse(x,y,direction,speed,size)$/;" f signature:(x,y,direction,speed,size)+ cursor snek.js /^let cursor = {$/;" cdraw snek.js /^function draw(timeStamp)$/;" f signature:(timeStamp)- drawInterval snek.js /^let drawInterval=1000\/30;$/;" v- drawMice snek.js /^function drawMice()$/;" f signature:()- drawMouse snek.js /^function drawMouse(mouse)$/;" f signature:(mouse)+ drawExplosion snek.js /^function drawExplosion(explosion,timeElapsed)$/;" f signature:(explosion,timeElapsed)+ drawExplosions snek.js /^function drawExplosions(timeElapsed)$/;" f signature:(timeElapsed)+ drawInterval snek.js /^let drawInterval=20\/1000;$/;" v+ drawMice snek.js /^function drawMice(timeElapsed)$/;" f signature:(timeElapsed)+ drawMouse snek.js /^function drawMouse(mouse,timeElapsed)$/;" f signature:(mouse,timeElapsed)+ drawSnake snek.js /^function drawSnake(timeElapsed)$/;" f signature:(timeElapsed)+ explosions snek.js /^let explosions;$/;" v+ gravitate snek.js /^function gravitate(subject,gravitas,doesItPull,pullStrength,nearDistance)$/;" f signature:(subject,gravitas,doesItPull,pullStrength,nearDistance)initialise snek.js /^function initialise()$/;" f signature:()lastTimeStamp snek.js /^let lastTimeStamp;$/;" vmain snek.js /^function main()$/;" f signature:()+ makeExplosion snek.js /^function makeExplosion(mouse)$/;" f signature:(mouse)+ maxExplosionAge snek.js /^let maxExplosionAge=100;$/;" v+ maxNumberOfExplosionParticles snek.js /^let maxNumberOfExplosionParticles=50;$/;" vmice snek.js /^let mice;$/;" vmicePerSecond snek.js /^let micePerSecond=0.3;$/;" v+ mouse snek.js /^ let ret={ 'mouse': mouse, 'animation':0, 'particles':[] };$/;" p class:makeExplosion.retnormalMouseSize snek.js /^let normalMouseSize=1;$/;" v- normalMouseSpeed snek.js /^let normalMouseSpeed=10;$/;" v+ normalMouseSpeed snek.js /^let normalMouseSpeed=3;$/;" v+ particles snek.js /^ let ret={ 'mouse': mouse, 'animation':0, 'particles':[] };$/;" p class:makeExplosion.ret+ ret snek.js /^ let ret={ 'mouse': mouse, 'animation':0, 'particles':[] };$/;" c class:makeExplosion+ snake snek.js /^let snake = { $/;" csnek.css snek.css 1;" Fsnek.html snek.html 1;" Fsnek.js snek.js 1;" FspawnMouse snek.js /^function spawnMouse()$/;" f signature:()+ x snek.js /^ 'x' : 0,$/;" p class:cursor+ x snek.js /^ 'x':window.innerWidth\/2,$/;" p class:snake+ y snek.js /^ 'y' : 0$/;" p class:cursor+ y snek.js /^ 'y':window.innerHeight\/2 $/;" p class:snake