PeppaMusic.js Feature Implementation
Overview
This feature implements a dynamic background music system using the iTunes Search API. It fetches a playable preview, handles browser autoplay restrictions, and provides a toggle button for user control.
Full Code
console.log("PeppaMusic.js loaded from _projects/PeppaPigGame/levels");
class PeppaMusic {
constructor() {
this.audio = null;
this.started = false;
this.isPlaying = false;
this.endpoint = 'https://itunes.apple.com/search?term=peppa%20pig%20theme&entity=song&limit=10';
this.userActivated = false;
this.activateFromUserGesture = this.activateFromUserGesture.bind(this);
this.createToggleButton();
}
createToggleButton() {
const btn = document.createElement('button');
btn.id = 'peppa-music-toggle';
btn.innerHTML = 'Music';
btn.style.cssText = `
position: fixed;
top: 10px;
right: 10px;
z-index: 10000;
padding: 8px 16px;
font-size: 14px;
font-family: sans-serif;
background: #ff6b9d;
color: white;
border: none;
border-radius: 20px;
cursor: pointer;
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
`;
btn.addEventListener('click', (e) => {
e.stopPropagation();
this.toggleMusic();
});
document.body.appendChild(btn);
this.toggleBtn = btn;
}
async fetchPreviewUrl() {
const response = await fetch(this.endpoint);
if (!response.ok) {
throw new Error('API request failed (' + response.status + ')');
}
const data = await response.json();
const tracks = (data && Array.isArray(data.results)) ? data.results : [];
const track = tracks.find(function(item) {
return item && item.previewUrl;
});
if (!track || !track.previewUrl) {
throw new Error('No playable preview URL found in API response');
}
return track.previewUrl;
}
async startMusic() {
if (this.started || !this.userActivated) return;
try {
const previewUrl = await this.fetchPreviewUrl();
this.audio = new Audio(previewUrl);
this.audio.volume = 0.35;
this.audio.loop = true;
await this.audio.play();
this.started = true;
this.isPlaying = true;
this.removeGestureListeners();
this.updateButton();
} catch (error) {
console.warn('Failed to start music', error);
}
}
stopMusic() {
if (this.audio) {
this.audio.pause();
this.audio.currentTime = 0;
this.isPlaying = false;
this.updateButton();
}
}
async toggleMusic() {
if (!this.started) {
this.userActivated = true;
await this.startMusic();
} else if (this.isPlaying) {
this.stopMusic();
} else {
if (this.audio) {
await this.audio.play();
this.isPlaying = true;
this.updateButton();
}
}
}
updateButton() {
if (this.toggleBtn) {
this.toggleBtn.innerHTML = this.isPlaying ? 'Music On' : 'Music Off';
}
}
activateFromUserGesture() {
this.userActivated = true;
this.startMusic();
}
addGestureListeners() {
window.addEventListener('click', this.activateFromUserGesture, { once: true });
window.addEventListener('keydown', this.activateFromUserGesture, { once: true });
window.addEventListener('touchstart', this.activateFromUserGesture, { once: true });
}
removeGestureListeners() {
window.removeEventListener('click', this.activateFromUserGesture);
window.removeEventListener('keydown', this.activateFromUserGesture);
window.removeEventListener('touchstart', this.activateFromUserGesture);
}
}
export default PeppaMusic;
Code Breakdown
Constructor
Initializes the music system by defining variables that track audio state, API configuration, and user interaction. It also binds the gesture handler and creates the toggle button immediately.
Button Creation (createToggleButton)
Creates a floating button on the screen that allows the user to control music. The button triggers the main control logic (toggleMusic) when clicked.
API Fetching (fetchPreviewUrl)
Connects to the iTunes Search API and retrieves a list of tracks. It selects the first valid track that contains a playable previewUrl and returns it for playback.
Music Start Logic (startMusic)
Handles the process of starting music. It ensures that music only starts after user interaction and only runs once. It creates the audio object, sets volume and looping, and begins playback.
Stop Logic (stopMusic)
Stops the audio playback and resets it to the beginning. It also updates the system state to reflect that music is no longer playing.
Toggle Logic (toggleMusic)
Acts as the main control system. It determines whether to start, stop, or resume music depending on the current state of the system.
UI Update (updateButton)
Updates the text of the toggle button to reflect whether music is currently playing or not.
Gesture Handling (activateFromUserGesture, addGestureListeners, removeGestureListeners)
Handles browser autoplay restrictions by detecting user interaction (click, keypress, or touch). Once interaction occurs, music is allowed to start, and listeners are removed afterward.

- Option to turn the music on or off
Summary
This system integrates an external API into a game environment while handling real-world constraints like autoplay restrictions. It provides a simple user interface for control and manages playback through clear state tracking, resulting in a smooth and interactive background music experience.
PeppaMusic.js Feature Implementation
Overview
This feature implements a dynamic background music system using the iTunes Search API. It fetches a playable preview, handles browser autoplay restrictions, and provides a toggle button for user control.
Full Code
Code Breakdown
Constructor
Initializes the music system by defining variables that track audio state, API configuration, and user interaction. It also binds the gesture handler and creates the toggle button immediately.
Button Creation (createToggleButton)
Creates a floating button on the screen that allows the user to control music. The button triggers the main control logic (toggleMusic) when clicked.
API Fetching (fetchPreviewUrl)
Connects to the iTunes Search API and retrieves a list of tracks. It selects the first valid track that contains a playable previewUrl and returns it for playback.
Music Start Logic (startMusic)
Handles the process of starting music. It ensures that music only starts after user interaction and only runs once. It creates the audio object, sets volume and looping, and begins playback.
Stop Logic (stopMusic)
Stops the audio playback and resets it to the beginning. It also updates the system state to reflect that music is no longer playing.
Toggle Logic (toggleMusic)
Acts as the main control system. It determines whether to start, stop, or resume music depending on the current state of the system.
UI Update (updateButton)
Updates the text of the toggle button to reflect whether music is currently playing or not.
Gesture Handling (activateFromUserGesture, addGestureListeners, removeGestureListeners)
Handles browser autoplay restrictions by detecting user interaction (click, keypress, or touch). Once interaction occurs, music is allowed to start, and listeners are removed afterward.
Summary
This system integrates an external API into a game environment while handling real-world constraints like autoplay restrictions. It provides a simple user interface for control and manages playback through clear state tracking, resulting in a smooth and interactive background music experience.