added idle animations as per original Neko program

This commit is contained in:
2025-12-18 00:27:34 +08:00
parent a7da171b21
commit 2d11567fc1

View File

@@ -10,6 +10,8 @@
let nekoPosY = 32; let nekoPosY = 32;
let frameCount = 0; let frameCount = 0;
let idleTime = 0; let idleTime = 0;
let idleAnimation: string | null = null;
let idleAnimationFrame = 0;
let currentSprite = { x: -3, y: -3 }; // idle sprite initially let currentSprite = { x: -3, y: -3 }; // idle sprite initially
const nekoSpeed = 10; const nekoSpeed = 10;
@@ -86,6 +88,67 @@
currentSprite = { x: sprite[0] * 32, y: sprite[1] * 32 }; currentSprite = { x: sprite[0] * 32, y: sprite[1] * 32 };
} }
function resetIdleAnimation() {
idleAnimation = null;
idleAnimationFrame = 0;
}
function idle() {
idleTime += 1;
// every ~ 20 seconds (idleTime increments every frame, with ~10 frames/second, so ~200 frames)
if (
idleTime > 10 &&
Math.floor(Math.random() * 200) == 0 &&
idleAnimation == null
) {
let availableIdleAnimations = ["sleeping", "scratchSelf"];
if (nekoPosX < 32) {
availableIdleAnimations.push("scratchWallW");
}
if (nekoPosY < 32) {
availableIdleAnimations.push("scratchWallN");
}
if (nekoPosX > window.innerWidth - 32) {
availableIdleAnimations.push("scratchWallE");
}
if (nekoPosY > window.innerHeight - 32) {
availableIdleAnimations.push("scratchWallS");
}
idleAnimation =
availableIdleAnimations[
Math.floor(Math.random() * availableIdleAnimations.length)
];
}
switch (idleAnimation) {
case "sleeping":
if (idleAnimationFrame < 8) {
setSprite("tired", 0);
break;
}
setSprite("sleeping", Math.floor(idleAnimationFrame / 4));
if (idleAnimationFrame > 192) {
resetIdleAnimation();
}
break;
case "scratchWallN":
case "scratchWallS":
case "scratchWallE":
case "scratchWallW":
case "scratchSelf":
setSprite(idleAnimation, idleAnimationFrame);
if (idleAnimationFrame > 9) {
resetIdleAnimation();
}
break;
default:
setSprite("idle", 0);
return;
}
idleAnimationFrame += 1;
}
function frame(timestamp: number) { function frame(timestamp: number) {
if (!lastFrameTimestamp) { if (!lastFrameTimestamp) {
lastFrameTimestamp = timestamp; lastFrameTimestamp = timestamp;
@@ -108,8 +171,7 @@
// If close enough, stop moving and idle // If close enough, stop moving and idle
if (distance < nekoSpeed || distance < 48) { if (distance < nekoSpeed || distance < 48) {
setSprite("idle", 0); idle();
idleTime += 1;
return; return;
} }
@@ -122,6 +184,8 @@
} }
idleTime = 0; idleTime = 0;
idleAnimation = null;
idleAnimationFrame = 0;
// Calculate direction // Calculate direction
let direction = ""; let direction = "";