Document

by jt3k

HTML

<canvas id="canvas"></canvas>

CSS

html,
body,
#canvas {
  width: 100%;
  height: 100%;
}

JavaScript

var canvas = document.getElementById('canvas');
var ctx;
var hero = {pos:{x:100,y:100},r:5,c:'red'};
var rat={x:hero.x,y:hero.y};
var foods=[];

var fps, fpsInterval, startTime, now, then, elapsed;

function startAnimating(fps) {
  fpsInterval = 1000 / fps;
  then = Date.now();
  startTime = then;
  animate();
}

function animate() {


  // calc elapsed time since last loop

  now = Date.now();
  elapsed = now - then;

  // if enough time has elapsed, draw the next frame

  if (elapsed > fpsInterval) {

    // Get ready for next frame by setting then=now, but also adjust for your
    // specified fpsInterval not being a multiple of RAF's interval (16.7ms)
    then = now - (elapsed % fpsInterval);

    var direct=vectorSub(rat,hero.pos);
    if(vectorMod(direct)>5){
      hero.pos = vectorAdd(hero.pos, vectorMultScalar(direct, elapsed*0.1/vectorMod(direct)));
    }

    foods.map((food,i) => {
      if(vectorMod(vectorSub(hero.pos, food.pos))<food.r+hero.r){
        hero.r++;
        foods.splice(i,1);
      }
    });

    if(foods.length<10){
      addFood();
    }

    ctx.clearRect(0,0,canvas.width,canvas.height);
    drawItem(hero);
    drawFoods();

  }

  // request another frame

  requestAnimationFrame(animate);
}


// Проверяем понимает ли браузер canvas
if (canvas.getContext) {
  ctx = canvas.getContext('2d'); // Получаем 2D контекст
}
document.body.addEventListener('mousemove', (e) => {
  rat.x=e.clientX;
  rat.y=e.clientY;
})

startAnimating(60);

function drawItem(item){
  ctx.strokeStyle = item.c; // Цвет обводки
  ctx.lineWidth = 3; // Ширина линии
  ctx.fillStyle = item.c; // Цвет заливки
  // Ниже выполняем рисование
  ctx.beginPath();
  ctx.arc(item.pos.x,item.pos.y,item.r,0,Math.PI * 2);
  ctx.closePath();
  ctx.fill();

}

function drawFoods(){
  foods.map(drawItem);
}

//длина вектора (Пифагор рулит)
function vectorMod(v){
  return Math.sqrt(v.x*v.x +...