From 922deee5892eef0e2bd12dbb75f8425f239c28eb Mon Sep 17 00:00:00 2001 From: Galin Simeonov Date: Wed, 29 Sep 2021 12:28:30 +0300 Subject: added lazor --- snek.js | 159 ++++++++++++++++++---- w | 456 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 587 insertions(+), 28 deletions(-) create mode 100644 w diff --git a/snek.js b/snek.js index 49d14b3..4e83075 100644 --- a/snek.js +++ b/snek.js @@ -10,28 +10,38 @@ let context; let mice; let explosions; -let drawInterval=20/1000; +const drawInterval=20/1000; let micePerSecond=0.3; +const chargeDepletionRate=200; let normalMouseSpeed=3; let normalMouseSize=1; -let maxNumberOfExplosionParticles=20; -let minNumberOfExplosionParticles=5; -let maxParticleSize=50; -let maxExplosionAge=100; +const maxNumberOfExplosionParticles=20; +const minNumberOfExplosionParticles=5; +const maxParticleSize=50; +const maxExplosionAge=100; + let lastTimeStamp; let snake = { 'x':window.innerWidth/2, - 'y':window.innerHeight/2 + 'y':window.innerHeight/2, + 'discharging': false, + 'direction' : 0 + }; let health=10; +let score=0; let frameId; +let snakeLaserId; + +let charge=0; +const chargeTipoffPoint=10; function draw(timeStamp) { @@ -46,15 +56,27 @@ function draw(timeStamp) canvas.width = window.innerWidth; canvas.height = window.innerHeight; + /*the only clear thing here is that I am very bad at geometry*/ context.clearRect(0, 0, canvas.width, canvas.height); + drawExplosions(timeElapsed); drawMice(timeElapsed); drawSnake(timeElapsed); + drawHealth(); frameId=window.requestAnimationFrame(draw); } +function drawHealth() +{ + context.save(); + context.font='48px serif'; + context.fillText(`Health: ${health}`,10,70); + context.font='48px serif'; + context.fillText(`Score: ${score}/30`,window.innerWidth-48*10,70); + context.restore(); +} function createMouse(x,y,direction,speed,size) { return { 'x':x, 'y':y, 'direction':direction, 'speed':speed,'size':size ,'tailLag':0, 'animation':0, 'animationCounter':0, 'hitbox':size*90 }; @@ -68,11 +90,13 @@ function main() setInterval(spawnMouse,1000/micePerSecond); setInterval(cleanUpMice,100); setInterval(cleanUpBlood,maxExplosionAge); + + setInterval(depleteCharge,chargeDepletionRate); } function spawnMouse() { - mice.push(createMouse(5+window.innerWidth*Math.random()*0.9,window.innerHeight+normalMouseSize*90,-Math.PI/2,normalMouseSpeed,normalMouseSize)); + mice.push(createMouse(5+window.innerWidth*Math.random()*0.9,window.innerHeight+normalMouseSize*90,-Math.PI/2,(normalMouseSpeed*(Math.random()+1)),normalMouseSize*(Math.random()+1))); } function initialise() @@ -86,7 +110,6 @@ function initialise() mice.push(createMouse(200,100,1,normalMouseSpeed,normalMouseSize)); explosions=[]; - } function cleanUpMice() { @@ -100,11 +123,20 @@ function cleanUpMice() if(health==0) { window.cancelAnimationFrame(frameId); - alert("Too many of the filthy rats escaped! Your snake died of despair."); + alert(`Too many of the filthy rats escaped! Your snake has died of despair. Your score is ${score}`); } } else if(mice[i].x-mice[i].hitboxsnake.x && mice[i].y+mice[i].hitbox>snake.y && mice[i].y-mice[i].hitboxchargeTipoffPoint && snake.discharging==false) + { + snake.discharging=true; + snakeLaserId=setInterval(cleanUpMice,drawInterval); + }else if(snake.discharging==true && charge<=0) + { + snake.discharging=false; + clearInterval(snakeLaserId); + } + if(snake.discharging==true) + { + gravitate(snake,{'x':Math.random()*window.innerWidth,'y':Math.random()*window.innerHeight/4},false,10000*(timeElapsed/drawInterval),1); + charge+=Math.abs(Math.asin(wx)-Math.asin(vx))*0.5; + }else + { + charge+=Math.abs(Math.asin(wx)-Math.asin(vx)); + } + + context.save(); + context.shadowBlur=charge; + context.shadowColor="yellow"; /*body*/ context.beginPath(); context.strokeStyle="#00FF00"; @@ -148,27 +206,34 @@ function drawSnake(timeElapsed) 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); + snake.direction=Math.atan2(vy,vx); + context.rotate(Math.PI/2+snake.direction); + /* if(wx>0) { - context.rotate(Math.PI-Math.acos(wy)); + snake.direction=Math.acos(wy); + context.rotate(Math.PI-snake.direction); }else { - context.rotate(Math.PI+Math.acos(wy)); + snake.direction=Math.acos(wy); + context.rotate(Math.PI+snake.direction); + } + */ + + if(snake.discharging==true) + { + context.beginPath(); + context.fillStyle="#FF0000"; + context.rect(-15,0,30,10000); + context.fill(); + context.closePath(); } + context.strokeStyle="#00FF00"; context.beginPath(); - context.ellipse(0,50,30,70,0,0,3*Math.PI); context.fillStyle = "#00FF00"; + context.ellipse(0,50,30,70,0,0,3*Math.PI); context.fill(); context.stroke(); context.closePath(); @@ -244,10 +309,10 @@ function drawMouse(mouse,timeElapsed) mouse.y+=mouse.speed*(timeElapsed/drawInterval)*Math.sin(mouse.direction); mouse.animation+=0.4*(timeElapsed/drawInterval); - /* - mouse.direction+=0.1; - if(mouse.direction>1) mouse.direction-=1; - */ + if(score>=0) + { + gravitate(mouse,snake,false,(timeElapsed/drawInterval)*500,10); + } context.save(); @@ -355,6 +420,7 @@ function makeExplosion(mouse) let numberOfParticles=Math.floor(Math.random()*(maxNumberOfExplosionParticles-minNumberOfExplosionParticles))+minNumberOfExplosionParticles; let i=0; + ++score; for(i;i=30) + { + window.cancelAnimationFrame(frameId); + alert("You are winner!"); + } +} diff --git a/w b/w new file mode 100644 index 0000000..e8db78b --- /dev/null +++ b/w @@ -0,0 +1,456 @@ + +let cursor = { + 'x' : 0, + 'y' : 0 +}; + +let canvas; +let context; + +let mice; +let explosions; + +const drawInterval=20/1000; + +let micePerSecond=0.3; +const chargeDepletionRate=200; + +const normalMouseSpeed=3; +const normalMouseSize=1; + +const maxNumberOfExplosionParticles=20; +const minNumberOfExplosionParticles=5; +const maxParticleSize=50; +const maxExplosionAge=100; + + +let lastTimeStamp; + +let snake = { + 'x':window.innerWidth/2, + 'y':window.innerHeight/2, + 'discharging': false, + 'direction' : 0 + +}; + +let health=10; +let score=0; + +let frameId; +let snakeLaserId; + +let charge=0; +const chargeTipoffPoint=10; + +function draw(timeStamp) +{ + let timeElapsed; + + if(lastTimeStamp==undefined) + lastTimeStamp=timeStamp; + + timeElapsed=Math.min((timeStamp-lastTimeStamp)/1000,0.1); + lastTimeStamp=timeStamp; + + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; + + /*the only clear thing here is that I am very bad at geometry*/ + context.clearRect(0, 0, canvas.width, canvas.height); + + + drawExplosions(timeElapsed); + drawMice(timeElapsed); + drawSnake(timeElapsed); + drawHealth(); + + frameId=window.requestAnimationFrame(draw); +} +function drawHealth() +{ + context.save(); + context.font='48px serif'; + context.fillText(`Health: ${health}`,10,70); + + context.font='48px serif'; + context.fillText(`Score: ${score}/30`,window.innerWidth-48*10,70); + context.restore(); +} +function createMouse(x,y,direction,speed,size) +{ + return { 'x':x, 'y':y, 'direction':direction, 'speed':speed,'size':size ,'tailLag':0, 'animation':0, 'animationCounter':0, 'hitbox':size*90 }; +} + + +function main() +{ + initialise(); + frameId=window.requestAnimationFrame(draw); + setInterval(spawnMouse,1000/micePerSecond); + setInterval(cleanUpMice,100); + setInterval(cleanUpBlood,maxExplosionAge); + + setInterval(depleteCharge,chargeDepletionRate); +} + +function spawnMouse() +{ + mice.push(createMouse(5+window.innerWidth*Math.random()*0.9,window.innerHeight+normalMouseSize*90,-Math.PI/2,(normalMouseSpeed*(Math.random()+1)),normalMouseSize*(Math.random()+1))); +} + +function initialise() +{ + + 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() +{ + let i=0; + for(i;iwindow.innerHeight+300 || mice[i].x<-100 || mice[i].x>window.innerWidth+300) + { + mice.splice(i,1); + --health; + } + else if(mice[i].x-mice[i].hitboxsnake.x && mice[i].y+mice[i].hitbox>snake.y && mice[i].y-mice[i].hitbox=30) + { + window.cancelAnimationFrame(frameId); + alert("You are winner!"); + } + } +} +function cleanUpBlood() +{ + let i=0; + for(i;imaxExplosionAge) + explosions.splice(i,1); + } +} +function drawSnake(timeElapsed) +{ + let distance; + let distance2; + let vx; + let vy; + let wx; + let wy; + + distance2=Math.sqrt(Math.pow(window.innerWidth/2-snake.x,2) + Math.pow(window.innerHeight/2-snake.y,2))+0.1; + wx=((window.innerWidth/2)-snake.x)/distance2; + + gravitate(snake,cursor,true,10000*(timeElapsed/drawInterval),100); + + distance=Math.sqrt(Math.pow(window.innerWidth/2-snake.x,2) + Math.pow(window.innerHeight/2-snake.y,2))+0.1; + vx=(window.innerWidth/2-snake.x)/distance; + vy=(window.innerHeight/2-snake.y)/distance; + + + if(charge>chargeTipoffPoint && snake.discharging==false) + { + snake.discharging=true; + snakeLaserId=setInterval(cleanUpMice,drawInterval); + }else if(snake.discharging==true && charge<=0) + { + snake.discharging=false; + clearInterval(snakeLaserId); + } + + if(snake.discharging==true) + { + gravitate(snake,{'x':Math.random()*window.innerWidth,'y':Math.random()*window.innerHeight/4},false,10000*(timeElapsed/drawInterval),1); + charge+=Math.abs(Math.asin(wx)-Math.asin(vx))*0.5; + }else + { + charge+=Math.abs(Math.asin(wx)-Math.asin(vx)); + } + + context.save(); + + context.shadowBlur=charge; + context.shadowColor="yellow"; + /*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(); + + context.translate(snake.x,snake.y); + snake.direction=Math.atan2(vy,vx); + context.rotate(Math.PI/2+snake.direction); + /* + if(wx>0) + { + snake.direction=Math.acos(wy); + context.rotate(Math.PI-snake.direction); + }else + { + snake.direction=Math.acos(wy); + context.rotate(Math.PI+snake.direction); + } + */ + + if(snake.discharging==true) + { + context.beginPath(); + context.fillStyle="#FF0000"; + context.rect(-15,0,30,10000); + context.fill(); + context.closePath(); + } + + context.strokeStyle="#00FF00"; + context.beginPath(); + context.fillStyle = "#00FF00"; + context.ellipse(0,50,30,70,0,0,3*Math.PI); + 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;i1) mouse.direction-=1; + */ + + context.save(); + + context.translate(mouse.x, mouse.y); + context.rotate(mouse.direction); + context.scale(mouse.size,mouse.size); + + /*body*/ + context.beginPath(); + context.ellipse(0,0,90,40,0,0,2*Math.PI); + context.fillStyle = "#8f8f8f"; + context.fill(); + context.stroke(); + context.closePath(); + /*right ear*/ + context.beginPath(); + context.arc(50, 20, 20, 0, Math.PI*1.5, false); + context.fillStyle = "#8f8f8f"; + context.fill(); + context.stroke(); + context.closePath(); + /*left ear*/ + context.beginPath(); + context.arc(50, -22, 20, 0,- Math.PI*1.5, true); + context.fillStyle = "#8f8f8f"; + context.fill(); + context.stroke(); + context.closePath(); + /*left eye*/ + context.beginPath(); + context.ellipse(80,7,5,3,-1/2,0,2*Math.PI); + context.fillStyle = "#000000"; + context.fill(); + context.closePath(); + /*right eye*/ + context.beginPath(); + context.ellipse(80,-7,5,3,1/2,0,2*Math.PI); + context.fillStyle = "#000000"; + context.fill(); + context.closePath(); + /*right wiskers*/ + context.beginPath(); + context.moveTo(89,0); + context.lineTo(95,20); + context.stroke(); + context.closePath(); + context.beginPath(); + context.moveTo(89,0); + context.lineTo(90,20); + context.stroke(); + context.closePath(); + /*left wiskers*/ + context.beginPath(); + context.moveTo(89,0); + context.lineTo(95,-20); + context.stroke(); + context.closePath(); + context.beginPath(); + context.moveTo(89,0); + context.lineTo(90,-20); + context.stroke(); + context.closePath(); + + /*tail*/ + context.beginPath(); + context.moveTo(-90,0); + context.bezierCurveTo(-100,0,-150,Math.cos(mouse.animation)*30,-200,Math.sin(mouse.animation)*10); + context.lineWidth+=2; + context.stroke(); + context.closePath(); + + 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; + + ++score; + for(i;i