Drop The Beat is a music experience game that makes you become a great DJ!
This game was made during the first module of the Ironhack Web Development Bootcamp, in a time span of 4 days.
The goal of the game is to drag & drop music elements into the Drop Zone.
It is possible to drop any element together.
Best soundtrack: First place 🥇
Best game: Second place 🥈
JavaScript (arrays, objects, events and DOM manipulation), HTML5 & CSS3.
🕹️ Click here to play - Notice: This is a web experiment which only works with Google Chrome.
- Make the game work on any browser
- Add the possibility for the user to record the creation OR to save the parameters
Automate the creation of the music boxes for all genres and also the creation + the assignation of the audio elements to their music boxes.
Every music box is automatically created from one core Object.
const MUSIC = {
techno: {
genre: "TECHNO",
color: "#c3ec52",
types: {
beat: {
type: "BEAT",
image: `${IMAGE_DIRECTORY}/icon-drum.svg`,
audio: `${SOUNDS_DIRECTORY}/techno-beat.mp3`
},
synth: {
type: "SYNTH",
image: `${IMAGE_DIRECTORY}/icon-synth.svg`,
audio: `${SOUNDS_DIRECTORY}/techno-synth.mp3`
}
// ... and so on
The keys/values are mapped in order to assign them as arguments in the constructors.
const TYPES_ARRAY = Object.entries(loop_types).map(types => {
let audio = types[1].audio;
let type = types[1].type;
let image = types[1].image;
const PARAMS = [color, genre, type, image, audio];
if (genre === "TECHNO") {
return new TechnoBox(...PARAMS);
} else if (genre === "LATINO") {
return new LatinoBox(...PARAMS);
} else if (genre === "ROCK") {
return new RockBox(...PARAMS);
}
});
return TYPES_ARRAY;
Every value is then assigned in the constructor
class TechnoBox extends Box {
constructor(color, genre, type, image, audio) {
super();
this.audioElement.src = audio;
this.classGenre = genre.toLowerCase();
this.boxElement.classList.add(this.classGenre);
this.boxElement.style.backgroundColor = color;
this.boxElement.style.backgroundImage = `url('${image}')`;
}
}
Drag & Drop functionality
For a better user experience I wanted the user to drag the music element and drop it into the "Drop Zone". I've first tried different libraries (jQuery UI Draggable/Droppable, Interact.js, GSAP...) to finally go for the native DOM events, that was giving me more flexibility and a better performance. More info on the MDN - Drag & drop events.
Audio loop gap
When you loop a HTML5 audio element, a small gap is happening between each loop. To remove this gap, I added an Event Listener on the audio elements, that resets the Current Time of the track with a calculation based on a buffer value. I found this solution on Stackoverflow - creation of a buffer.
AUDIO_ELEMENT[0].addEventListener("timeupdate", function() {
const BUFFER = 0.22; // for 3.8s loops (or 4 times at 128bpm)
if (this.currentTime > this.duration - BUFFER) {
this.currentTime = 0;
this.play();
}
});
Sounds' synch playback
The main functionality of the game is the playback of numerous audio files at the same time, thus, they need to be synchronized. I created loops with same length and tempo (128bpm) using the GarageBand app, then with calculation, each time a new music box is dropped, the playback is "reset" and starts again from the Current Time of the previous element.
let audioCurrentTime = document.querySelectorAll(".active")[0].querySelector("audio").currentTime;
AUDIO_ELEMENT[0].currentTime = audioCurrentTime;
AUDIO_ELEMENT[0].play();
- Drum, Maracas, Bass, Guitars, Headphones, Move: made by Freepik
- Synthesizer: made by Eucalyp
- Clapping hands, Triangle: made by Smashicons
- Pulse: made by Prosymbols
- Conga: made by Iconnice
- Refresh: made by Becris
- Light bulb: made by Puppets
Creative Commons BY 3.0