const socket = io('https://broadfield-dev-dungeon-game.hf.space'); socket.on('connect', () => { console.log('Connected to the server!'); }); socket.on('connect_error', (error) => { console.error('Connection error:', error); }); socket.on('disconnect', () => { console.log('Disconnected from the server.'); }); const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); const tileSize = 32; // Preload individual images const images = { 'w': new Image(), 'f': new Image(), 'player': new Image(), 'goblin': new Image(), 'skeleton': new Image(), 'potion': new Image(), 'sword': new Image(), 'door': new Image() }; images['w'].src = '/static/wall.png'; images['f'].src = '/static/floor.png'; images['player'].src = '/static/player.png'; images['goblin'].src = '/static/goblin.png'; images['skeleton'].src = '/static/goblin.png'; // Reuse goblin for skeleton (update if needed) images['potion'].src = '/static/potion.png'; images['sword'].src = '/static/sword.png'; images['door'].src = '/static/door.png'; // Reuse sword for door (update if needed) socket.on('update_game', (state) => { drawGame(state); document.getElementById('health').textContent = state.health; document.getElementById('attack').textContent = state.attack; document.getElementById('inventory').textContent = state.inventory.join(', '); document.getElementById('level').textContent = state.level; document.getElementById('usePotion').disabled = !state.inventory.includes('potion'); if (state.health <= 0) { alert('Game Over! Refresh to restart.'); } }); socket.on('message', (msg) => { const messagesDiv = document.getElementById('messages'); messagesDiv.innerHTML += `
${msg}
`; messagesDiv.scrollTop = messagesDiv.scrollHeight; }); function drawGame(state) { ctx.clearRect(0, 0, canvas.width, canvas.height); // Draw visible 10x10 area centered on player for (let y = 0; y < state.terrain.length; y++) { for (let x = 0; x < state.terrain[y].length; x++) { const img = images[state.terrain[y][x] || 'f']; // Default to floor if empty if (img.complete) { ctx.drawImage(img, x * tileSize, y * tileSize, tileSize, tileSize); } } } // Draw entities on top for (let y = 0; y < state.entities.length; y++) { for (let x = 0; x < state.entities[y].length; x++) { if (state.entities[y][x] && images[state.entities[y][x]]) { const img = images[state.entities[y][x]]; if (img.complete) { ctx.drawImage(img, x * tileSize, y * tileSize, tileSize, tileSize); } } } } } document.addEventListener('keydown', (e) => { const directions = { 'ArrowUp': 'up', 'ArrowDown': 'down', 'ArrowLeft': 'left', 'ArrowRight': 'right' }; if (directions[e.key]) { socket.emit('move', directions[e.key]); } }); document.getElementById('usePotion').addEventListener('click', () => { socket.emit('use_item', 'potion'); }); // Ensure all images are loaded before drawing let imagesLoaded = 0; const totalImages = Object.keys(images).length; for (let key in images) { images[key].onload = () => { imagesLoaded++; if (imagesLoaded === totalImages) { console.log('All images loaded'); } }; images[key].onerror = () => { console.error(`Failed to load image: ${images[key].src}`); }; }