Added experiment for spawning items on a queue

This commit is contained in:
pfych 2024-09-02 18:41:15 +10:00
parent f57e627c93
commit 0dedb0ec6a
2 changed files with 141 additions and 0 deletions

View File

@ -11,3 +11,4 @@ Small micro-projects that fit into a single HTML file. Used to experiment and me
- [Animated background grid](./src/tiling.html) - [Animated background grid](./src/tiling.html)
- [Swipeable scrolling](./src/scrolling.html) - [Swipeable scrolling](./src/scrolling.html)
- [88x31](./src/88x31.html) - [88x31](./src/88x31.html)
- [Spawning queues](./src/spawning.html) - Fireworks!

140
src/spawning.html Normal file
View File

@ -0,0 +1,140 @@
<html>
<body>
<canvas id="render" width="1920" height="1080"></canvas>
</body>
<style>
canvas {
width: 100%;
}
</style>
<script>
const bulletRadius = 10;
const ctx = render.getContext("2d");
const { width, height } = render;
let _entities = [];
let _queue = [];
const batchToQueue = (queue, entities) => {
let _builtQueue = queue;
entities.forEach(
(entity) => (_builtQueue = pushToQueue(_builtQueue, entity)),
);
return _builtQueue;
};
const pushToQueue = (queue, entity) => {
return [{ ...entity, delay: performance.now() + entity.delay }, ...queue];
};
const pullFromQueue = (queue, entities, now) => {
const newEntities = [];
const actionedQueue = queue.filter((item) => {
if (item.delay < now) {
newEntities.push(item);
return false;
}
return true;
});
return {
queue: actionedQueue,
entities: [...newEntities, ...entities],
};
};
const spawnRandomBurst = (queue) => {
const pattern = [];
const x = Math.random() * (width - 32) + 32;
const y = Math.random() * (height - 32) + 32;
for (let i = 0; i <= 100; i++) {
pattern.push({
delay: (Math.random() * 10 + 1) * i,
x,
y,
speed: 2,
angle: Math.random() * 360,
color: `rgb(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255})`,
});
}
return batchToQueue(queue, pattern);
};
const moveBullets = (bullets, delta) => {
return bullets.map((bullet) => {
const speed = bullet.speed;
const rad = (bullet.angle * Math.PI) / 180;
return {
...bullet,
x: bullet.x + speed * Math.cos(rad),
y: bullet.y + speed * Math.sin(rad),
};
});
};
const renderBullets = (bullets, ctx) => {
bullets.forEach((bullet) => {
const { x, y } = bullet;
ctx.fillStyle = bullet.color;
ctx.fillRect(
x - bulletRadius / 2,
y - bulletRadius / 2,
bulletRadius,
bulletRadius,
);
});
return bullets;
};
const cullBullets = (bullets) => {
return bullets.filter(
(bullet) =>
!(
bullet.x > width ||
bullet.x < 0 ||
bullet.y > height ||
bullet.y < 0
),
);
};
let lastTickTime = performance.now();
let lastSpawnTime = performance.now();
const tick = (ms) => {
const delta = ms - lastTickTime;
ctx.fillStyle = "#000";
ctx.fillRect(0, 0, width, height);
if (lastTickTime > lastSpawnTime + 1000) {
lastSpawnTime = lastTickTime;
_queue = spawnRandomBurst(_queue);
}
const { queue, entities } = pullFromQueue(
_queue,
_entities,
lastTickTime + delta,
);
_queue = queue; // Set the queue to the new filtered queue
_entities = renderBullets(
moveBullets(cullBullets(entities), delta), // Pass in new entities here
ctx,
);
console.log("queue", _queue);
lastTickTime = performance.now();
requestAnimationFrame(tick);
};
requestAnimationFrame(tick);
</script>
</html>