Spaces:
Running
Running
Upload folder using huggingface_hub
Browse files- index.html +87 -169
index.html
CHANGED
|
@@ -4,7 +4,7 @@
|
|
| 4 |
<head>
|
| 5 |
<meta charset="UTF-8">
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 7 |
-
<title>Game Sound Synthesizer -
|
| 8 |
<script src="https://cdn.tailwindcss.com"></script>
|
| 9 |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
| 10 |
<style>
|
|
@@ -149,7 +149,8 @@
|
|
| 149 |
</div>
|
| 150 |
<div>
|
| 151 |
<h1 class="text-2xl font-bold text-white neon-text">Game Sound Synthesizer</h1>
|
| 152 |
-
<p class="text-xs text-gray-200">
|
|
|
|
| 153 |
</div>
|
| 154 |
</div>
|
| 155 |
<div class="flex items-center space-x-4">
|
|
@@ -206,17 +207,7 @@
|
|
| 206 |
{ id: 17, name: 'Fire', icon: 'fa-fire', category: 'element' },
|
| 207 |
{ id: 18, name: 'Thunder', icon: 'fa-cloud-bolt', category: 'element' },
|
| 208 |
{ id: 19, name: 'Level Up', icon: 'fa-trophy', category: 'ui' },
|
| 209 |
-
{ id: 20, name: 'Game Over', icon: 'fa-skull', category: 'ui' }
|
| 210 |
-
{ id: 21, name: 'Menu Click', icon: 'fa-mouse-pointer', category: 'ui' },
|
| 211 |
-
{ id: 22, name: 'Pause', icon: 'fa-pause-circle', category: 'ui' },
|
| 212 |
-
{ id: 23, name: 'Resume', icon: 'fa-play-circle', category: 'ui' },
|
| 213 |
-
{ id: 24, name: 'Achievement', icon: 'fa-medal', category: 'ui' },
|
| 214 |
-
{ id: 25, name: 'Critical Hit', icon: 'fa-crosshairs', category: 'impact' },
|
| 215 |
-
{ id: 26, name: 'Dodge', icon: 'fa-wind', category: 'movement' },
|
| 216 |
-
{ id: 27, name: 'Potion Drink', icon: 'fa-flask', category: 'power' },
|
| 217 |
-
{ id: 28, name: 'Lockpick', icon: 'fa-key', category: 'environment' },
|
| 218 |
-
{ id: 29, name: 'Chest Open', icon: 'fa-box-open', category: 'collect' },
|
| 219 |
-
{ id: 30, name: 'Monster Roar', icon: 'fa-dragon', category: 'creature' }
|
| 220 |
];
|
| 221 |
|
| 222 |
// Sound synthesis functions
|
|
@@ -697,160 +688,87 @@
|
|
| 697 |
|
| 698 |
osc.start(audioContext.currentTime);
|
| 699 |
osc.stop(audioContext.currentTime + 1);
|
| 700 |
-
}
|
| 701 |
-
|
| 702 |
-
|
| 703 |
-
|
| 704 |
-
|
| 705 |
-
|
| 706 |
-
|
| 707 |
-
|
| 708 |
-
|
| 709 |
-
|
| 710 |
-
|
| 711 |
-
|
| 712 |
-
|
| 713 |
-
|
| 714 |
-
|
| 715 |
-
|
| 716 |
-
|
| 717 |
-
|
| 718 |
-
|
| 719 |
-
|
| 720 |
-
|
| 721 |
-
|
| 722 |
-
|
| 723 |
-
|
| 724 |
-
|
| 725 |
-
|
| 726 |
-
|
| 727 |
-
|
| 728 |
-
|
| 729 |
-
|
| 730 |
-
|
| 731 |
-
|
| 732 |
-
|
| 733 |
-
|
| 734 |
-
|
| 735 |
-
|
| 736 |
-
},
|
| 737 |
-
|
| 738 |
-
23: () => { // Resume
|
| 739 |
-
const osc = audioContext.createOscillator();
|
| 740 |
-
const gain = audioContext.createGain();
|
| 741 |
-
|
| 742 |
-
osc.connect(gain);
|
| 743 |
-
gain.connect(masterGainNode);
|
| 744 |
-
|
| 745 |
-
osc.type = 'triangle';
|
| 746 |
-
osc.frequency.setValueAtTime(220, audioContext.currentTime);
|
| 747 |
-
osc.frequency.linearRampToValueAtTime(440, audioContext.currentTime + 0.2);
|
| 748 |
-
|
| 749 |
-
gain.gain.setValueAtTime(0.15, audioContext.currentTime);
|
| 750 |
-
gain.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.2);
|
| 751 |
-
|
| 752 |
-
osc.start(audioContext.currentTime);
|
| 753 |
-
osc.stop(audioContext.currentTime + 0.2);
|
| 754 |
-
},
|
| 755 |
-
|
| 756 |
-
24: () => { // Achievement
|
| 757 |
-
const notes = [523.25, 659.25, 783.99, 1046.5];
|
| 758 |
-
notes.forEach((freq, i) => {
|
| 759 |
-
const osc = audioContext.createOscillator();
|
| 760 |
-
const gain = audioContext.createGain();
|
| 761 |
-
|
| 762 |
-
osc.connect(gain);
|
| 763 |
-
gain.connect(masterGainNode);
|
| 764 |
-
|
| 765 |
-
osc.frequency.value = freq;
|
| 766 |
-
osc.type = 'sine';
|
| 767 |
-
|
| 768 |
-
gain.gain.setValueAtTime(0, audioContext.currentTime + i * 0.08);
|
| 769 |
-
gain.gain.linearRampToValueAtTime(0.25, audioContext.currentTime + i * 0.08 + 0.05);
|
| 770 |
-
gain.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + i * 0.08 + 0.3);
|
| 771 |
-
|
| 772 |
-
osc.start(audioContext.currentTime + i * 0.08);
|
| 773 |
-
osc.stop(audioContext.currentTime + i * 0.08 + 0.3);
|
| 774 |
-
});
|
| 775 |
-
},
|
| 776 |
-
|
| 777 |
-
25: () => { // Critical Hit
|
| 778 |
-
const osc = audioContext.createOscillator();
|
| 779 |
-
const gain = audioContext.createGain();
|
| 780 |
-
const filter = audioContext.createBiquadFilter();
|
| 781 |
-
|
| 782 |
-
osc.connect(filter);
|
| 783 |
-
filter.connect(gain);
|
| 784 |
-
gain.connect(masterGainNode);
|
| 785 |
-
|
| 786 |
-
osc.type = 'sawtooth';
|
| 787 |
-
osc.frequency.setValueAtTime(100, audioContext.currentTime);
|
| 788 |
-
|
| 789 |
-
filter.type = 'highpass';
|
| 790 |
-
filter.frequency.setValueAtTime(500, audioContext.currentTime);
|
| 791 |
-
filter.Q.value = 15;
|
| 792 |
-
|
| 793 |
-
gain.gain.setValueAtTime(0.5, audioContext.currentTime);
|
| 794 |
-
gain.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.3);
|
| 795 |
-
|
| 796 |
-
osc.start(audioContext.currentTime);
|
| 797 |
-
osc.stop(audioContext.currentTime + 0.3);
|
| 798 |
-
},
|
| 799 |
-
|
| 800 |
-
26: () => { // Dodge
|
| 801 |
-
const noise = audioContext.createBufferSource();
|
| 802 |
-
const filter = audioContext.createBiquadFilter();
|
| 803 |
-
const gain = audioContext.createGain();
|
| 804 |
-
const bufferSize = audioContext.sampleRate * 0.15;
|
| 805 |
-
const buffer = audioContext.createBuffer(1, bufferSize, audioContext.sampleRate);
|
| 806 |
-
const output = buffer.getChannelData(0);
|
| 807 |
-
|
| 808 |
-
for (let i = 0; i < bufferSize; i++) {
|
| 809 |
-
output[i] = (Math.random() * 2 - 1) * Math.exp(-i / (bufferSize * 0.2));
|
| 810 |
}
|
| 811 |
-
|
| 812 |
-
|
| 813 |
-
|
| 814 |
-
|
| 815 |
-
|
| 816 |
-
|
| 817 |
-
|
| 818 |
-
|
| 819 |
-
|
| 820 |
-
|
| 821 |
-
|
| 822 |
-
|
| 823 |
-
|
| 824 |
-
|
| 825 |
-
|
| 826 |
-
|
| 827 |
-
|
| 828 |
-
|
| 829 |
-
|
| 830 |
-
|
| 831 |
-
|
| 832 |
-
|
| 833 |
-
|
| 834 |
-
|
| 835 |
-
|
| 836 |
-
|
| 837 |
-
|
| 838 |
-
|
| 839 |
-
|
| 840 |
-
|
| 841 |
-
|
| 842 |
-
|
| 843 |
-
|
| 844 |
-
|
| 845 |
-
|
| 846 |
-
|
| 847 |
-
|
| 848 |
-
|
| 849 |
-
|
| 850 |
-
|
| 851 |
-
|
| 852 |
-
|
| 853 |
-
|
| 854 |
-
|
| 855 |
-
|
| 856 |
-
|
|
|
|
|
|
| 4 |
<head>
|
| 5 |
<meta charset="UTF-8">
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 7 |
+
<title>Game Sound Synthesizer - 20 Effects</title>
|
| 8 |
<script src="https://cdn.tailwindcss.com"></script>
|
| 9 |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
| 10 |
<style>
|
|
|
|
| 149 |
</div>
|
| 150 |
<div>
|
| 151 |
<h1 class="text-2xl font-bold text-white neon-text">Game Sound Synthesizer</h1>
|
| 152 |
+
<p class="text-xs text-gray-200">20 Procedurally Generated Sound Effects</p>
|
| 153 |
+
<a href="https://huggingface.co/spaces/akhaliq/anycoder" class="text-xs text-blue-300 hover:text-blue-200 transition-colors">Built with anycoder</a>
|
| 154 |
</div>
|
| 155 |
</div>
|
| 156 |
<div class="flex items-center space-x-4">
|
|
|
|
| 207 |
{ id: 17, name: 'Fire', icon: 'fa-fire', category: 'element' },
|
| 208 |
{ id: 18, name: 'Thunder', icon: 'fa-cloud-bolt', category: 'element' },
|
| 209 |
{ id: 19, name: 'Level Up', icon: 'fa-trophy', category: 'ui' },
|
| 210 |
+
{ id: 20, name: 'Game Over', icon: 'fa-skull', category: 'ui' }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 211 |
];
|
| 212 |
|
| 213 |
// Sound synthesis functions
|
|
|
|
| 688 |
|
| 689 |
osc.start(audioContext.currentTime);
|
| 690 |
osc.stop(audioContext.currentTime + 1);
|
| 691 |
+
}
|
| 692 |
+
};
|
| 693 |
+
|
| 694 |
+
// Create visualizer bars
|
| 695 |
+
function createVisualizer() {
|
| 696 |
+
const visualizer = document.getElementById('visualizer');
|
| 697 |
+
for (let i = 0; i < 50; i++) {
|
| 698 |
+
const bar = document.createElement('div');
|
| 699 |
+
bar.className = 'bar';
|
| 700 |
+
bar.style.height = '5px';
|
| 701 |
+
visualizer.appendChild(bar);
|
| 702 |
+
}
|
| 703 |
+
}
|
| 704 |
+
|
| 705 |
+
// Animate visualizer
|
| 706 |
+
function animateVisualizer() {
|
| 707 |
+
const bars = document.querySelectorAll('.bar');
|
| 708 |
+
bars.forEach(bar => {
|
| 709 |
+
const height = Math.random() * 80 + 10;
|
| 710 |
+
bar.style.height = height + 'px';
|
| 711 |
+
});
|
| 712 |
+
}
|
| 713 |
+
|
| 714 |
+
// Play sound function
|
| 715 |
+
function playSound(soundId) {
|
| 716 |
+
if (soundSynthesizers[soundId]) {
|
| 717 |
+
soundSynthesizers[soundId]();
|
| 718 |
+
animateVisualizer();
|
| 719 |
+
|
| 720 |
+
// Add visual feedback
|
| 721 |
+
const button = document.querySelector(`[data-sound-id="${soundId}"]`);
|
| 722 |
+
if (button) {
|
| 723 |
+
button.classList.add('playing', 'pulse');
|
| 724 |
+
setTimeout(() => {
|
| 725 |
+
button.classList.remove('playing', 'pulse');
|
| 726 |
+
}, 500);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 727 |
}
|
| 728 |
+
}
|
| 729 |
+
}
|
| 730 |
+
|
| 731 |
+
// Create sound buttons
|
| 732 |
+
function createSoundButtons() {
|
| 733 |
+
const grid = document.getElementById('soundGrid');
|
| 734 |
+
sounds.forEach(sound => {
|
| 735 |
+
const button = document.createElement('button');
|
| 736 |
+
button.className = 'sound-button p-6 rounded-xl text-white flex flex-col items-center justify-center space-y-2 min-h-[120px]';
|
| 737 |
+
button.dataset.soundId = sound.id;
|
| 738 |
+
button.innerHTML = `
|
| 739 |
+
<i class="fas ${sound.icon} text-3xl"></i>
|
| 740 |
+
<span class="text-sm font-semibold">${sound.name}</span>
|
| 741 |
+
<span class="category-badge">${sound.category}</span>
|
| 742 |
+
`;
|
| 743 |
+
button.addEventListener('click', () => playSound(sound.id));
|
| 744 |
+
grid.appendChild(button);
|
| 745 |
+
});
|
| 746 |
+
}
|
| 747 |
+
|
| 748 |
+
// Volume control
|
| 749 |
+
document.getElementById('volumeControl').addEventListener('input', (e) => {
|
| 750 |
+
const volume = e.target.value / 100;
|
| 751 |
+
masterGainNode.gain.value = volume;
|
| 752 |
+
document.getElementById('volumeValue').textContent = e.target.value + '%';
|
| 753 |
+
});
|
| 754 |
+
|
| 755 |
+
// Random play
|
| 756 |
+
document.getElementById('randomPlay').addEventListener('click', () => {
|
| 757 |
+
const randomSound = sounds[Math.floor(Math.random() * sounds.length)];
|
| 758 |
+
playSound(randomSound.id);
|
| 759 |
+
});
|
| 760 |
+
|
| 761 |
+
// Initialize
|
| 762 |
+
createVisualizer();
|
| 763 |
+
createSoundButtons();
|
| 764 |
+
|
| 765 |
+
// Animate visualizer periodically
|
| 766 |
+
setInterval(() => {
|
| 767 |
+
if (Math.random() > 0.7) {
|
| 768 |
+
animateVisualizer();
|
| 769 |
+
}
|
| 770 |
+
}, 500);
|
| 771 |
+
</script>
|
| 772 |
+
</body>
|
| 773 |
+
|
| 774 |
+
</html>
|