summaryrefslogtreecommitdiffstats
path: root/snek.js
diff options
context:
space:
mode:
authorGalin Simeonov <gts@volconst.com>2021-09-29 04:17:58 +0300
committerGalin Simeonov <gts@volconst.com>2021-09-29 04:17:58 +0300
commitd4c75508509eb46c2647488f8d111373abd80a22 (patch)
treec1a2be2f5f22746fccc62cc116063a56fc39e81c /snek.js
parent20c04c8dec132112fdef2356a22890df8e064e91 (diff)
downloadsnek-d4c75508509eb46c2647488f8d111373abd80a22.tar.gz
basic game functionality
Diffstat (limited to 'snek.js')
-rw-r--r--snek.js205
1 files changed, 201 insertions, 4 deletions
diff --git a/snek.js b/snek.js
index 3f969da..49d14b3 100644
--- a/snek.js
+++ b/snek.js
@@ -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;
+}