🔬 This code bounces the ball off left and right walls. What if you change *= -1 to *= -0.8 so the ball loses a little speed on each bounce? Will it eventually stop?
if (ballX + ballRadius >= width || ballX - ballRadius <= 0) {
baseBallSpeedX *= -1; // Reverse the base X speed
collidedX = true;
}
🔬 The first line maps the X position to a hue 0-360, creating a rainbow. What happens if you swap the numbers and use map(ballX, 0, width, 360, 0) so hue counts backwards?
let ballHue = map(ballX, 0, width, 0, 360);
fill(ballHue, 80, 100); // Dynamic hue, high saturation, full brightness
function draw() {
// Draw the animated background gradient
// Instead of completely clearing the background, we draw a semi-transparent rectangle
// over it. This creates a fading trail effect.
// The alpha value (last parameter) controls the transparency. Lower values mean longer trails.
fill(0, 0, 100, 10); // White color (0 hue, 0 saturation, 100 brightness) with 10% opacity
noStroke();
rect(0, 0, width, height); // Draw a rectangle over the entire canvas
// Calculate the current ball speed based on the multiplier
ballSpeedX = baseBallSpeedX * speedMultiplier;
ballSpeedY = baseBallSpeedY * speedMultiplier;
// 1. Update the ball's position based on its speed
ballX += ballSpeedX;
ballY += ballSpeedY;
// 2. Check for collisions with canvas edges and reverse speed
// A flag to ensure sound is played only once per collision direction
let collidedX = false;
let collidedY = false;
// If the ball hits the right edge or left edge
if (ballX + ballRadius >= width || ballX - ballRadius <= 0) {
baseBallSpeedX *= -1; // Reverse the base X speed
collidedX = true;
}
// If the ball hits the bottom edge or top edge
if (ballY + ballRadius >= height || ballY - ballRadius <= 0) {
baseBallSpeedY *= -1; // Reverse the base Y speed
collidedY = true;
}
// Play the sound if a collision occurred in either direction
if (collidedX || collidedY) {
// Quickly set amplitude to 0.5 (volume), then fade out over 0.3 seconds
bounceOsc.amp(0.5, 0.05); // Turn on quickly
bounceOsc.amp(0, 0.3); // Fade out
}
// 3. Draw the ball
// Map the ball's horizontal position to a hue value (0 to 360)
let ballHue = map(ballX, 0, width, 0, 360);
fill(ballHue, 80, 100); // Dynamic hue, high saturation, full brightness
noStroke();
ellipse(ballX, ballY, ballRadius * 2); // Draw an ellipse for the ball
// Display current speed multiplier
fill(0); // Black color for text
textSize(16);
noStroke();
text(`Speed: x${speedMultiplier.toFixed(1)} (Up/Down Arrows, Space to Reset)`, 10, 30);
}