Advertisement
agunq

neko.js

May 28th, 2023
704
1
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. (function oneko() {
  3.     const nekoEl = document.createElement("div");
  4.     let nekoPosX = 32;
  5.     let nekoPosY = 32;
  6.     let mousePosX = 0;
  7.     let mousePosY = 0;
  8.     let frameCount = 0;
  9.     let idleTime = 0;
  10.     let idleAnimation = null;
  11.     let idleAnimationFrame = 0;
  12.     const nekoSpeed = 10;
  13.     const spriteSets = {
  14.         idle: [[-3, -3]],
  15.         alert: [[-7, -3]],
  16.         scratch: [
  17.             [-5, 0],
  18.             [-6, 0],
  19.             [-7, 0],
  20.         ],
  21.         tired: [[-3, -2]],
  22.         sleeping: [
  23.             [-2, 0],
  24.             [-2, -1],
  25.         ],
  26.         N: [
  27.             [-1, -2],
  28.             [-1, -3],
  29.         ],
  30.         NE: [
  31.             [0, -2],
  32.             [0, -3],
  33.         ],
  34.         E: [
  35.             [-3, 0],
  36.             [-3, -1],
  37.         ],
  38.         SE: [
  39.             [-5, -1],
  40.             [-5, -2],
  41.         ],
  42.         S: [
  43.             [-6, -3],
  44.             [-7, -2],
  45.         ],
  46.         SW: [
  47.             [-5, -3],
  48.             [-6, -1],
  49.         ],
  50.         W: [
  51.             [-4, -2],
  52.             [-4, -3],
  53.         ],
  54.         NW: [
  55.             [-1, 0],
  56.             [-1, -1],
  57.         ],
  58.     };
  59.     function create() {
  60.         nekoEl.id = "oneko";
  61.         nekoEl.style.width = "32px";
  62.         nekoEl.style.height = "32px";
  63.         nekoEl.style.position = "fixed";
  64.         nekoEl.style.backgroundImage = "url('./oneko.gif')";
  65.         nekoEl.style.imageRendering = "pixelated";
  66.         nekoEl.style.left = "16px";
  67.         nekoEl.style.top = "16px";
  68.  
  69.         document.body.appendChild(nekoEl);
  70.  
  71.         document.onmousemove = (event) => {
  72.             mousePosX = event.clientX;
  73.             mousePosY = event.clientY;
  74.         };
  75.  
  76.         window.onekoInterval = setInterval(frame, 100);
  77.     }
  78.  
  79.     function setSprite(name, frame) {
  80.         const sprite = spriteSets[name][frame % spriteSets[name].length];
  81.         nekoEl.style.backgroundPosition = `${sprite[0] * 32}px ${
  82.             sprite[1] * 32
  83.         }px`;
  84.     }
  85.  
  86.     function resetIdleAnimation() {
  87.         idleAnimation = null;
  88.         idleAnimationFrame = 0;
  89.     }
  90.  
  91.     function idle() {
  92.         idleTime += 1;
  93.  
  94.         // every ~ 20 seconds
  95.         if (
  96.             idleTime > 10 &&
  97.             Math.floor(Math.random() * 200) == 0 &&
  98.             idleAnimation == null
  99.         ) {
  100.             idleAnimation = ["sleeping", "scratch"][
  101.                 Math.floor(Math.random() * 2)
  102.             ];
  103.         }
  104.  
  105.         switch (idleAnimation) {
  106.             case "sleeping":
  107.                 if (idleAnimationFrame < 8) {
  108.                     setSprite("tired", 0);
  109.                     break;
  110.                 }
  111.                 setSprite("sleeping", Math.floor(idleAnimationFrame / 4));
  112.                 if (idleAnimationFrame > 192) {
  113.                     resetIdleAnimation();
  114.                 }
  115.                 break;
  116.             case "scratch":
  117.                 setSprite("scratch", idleAnimationFrame);
  118.                 if (idleAnimationFrame > 9) {
  119.                     resetIdleAnimation();
  120.                 }
  121.                 break;
  122.             default:
  123.                 setSprite("idle", 0);
  124.                 return;
  125.         }
  126.         idleAnimationFrame += 1;
  127.     }
  128.  
  129.     function frame() {
  130.         frameCount += 1;
  131.         const diffX = nekoPosX - mousePosX;
  132.         const diffY = nekoPosY - mousePosY;
  133.         const distance = Math.sqrt(diffX ** 2 + diffY ** 2);
  134.  
  135.         if (distance < nekoSpeed || distance < 48) {
  136.             idle();
  137.             return;
  138.         }
  139.  
  140.         idleAnimation = null;
  141.         idleAnimationFrame = 0;
  142.  
  143.         if (idleTime > 1) {
  144.             setSprite("alert", 0);
  145.             // count down after being alerted before moving
  146.             idleTime = Math.min(idleTime, 7);
  147.             idleTime -= 1;
  148.             return;
  149.         }
  150.  
  151.         direction = diffY / distance > 0.5 ? "N" : "";
  152.         direction += diffY / distance < -0.5 ? "S" : "";
  153.         direction += diffX / distance > 0.5 ? "W" : "";
  154.         direction += diffX / distance < -0.5 ? "E" : "";
  155.         setSprite(direction, frameCount);
  156.  
  157.         nekoPosX -= (diffX / distance) * nekoSpeed;
  158.         nekoPosY -= (diffY / distance) * nekoSpeed;
  159.  
  160.         nekoEl.style.left = `${nekoPosX - 16}px`;
  161.         nekoEl.style.top = `${nekoPosY - 16}px`;
  162.     }
  163.  
  164.     create();
  165. })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement