AI Bubble Pop - Satisfying Click Game Pop colorful bubbles as they float up! Click bubbles to burst

45 views Β· Dec 16, 2025

Create a Bubble Pop game with sounds! Colorful bubbles float up from the bottom. Click bubbles to po

#xelsedia#xelsedai#xelsedp5flashalpha6
πŸ”€ Remix This πŸ“– View Docs β›Ά Full Screen ← Back to Gallery
πŸ“‹ Embed Code

Copy this code to embed this sketch on your website:

<iframe src="https://p5js.ai/embed/46a4d3fe-7ace-4a09-b456-47c2d64f517d" width="400" height="400" frameborder="0" allow="autoplay" title="AI Bubble Pop - Satisfying Click Game Pop colorful bubbles as they float up! Click bubbles to burst"></iframe>

Adjust width and height as needed. Preview embed β†’

❓ About This Sketch 3 questions

What visual experience does the AI Bubble Pop sketch provide?

The sketch creates a vibrant scene where colorful bubbles float upwards against a deep blue-ish background, providing a visually satisfying experience.

How can players interact with the AI Bubble Pop game?

Users can click on the bubbles as they float up to burst them, contributing to a fun and engaging gameplay experience.

What creative coding concepts does the AI Bubble Pop sketch illustrate?

This sketch demonstrates the use of object-oriented programming with classes to manage bubbles, as well as sound synthesis to enhance user interaction through audio feedback.

πŸ’¬ AI Chat History 2 messages
πŸ‘€ You
Create a Bubble Pop game with sounds! Colorful bubbles float up from the bottom. Click bubbles to pop them with a satisfying pop sound using p5.Oscillator. Each pop creates a particle burst. Show score counter. Bubbles respawn continuously. Fun and addictive!
πŸ€– AI
Here’s a complete Bubble Pop game with sounds, particle bursts, and a score counter, using **p5.js 1.11.3** and **p5.sound** (with `p5.Oscillator`).

---

### index.html

Make sure p5.js and p5.sound are loaded **before** `sketch.js`:

```html
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bubble Pop Game</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- p5.js core -->
<script src="https://cdn.jsdelivr.net/npm/p5@1.11.3/lib/p5.min.js"></script>
<!-- p5.sound addon -->
<script src="https://cdn.jsdelivr.net/npm/p5@1.11.3/lib/addons/p5.sound.min.js"></script>
<!-- Your sketch -->
<script src="sketch.js"></script>
</body>
</html>
```

---

### style.css

You can keep your existing styles; here’s a slightly polished version:

```css
/* style.css */
body {
margin: 0;
padding: 0;
overflow: hidden;
background: radial-gradient(circle at top, #1a237e 0, #0b1025 60%, #000000 100%);
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

canvas {
display: block;
}
```

---

### sketch.js

This file implements:

- Colorful bubbles floating up from the bottom
- Mouse/touch click popping
- `p5.Oscillator` + `p5.Envelope` for per-pop sound
- Particle burst on pop
- Score counter
- Continuous respawning

References:
- `createCanvas` / `background` / `circle`: [p5 reference](https://p5js.org/reference/)
- `p5.Oscillator`: <https://p5js.org/reference/#/p5.Oscillator>
- `p5.Envelope`: <https://p5js.org/reference/#/p5.Envelope>
- `userStartAudio`: <https://p5js.org/reference/#/p5/userStartAudio>

```js
// sketch.js

// ----- CONFIG -----
const NUM_BUBBLES = 18;
const BUBBLE_MIN_R = 20;
const BUBBLE_MAX_R = 60;

let bubbles = [];
let particles = [];
let score = 0;

// Sound
let popOsc;
let popEnv;
let audioStarted = false;

function setup() {
createCanvas(windowWidth, windowHeight); // 2D canvas

// Use HSB for nice rainbow colors
colorMode(HSB, 360, 100, 100, 255);
noStroke();
textFont('system-ui');
textSize(24);

// Setup pop sound: one oscillator + envelope reused for all pops
popOsc = new p5.Oscillator('sine');
popEnv = new p5.Envelope();
// Fast, percussive pop: short attack/decay
popEnv.setADSR(0.001, 0.1, 0.0, 0.1);
popEnv.setRange(0.5, 0.0); // max amp, sustain amp
popOsc.amp(popEnv);
popOsc.start();
popOsc.freq(400); // base; will be changed per bubble

// Create initial bubbles
for (let i = 0; i < NUM_BUBBLES; i++) {
bubbles.push(new Bubble());
}
}

function draw() {
// Slightly animated background
background(230, 50, 10); // HSB: deep blue-ish background

// Draw and update bubbles
for (let b of bubbles) {
b.update();
b.show();
}

// Draw and update particles
for (let i = particles.length - 1; i >= 0; i--) {
let p = particles[i];
p.update();
p.show();
if (p.isDead()) {
particles.splice(i, 1);
}
}

// Draw score
drawScore();
}

function windowResized() {
resizeCanvas(windowWidth, windowHeight);
}

// ----- CLASSES -----

class Bubble {
constructor() {
this.reset(true);
}

reset(initial = false) {
this.r = random(BUBBLE_MIN_R, BUBBLE_MAX_R);
this.x = random(this.r, width - this.r);

// Start from bottom; if initial, randomize a bit up the screen
if (initial) {
this.y = random(height + this.r * 0.5, height + this.r * 4);
} else {
this.y = height + this.r * 2;
}

this.speed = random(0.7, 1.8);
this.driftAmount = random(0.2, 0.8);
this.driftOffset = random(TWO_PI);

const hue = random(180, 300); // cool colors
const sat = random(60, 100);
const bri = random(70, 100);
this.col = color(hue, sat, bri, 180);
}

update() {
// Float up
this.y -= this.speed;

// Gentle horizontal drift using a sine wave
this.x += sin(frameCount * 0.01 + this.driftOffset) * this.driftAmount;

// Keep within horizontal bounds
this.x = constrain(this.x, this.r, width - this.r);

// If bubble went off the top, respawn at bottom
if (this.y + this.r < 0) {
this.reset(false);
}
}

show() {
// Outer soft bubble
fill(hue(this.col), saturation(this.col), brightness(this.col), 80);
circle(this.x, this.y, this.r * 2.3);

// Main bubble
fill(this.col);
circle(this.x, this.y, this.r * 2);

// Highlight
fill(0, 0, 100, 180);
circle(this.x - this.r * 0.4, this.y - this.r * 0.4, this.r * 0.6);
}

contains(px, py) {
return dist(px, py, this.x, this.y) < this.r;
}

pop() {
// Play sound and create particle burst
playPopSound(this);
createParticleBurst(this.x, this.y, this.col);

// Respawn bubble at bottom
this.reset(false);
}
}

class Particle {
constructor(x, y, c) {
this.pos = createVector(x, y);

const angle = random(TWO_PI);
const speed = random(1.5, 4);
this.vel = p5.Vector.fromAngle(angle).mult(speed);

this.gravity = createVector(0, 0.04);
this.friction = 0.96;

this.life = random(25, 45);
this.totalLife = this.life;

const baseHue = hue(c);
const sat = saturation(c);
const bri = brightness(c);
// Slight color variation
this.col = color(
baseHue + random(-10, 10),
sat,
bri,
255
);
this.size = random(3, 7);
}

update() {
this.vel.mult(this.friction);
this.vel.add(this.gravity);
this.pos.add(this.vel);
this.life--;
}

isDead() {
return this.life <= 0;
}

show() {
const alpha = map(this.life, 0, this.totalLife, 0, 255);
fill(hue(this.col), saturation(this.col), brightness(this.col), alpha);
circle(this.pos.x, this.pos.y, this.size);
}
}

// ----- SOUND -----

function ensureAudioStarted() {
if (!audioStarted) {
userStartAudio(); // resumes AudioContext on first user gesture
audioStarted = true;
}
}

function playPopSound(bubble) {
// Map bubble size to pitch: small bubbles -> higher pitch
const freq = map(
bubble.r,
BUBBLE_MIN_R,
BUBBLE_MAX_R,
800, // small radius
200, // large radius
true
);
popOsc.freq(freq);
popEnv.play(); // triggers envelope on the oscillator
}

// ----- PARTICLES -----

function createParticleBurst(x, y, col) {
const count = floor(random(12, 22));
for (let i = 0; i < count; i++) {
particles.push(new Particle(x, y, col));
}
}

// ----- INPUT -----

function mousePressed() {
handlePop(mouseX, mouseY);
}

function touchStarted() {
// On many platforms, touch also triggers mousePressed, but this ensures
// touch-only environments still work nicely.
handlePop(mouseX, mouseY);
return false; // prevent default scrolling on touch
}

function handlePop(px, py) {
ensureAudioStarted();

// Pop only one bubble per click, preferring the one drawn last (topmost)
for (let i = bubbles.length - 1; i >= 0; i--) {
if (bubbles[i].contains(px, py)) {
bubbles[i].pop();
score++;
break;
}
}
}

// ----- UI -----

function drawScore() {
push();
textAlign(LEFT, TOP);
fill(0, 0, 100, 220); // bright text
text("Score: " + score, 16, 16);
pop();
}
```

---

You can now:

1. Replace your existing `sketch.js`, `index.html`, and `style.css` with the versions above.
2. Click/tap bubbles to pop them and hear the oscillator-based pop sound.
3. Watch the particle bursts and score counter as bubbles respawn continuously.

If you’d like extra features (timer, combo multiplier, increasing difficulty, or different sound types per bubble color), I can extend this further.
🎬 Video Preview