diff options
author | Galin Simeonov <gts@volconst.com> | 2021-09-29 04:17:58 +0300 |
---|---|---|
committer | Galin Simeonov <gts@volconst.com> | 2021-09-29 04:17:58 +0300 |
commit | d4c75508509eb46c2647488f8d111373abd80a22 (patch) | |
tree | c1a2be2f5f22746fccc62cc116063a56fc39e81c /snek.js | |
parent | 20c04c8dec132112fdef2356a22890df8e064e91 (diff) | |
download | snek-d4c75508509eb46c2647488f8d111373abd80a22.tar.gz |
basic game functionality
Diffstat (limited to 'snek.js')
-rw-r--r-- | snek.js | 205 |
1 files changed, 201 insertions, 4 deletions
@@ -1,7 +1,14 @@ +let cursor = { + 'x' : 0, + 'y' : 0 +}; + let canvas; let context; + let mice; +let explosions; let drawInterval=20/1000; @@ -10,7 +17,22 @@ let micePerSecond=0.3; 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; @@ -26,23 +48,26 @@ function draw(timeStamp) 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() @@ -56,9 +81,11 @@ 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() @@ -69,7 +96,137 @@ 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) @@ -85,7 +242,7 @@ function drawMouse(mouse,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; @@ -165,3 +322,43 @@ function drawMouse(mouse,timeElapsed) 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; +} |