← Back
TUFF · Now Playing
Bloons TD 5
const progressBar = document.getElementById('progressBar');
const loadedMb = document.getElementById('loadedMb');
const totalMb = document.getElementById('totalMb');
const statusText = document.getElementById('statusText');
const loader = document.getElementById('loader');
const container = document.getElementById('ruffle-container');
function fmt(bytes) {
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
}
function launchGame(arrayBuffer) {
statusText.textContent = 'Starting...';
progressBar.classList.remove('indeterminate');
progressBar.style.width = '100%';
setTimeout(() => {
loader.classList.add('fade-out');
container.classList.add('visible');
}, 500);
const script = document.createElement('script');
script.src = "https://unpkg.com/@ruffle-rs/ruffle";
script.onload = () => {
const ruffle = window.RufflePlayer.newest();
const player = ruffle.createPlayer();
container.appendChild(player);
player.style.width = "100%";
player.style.height = "100%";
player.load({ data: arrayBuffer });
};
document.head.appendChild(script);
}
async function loadWithProgress() {
try {
statusText.textContent = 'Downloading...';
const response = await fetch(SWF_URL);
if (!response.ok) throw new Error('Network error');
const contentLength = response.headers.get('content-length');
const total = contentLength ? parseInt(contentLength) : null;
if (total) {
totalMb.textContent = fmt(total);
progressBar.classList.remove('indeterminate');
} else {
totalMb.textContent = '? MB';
}
const reader = response.body.getReader();
const chunks = [];
let loaded = 0;
while (true) {
const { done, value } = await reader.read();
if (done) break;
chunks.push(value);
loaded += value.length;
loadedMb.textContent = fmt(loaded);
if (total) {
const pct = Math.round((loaded / total) * 100);
progressBar.style.width = pct + '%';
statusText.textContent = `Downloading... ${pct}%`;
} else {
statusText.textContent = `Downloaded ${fmt(loaded)}`;
}
}
const all = new Uint8Array(loaded);
let offset = 0;
for (const chunk of chunks) { all.set(chunk, offset); offset += chunk.length; }
launchGame(all.buffer);
} catch (err) {
statusText.textContent = 'Error loading — check console';
progressBar.classList.remove('indeterminate');
progressBar.style.background = '#ef4444';
progressBar.style.width = '100%';
console.error(err);
}
}
loadWithProgress();