let numberParticles = []; let encodedMessages = [ [84, 104, 105, 115, 32, 109, 111, 111, 110, 115, 116, 111, 110, 101, 32, 105, 115, 32, 105, 109, 98, 117, 101, 100, 32, 119, 105, 116, 104, 32, 116, 104, 101, 32, 112, 111, 119, 101, 114, 32, 111, 102, 32, 50, 56, 32, 97, 110, 100, 32, 116, 104, 101, 32, 109, 97, 103, 105, 99, 32, 55, 46, 32, 114, 101, 109, 101, 109, 98, 101, 114, 32, 50, 120, 56, 32, 101, 113, 117, 97, 108, 115, 32, 49, 54, 32, 101, 113, 117, 97, 108, 115, 32, 55], [84, 104, 101, 32, 97, 108, 112, 104, 97, 32, 116, 111, 32, 116, 104, 111, 115, 101, 32, 116, 104, 97, 116, 32, 99, 104, 111, 111, 115, 101, 32, 116, 111, 32, 112, 97, 114, 116, 105, 99, 105, 112, 97, 116, 101, 59, 32, 116, 104, 101, 32, 113, 117, 101, 115, 116, 32, 102, 111, 114, 32, 117, 110, 116, 111, 108, 100, 32, 114, 105, 99, 104, 101, 115, 32, 119, 105, 108, 108, 32, 98, 101, 32, 111, 117, 114, 32, 108, 101, 103, 97, 99, 121, 46, 46], [84, 104, 101, 32, 97, 108, 112, 104, 97, 32, 116, 111, 32, 116, 104, 111, 115, 101, 32, 116, 104, 97, 116, 32, 99, 104, 111, 111, 115, 101, 32, 116, 111, 32, 112, 97, 114, 116, 105, 99, 105, 112, 97, 116, 101, 59, 32, 116, 104, 101, 32, 113, 117, 101, 115, 116, 32, 102, 111, 114, 32, 117, 110, 116, 111, 108, 100, 32, 114, 105, 99, 104, 101, 115, 32, 119, 105, 108, 108, 32, 98, 101, 32, 111, 117, 114, 32, 108, 101, 103, 97, 99, 121, 46, 46], [116, 104, 105, 115, 32, 115, 116, 111, 110, 101, 32, 115, 104, 97, 108, 108, 32, 97, 99, 116, 32, 108, 105, 107, 101, 32, 97, 32, 98, 101, 97, 99, 111, 110, 32, 116, 111, 32, 97, 116, 116, 114, 97, 99, 116, 32, 119, 101, 97, 108, 116, 104, 32, 97, 110, 100, 32, 112, 114, 111, 115, 112, 101, 114, 105, 116, 121, 32, 116, 111, 32, 105, 116, 39, 115, 32, 98, 101, 97, 114, 101, 114] ]; let messageIndex = 0; let bgImg; let baseFontSize = 16; let scaleFactor = 0.01; function preload() { bgImg = loadImage('/content/cfcbc66b47e0bbd34729d0bccbcd076a36e9e6b2676185024a4fce6e51502e1fi0'); } function setup() { createCanvas(windowWidth, windowHeight); textAlign(CENTER, CENTER); updateFontSize(); } function draw() { image(bgImg, 0, 0, width, height); if (random(1) < 0.3) { for (let i = 0; i < 5; i++) { numberParticles.push(new NumberParticle()); } } for (let i = numberParticles.length - 1; i >= 0; i--) { numberParticles[i].update(); numberParticles[i].display(); if (numberParticles[i].isDead()) { numberParticles.splice(i, 1); } } displayBottomText(); } function displayBottomText() { push(); let bottomTextSize = height * 0.035; textSize(bottomTextSize); fill(128); textAlign(CENTER, BOTTOM); drawingContext.shadowColor = color(0, 200, 255, 188); drawingContext.shadowBlur = 45; let padding = height * 0.05; let textYPosition = height - padding; text("Moonstone - Casting Runes...", width / 2, textYPosition); pop(); } function windowResized() { resizeCanvas(windowWidth, windowHeight); updateFontSize(); } function updateFontSize() { baseFontSize = windowHeight * scaleFactor; } function decodeMessage(encodedArray) { let decoded = ''; for (let code of encodedArray) { decoded += String.fromCodePoint(code); } return decoded; } class NumberParticle { constructor() { this.position = createVector(width / 2, height / 2); this.velocity = p5.Vector.random2D().mult(random(2,10)); this.rotationSpeed = random(-0.03, 0.03); this.angle = 0; this.size = baseFontSize; this.lifespan = 200; this.targetColor = color(random(255), random(255), random(255), 255); this.isSecret = random(1) < 0.15; this.char = this.chooseChar(); this.initialFrames = 80; this.totalInitialFrames = this.initialFrames; } chooseChar() { let randomIndex = floor(random(0, encodedMessages.length)); let secretMessage = decodeMessage(encodedMessages[randomIndex]); if (this.isSecret) { let char = secretMessage[messageIndex % secretMessage.length]; messageIndex++; return char; } else { return floor(random(0, 10)).toString(); } } update() { this.position.add(this.velocity); this.angle += this.rotationSpeed; this.lifespan -= 2; if (this.initialFrames > 0) { this.initialFrames -= 1; } } display() { push(); translate(this.position.x, this.position.y); rotate(this.angle); let transitionProgress; if (this.initialFrames > 0) { transitionProgress = map(this.initialFrames, this.totalInitialFrames, 0, 0, 1); } else { transitionProgress = 1; } let currentColor = lerpColor(color(255, 255, 255), this.targetColor, transitionProgress); fill(currentColor); if (this.isSecret) { textStyle(BOLD); textSize(this.size * 2.5); } else { textStyle(NORMAL); textSize(this.size); } textFont('serif'); text(this.char, 0, 0); pop(); } isDead() { return this.lifespan <= 0; } }