Your concept:
I was inspired by my house cats, who always bring joy and happiness when I play with them or when they decide to sit on my lap. I wanted to include them, but wasn’t sure how, so I decided to base it on Nyan Cat, which I used to play when I was younger, when I had to wait for my friends to arrive, didn’t have access to the internet, or just wanted to give my brain a break.

Code:
I prompted Gemini to add the particles, it used blendMode(ADD) is what makes the magic particles look like they are made of light.
let segments = 8;
let segLength = 12;
let x = [], y = [];
let fireParticles = [];
const COLORS = {
fur: [255, 235, 245],
ears: [255, 180, 200],
eyes: [100, 200, 255],
magic: ['#FFD1DC', '#FFECB3', '#B2E2F2', '#D1FFD7', '#E0BBE4']
};
function setup() {
createCanvas(windowWidth, windowHeight);
// Initialize segment positions
for (let i = 0; i < segments; i++) {
x[i] = mouseX;
y[i] = mouseY;
}
background(0);
angleMode(RADIANS);
}
function draw() {
// Semi-transparent black rect creates the generative trail
blendMode(BLEND);
fill(0, 0, 0, 30);
rect(0, 0, width, height);
let mouseSpeed = dist(mouseX, mouseY, pmouseX, pmouseY);
//Follow Logic
dragSegment(0, mouseX, mouseY);
for (let i = 0; i < x.length - 1; i++) {
dragSegment(i + 1, x[i], y[i]);
}
let headAngle = atan2(mouseY - y[1], mouseX - x[1]);
let emissionRate = map(mouseSpeed, 0, 50, 1, 8);
if (mouseIsPressed || mouseSpeed > 2) {
for(let i = 0; i < emissionRate; i++) {
fireParticles.push(new MagicParticle(x[0], y[0], headAngle, mouseSpeed));
}
}
// Tail
drawTail(x[segments-1], y[segments-1]);
// Body
for (let i = x.length - 1; i > 0; i--) {
drawCatBody(x[i], y[i], i);
}
// Glowing Particles
// We use ADD blend mode to make them pop on black
blendMode(ADD);
for (let i = fireParticles.length - 1; i >= 0; i--) {
fireParticles[i].update();
fireParticles[i].display();
if (fireParticles[i].isDead()) fireParticles.splice(i, 1);
}
blendMode(BLEND);
//Head always on top
drawCatHead(x[0], y[0], headAngle);
}
function dragSegment(i, xin, yin) {
let dx = xin - x[i];
let dy = yin - y[i];
let angle = atan2(dy, dx);
x[i] = xin - cos(angle) * segLength;
y[i] = yin - sin(angle) * segLength;
}
function drawCatBody(posx, posy, index) {
push();
translate(posx, posy);
fill(COLORS.fur);
noStroke();
ellipse(0, 0, 50 - index, 45 - index);
pop();
}
function drawTail(tx, ty) {
push();
translate(tx, ty);
stroke(COLORS.fur);
strokeWeight(12);
noFill();
let wag = sin(frameCount * 0.2) * 25;
bezier(0, 0, -15, wag, -30, -wag, -45, 0);
pop();
}
function drawCatHead(hx, hy, angle) {
push();
translate(hx, hy);
rotate(angle);
fill(COLORS.fur);
noStroke();
ellipse(10, 0, 55, 50); // Face
// Ears
fill(COLORS.ears);
triangle(-5, -20, 5, -45, 20, -20);
triangle(10, -20, 25, -45, 40, -20);
// Mouth
fill(255, 150, 150);
arc(30, 5, 22, 22, 0, PI);
// Eyes
fill(COLORS.eyes);
ellipse(15, -5, 10, 12);
ellipse(35, -5, 10, 12);
fill(255);
ellipse(17, -7, 4, 4);
ellipse(37, -7, 4, 4);
// Whiskers
stroke(255, 200);
strokeWeight(1);
line(40, 2, 60, -5);
line(40, 5, 60, 5);
line(40, 8, 60, 15);
pop();
}
class MagicParticle {
constructor(x, y, angle, speed) {
this.pos = createVector(x, y);
// Spread the magic out
this.vel = p5.Vector.fromAngle(angle + random(-0.5, 0.5));
this.vel.mult(speed * 0.2 + random(1, 4));
this.lifespan = 255;
this.c = color(random(COLORS.magic));
this.size = random(2, 7);
}
update() {
this.pos.add(this.vel);
this.vel.mult(0.96);
this.lifespan -= 4;
}
display() {
noStroke();
let alpha = map(this.lifespan, 0, 255, 0, 200);
fill(red(this.c), green(this.c), blue(this.c), alpha);
ellipse(this.pos.x, this.pos.y, this.size);
// Sparkle effect
if (random(1) > 0.95) {
fill(255, 255, 255, alpha);
ellipse(this.pos.x, this.pos.y, this.size * 0.6);
}
}
isDead() { return this.lifespan < 0; }
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
background(0);
}
-
-
- Embedded sketch
Reflection and ideas for future work or improvements:
-
- In the future, I might add interactions or obstacles to make it like an interactive fun game, but I want to be unique