···
// Extend the KAPLAYCtx type to include our addConfetti method
declare module "kaplay" {
-
addConfetti?: (pos: { x: number, y: number }) => GameObj[];
// Function to create a confetti effect at a position
-
export function addConfetti(k: KAPLAYCtx, pos: { x: number, y: number }) {
// Number of confetti particles
const PARTICLE_COUNT = 50;
-
[255, 255, 0], // Yellow
-
[255, 0, 255], // Magenta
-
[255, 165, 0], // Orange
-
[128, 0, 128], // Purple
const particles: GameObj[] = [];
for (let i = 0; i < PARTICLE_COUNT; i++) {
const color = COLORS[Math.floor(Math.random() * COLORS.length)];
const size = Math.random() * 8 + 2; // 2-10 pixels
// Random shape (circle or rect)
const isCircle = Math.random() > 0.5;
const angle = Math.random() * Math.PI * 2;
const speed = Math.random() * 400 + 100; // 100-500 pixels per second
const vx = Math.cos(angle) * speed;
const vy = Math.sin(angle) * speed - 200; // Initial upward boost
const rotSpeed = Math.random() * 10 - 5; // -5 to 5 radians per second
isCircle ? k.circle(size / 2) : k.rect(size, size / 2),
k.rotate(Math.random() * 360), // Random initial rotation
···
fadeStart: 0.7, // When to start fading (0.7 = 70% of lifespan)
// Update function for the particle
particle.onUpdate(() => {
// Update position based on velocity
particle.pos.x += particle.vx * k.dt();
particle.pos.y += particle.vy * k.dt();
particle.vy += particle.gravity * k.dt();
particle.angle += particle.rotSpeed * k.dt() * 60;
particle.lifespan -= k.dt();
if (particle.lifespan < particle.fadeStart) {
particle.opacity = Math.max(0, particle.lifespan / particle.fadeStart);
// Destroy when lifespan is over
if (particle.lifespan <= 0) {
particles.push(particle);
···
export function confettiPlugin(k: KAPLAYCtx) {
// Add the confetti function to the game context
-
addConfetti(pos: { x: number, y: number }) {
return addConfetti(k, pos);
-
export default confettiPlugin;
···
// Extend the KAPLAYCtx type to include our addConfetti method
declare module "kaplay" {
+
addConfetti?: (pos: { x: number; y: number }) => GameObj[];
// Function to create a confetti effect at a position
+
export function addConfetti(k: KAPLAYCtx, pos: { x: number; y: number }) {
// Number of confetti particles
const PARTICLE_COUNT = 50;
+
[255, 255, 0], // Yellow
+
[255, 0, 255], // Magenta
+
[255, 165, 0], // Orange
+
[128, 0, 128], // Purple
const particles: GameObj[] = [];
for (let i = 0; i < PARTICLE_COUNT; i++) {
const color = COLORS[Math.floor(Math.random() * COLORS.length)];
const size = Math.random() * 8 + 2; // 2-10 pixels
// Random shape (circle or rect)
const isCircle = Math.random() > 0.5;
const angle = Math.random() * Math.PI * 2;
const speed = Math.random() * 400 + 100; // 100-500 pixels per second
const vx = Math.cos(angle) * speed;
const vy = Math.sin(angle) * speed - 200; // Initial upward boost
const rotSpeed = Math.random() * 10 - 5; // -5 to 5 radians per second
isCircle ? k.circle(size / 2) : k.rect(size, size / 2),
+
k.color(color[0], color[1], color[2]),
k.rotate(Math.random() * 360), // Random initial rotation
···
fadeStart: 0.7, // When to start fading (0.7 = 70% of lifespan)
// Update function for the particle
particle.onUpdate(() => {
// Update position based on velocity
particle.pos.x += particle.vx * k.dt();
particle.pos.y += particle.vy * k.dt();
particle.vy += particle.gravity * k.dt();
particle.angle += particle.rotSpeed * k.dt() * 60;
particle.lifespan -= k.dt();
if (particle.lifespan < particle.fadeStart) {
particle.opacity = Math.max(0, particle.lifespan / particle.fadeStart);
// Destroy when lifespan is over
if (particle.lifespan <= 0) {
particles.push(particle);
···
export function confettiPlugin(k: KAPLAYCtx) {
// Add the confetti function to the game context
+
addConfetti(pos: { x: number; y: number }) {
return addConfetti(k, pos);
+
export default confettiPlugin;