📜
object_copy.js
Back
📝 Javascript ⚡ Executable Ctrl+S: Save • Ctrl+R: Run • Ctrl+F: Find
// Debug alert for mobile debugging if (typeof debugAlert === 'function') { debugAlert('object.js starting to load'); } /** * Open the game controller overlay */ function openGameController() { const overlayContent = document.getElementById('overlayContent'); overlayContent.innerHTML = ` <div style="height: 100%; overflow: auto; padding: 10px;"> <div id="projectOverview"></div> </div> `; renderProjectOverview(); } /** * Render the complete project overview in game controller */ function renderProjectOverview() { const container = document.getElementById('projectOverview'); if (!container) return; container.innerHTML = ''; // Tile Groups Section const groupsSection = document.createElement('div'); groupsSection.style.cssText = 'margin-bottom: 20px; padding: 15px; background: #1a1a1a; border-radius: 8px;'; const groupsTitle = document.createElement('h3'); groupsTitle.textContent = 'Tile Groups'; groupsTitle.style.cssText = 'margin: 0 0 10px 0; color: #6cf; font-size: 18px;'; groupsSection.appendChild(groupsTitle); if (typeof groups !== 'undefined' && groups && groups.length > 0) { groups.forEach((group, index) => { const groupDiv = document.createElement('div'); groupDiv.style.cssText = 'margin-bottom: 15px; padding: 10px; background: #2a2a2a; border-radius: 6px;'; // Group header const header = document.createElement('div'); header.innerHTML = ` <strong style="color: #fff;">Group ${index + 1}</strong> <span style="color: #888; margin-left: 10px;">${group.tiles ? group.tiles.length : 0} tiles</span> `; header.style.cssText = 'margin-bottom: 8px;'; groupDiv.appendChild(header); // Group details const details = document.createElement('div'); details.style.cssText = 'font-size: 12px; color: #ccc; margin-bottom: 10px;'; details.innerHTML = ` <div><strong>URL:</strong> ${group.url || 'None'}</div> <div><strong>Group ID:</strong> ${group.id || index}</div> ${group.tiles && group.tiles.length > 0 ? ` <div><strong>Tile Size:</strong> ${group.tiles[0].size || 'Unknown'}px</div> ` : ''} `; groupDiv.appendChild(details); // Tile previews with ID badges if (group.tiles && group.tiles.length > 0) { const previewDiv = document.createElement('div'); previewDiv.style.cssText = 'display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px;'; group.tiles.forEach(tile => { const tileWrapper = document.createElement('div'); tileWrapper.style.cssText = 'position: relative; display: inline-block;'; const canvas = document.createElement('canvas'); canvas.width = 48; canvas.height = 48; canvas.style.cssText = 'border: 2px solid #666; border-radius: 4px; background: #000;'; const ctx = canvas.getContext('2d'); const tempCanvas = document.createElement('canvas'); tempCanvas.width = tile.size; tempCanvas.height = tile.size; const tempCtx = tempCanvas.getContext('2d'); tempCtx.putImageData(tile.data, 0, 0); ctx.drawImage(tempCanvas, 0, 0, tile.size, tile.size, 0, 0, 48, 48); // Add ID badge const idBadge = document.createElement('span'); idBadge.textContent = tile.uniqueId; idBadge.style.cssText = ` position: absolute; bottom: -2px; right: -2px; background: rgba(0,0,0,0.8); color: #fff; font-size: 9px; padding: 1px 4px; border-radius: 3px; border: 1px solid #6cf; `; tileWrapper.appendChild(canvas); tileWrapper.appendChild(idBadge); previewDiv.appendChild(tileWrapper); }); groupDiv.appendChild(previewDiv); } groupsSection.appendChild(groupDiv); }); } else { const noGroups = document.createElement('div'); noGroups.textContent = 'No tile groups created yet. Use the Tile Picker to create groups.'; noGroups.style.cssText = 'color: #888; font-style: italic; padding: 10px;'; groupsSection.appendChild(noGroups); } container.appendChild(groupsSection); // Tilemaps Section const mapsSection = document.createElement('div'); mapsSection.style.cssText = 'margin-bottom: 20px; padding: 15px; background: #1a1a1a; border-radius: 8px;'; const mapsTitle = document.createElement('h3'); mapsTitle.textContent = 'Tilemaps'; mapsTitle.style.cssText = 'margin: 0 0 10px 0; color: #6cf; font-size: 18px;'; mapsSection.appendChild(mapsTitle); if (typeof tilemaps !== 'undefined' && tilemaps && tilemaps.length > 0) { tilemaps.forEach((tilemap, index) => { const tilemapDiv = document.createElement('div'); tilemapDiv.style.cssText = 'margin-bottom: 20px; padding: 10px; background: #2a2a2a; border-radius: 6px;'; const totalTiles = tilemap.data ? tilemap.data.filter(t => t !== 0).length : 0; const totalCells = tilemap.width * tilemap.height; const fillPercent = ((totalTiles / totalCells) * 100).toFixed(1); const isActive = typeof currentTilemapIndex !== 'undefined' && currentTilemapIndex === index; // Tilemap header const header = document.createElement('div'); header.innerHTML = ` <strong style="color: ${isActive ? '#6cf' : '#fff'};">${tilemap.name}</strong> ${isActive ? '<span style="color: #6cf; margin-left: 10px;">(Active)</span>' : ''} `; header.style.cssText = 'margin-bottom: 8px;'; tilemapDiv.appendChild(header); // Tilemap details const details = document.createElement('div'); details.style.cssText = 'font-size: 12px; color: #ccc; margin-bottom: 10px;'; details.innerHTML = ` <div><strong>Dimensions:</strong> ${tilemap.width} × ${tilemap.height} (${totalCells} cells)</div> <div><strong>Tile Size:</strong> ${tilemap.tileSize}px</div> <div><strong>Placed Tiles:</strong> ${totalTiles}</div> <div><strong>Fill:</strong> ${fillPercent}%</div> <div><strong>Map ID:</strong> ${tilemap.id}</div> `; tilemapDiv.appendChild(details); // Phaser-style 2D array display if (tilemap.data && tilemap.data.length > 0) { const arrayTitle = document.createElement('div'); arrayTitle.textContent = 'Phaser 2D Array:'; arrayTitle.style.cssText = 'font-weight: bold; color: #6cf; margin-bottom: 5px; font-size: 12px;'; tilemapDiv.appendChild(arrayTitle); const arrayContainer = document.createElement('div'); arrayContainer.style.cssText = ` background: #1a1a1a; padding: 10px; border-radius: 4px; font-family: 'Courier New', monospace; font-size: 10px; color: #ccc; overflow-x: auto; max-height: 200px; overflow-y: auto; `; // Convert 1D array to 2D array format let arrayText = '[\n'; for (let y = 0; y < tilemap.height; y++) { let row = ' ['; for (let x = 0; x < tilemap.width; x++) { const index = y * tilemap.width + x; const tileId = tilemap.data[index] || 0; row += tileId.toString().padStart(3, ' '); if (x < tilemap.width - 1) row += ','; } row += ']'; if (y < tilemap.height - 1) row += ','; arrayText += row + '\n'; } arrayText += ']'; // Format for display with proper line breaks const formattedArray = arrayText.split('\n').map(line => { return `<div style="line-height: 1.2;">${line}</div>`; }).join(''); arrayContainer.innerHTML = formattedArray; tilemapDiv.appendChild(arrayContainer); // Copy button for the array const copyBtn = document.createElement('button'); copyBtn.textContent = 'Copy Array'; copyBtn.style.cssText = ` margin-top: 5px; background: #444; color: white; border: none; padding: 4px 8px; border-radius: 4px; cursor: pointer; font-size: 10px; `; copyBtn.addEventListener('click', () => { navigator.clipboard.writeText(arrayText).then(() => { copyBtn.textContent = 'Copied!'; setTimeout(() => copyBtn.textContent = 'Copy Array', 1000); }); }); tilemapDiv.appendChild(copyBtn); } mapsSection.appendChild(tilemapDiv); }); } else { const noMaps = document.createElement('div'); noMaps.textContent = 'No tilemaps created yet. Use the Tilemap Editor to create maps.'; noMaps.style.cssText = 'color: #888; font-style: italic; padding: 10px;'; mapsSection.appendChild(noMaps); } container.appendChild(mapsSection); // Project Stats Section const statsSection = document.createElement('div'); statsSection.style.cssText = 'margin-bottom: 20px; padding: 15px; background: #1a1a1a; border-radius: 8px;'; const statsTitle = document.createElement('h3'); statsTitle.textContent = 'Project Statistics'; statsTitle.style.cssText = 'margin: 0 0 10px 0; color: #6cf; font-size: 18px;'; statsSection.appendChild(statsTitle); // Calculate stats let totalGroups = 0; let totalTiles = 0; let totalMaps = 0; let totalPlacedTiles = 0; if (typeof groups !== 'undefined' && groups) { totalGroups = groups.length; totalTiles = groups.reduce((sum, group) => sum + (group.tiles ? group.tiles.length : 0), 0); } if (typeof tilemaps !== 'undefined' && tilemaps) { totalMaps = tilemaps.length; totalPlacedTiles = tilemaps.reduce((sum, map) => { return sum + (map.data ? map.data.filter(t => t !== 0).length : 0); }, 0); } const statsDiv = document.createElement('div'); statsDiv.style.cssText = 'font-size: 14px; color: #ccc;'; statsDiv.innerHTML = ` <div style="margin-bottom: 8px;"><strong>Total Tile Groups:</strong> ${totalGroups}</div> <div style="margin-bottom: 8px;"><strong>Total Unique Tiles:</strong> ${totalTiles}</div> <div style="margin-bottom: 8px;"><strong>Total Tilemaps:</strong> ${totalMaps}</div> <div style="margin-bottom: 8px;"><strong>Total Placed Tiles:</strong> ${totalPlacedTiles}</div> `; statsSection.appendChild(statsDiv); container.appendChild(statsSection); // Export section const exportSection = document.createElement('div'); exportSection.style.cssText = 'padding: 15px; background: #1a1a1a; border-radius: 8px;'; const exportTitle = document.createElement('h3'); exportTitle.textContent = 'Export Project'; exportTitle.style.cssText = 'margin: 0 0 10px 0; color: #6cf; font-size: 18px;'; exportSection.appendChild(exportTitle); const exportBtn = document.createElement('button'); exportBtn.textContent = 'Export Complete Project'; exportBtn.style.cssText = ` background: #4a4; color: white; border: none; padding: 10px 20px; border-radius: 6px; cursor: pointer; font-size: 14px; `; exportBtn.addEventListener('click', exportCompleteProject); exportSection.appendChild(exportBtn); container.appendChild(exportSection); } /** * Export complete project data */ function exportCompleteProject() { const projectData = { metadata: { exportDate: new Date().toISOString(), version: "1.0", editor: "Tile Map Editor" }, tileGroups: typeof groups !== 'undefined' ? groups : [], tilemaps: typeof tilemaps !== 'undefined' ? tilemaps : [], statistics: calculateProjectStats() }; // Create downloadable JSON const dataStr = JSON.stringify(projectData, null, 2); const dataBlob = new Blob([dataStr], {type: 'application/json'}); const url = URL.createObjectURL(dataBlob); // Create download link const link = document.createElement('a'); link.href = url; link.download = `tilemap-project-${new Date().toISOString().split('T')[0]}.json`; // Trigger download document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(url); alert('Project data exported successfully!'); } /** * Calculate project statistics */ function calculateProjectStats() { const stats = { totalGroups: 0, totalTiles: 0, totalMaps: 0, totalPlacedTiles: 0, sourceImages: 0, tileSizes: [] }; // Tile group stats if (typeof groups !== 'undefined' && groups) { stats.totalGroups = groups.length; stats.totalTiles = groups.reduce((sum, group) => sum + (group.tiles ? group.tiles.length : 0), 0); const uniqueUrls = new Set(groups.map(g => g.url).filter(url => url)); stats.sourceImages = uniqueUrls.size; const sizes = new Set(); groups.forEach(group => { if (group.tiles) { group.tiles.forEach(tile => { if (tile.size) sizes.add(tile.size); }); } }); stats.tileSizes = Array.from(sizes).sort((a, b) => a - b); } // Tilemap stats if (typeof tilemaps !== 'undefined' && tilemaps) { stats.totalMaps = tilemaps.length; stats.totalPlacedTiles = tilemaps.reduce((sum, map) => { return sum + (map.data ? map.data.filter(t => t !== 0).length : 0); }, 0); } return stats; } // Debug alert for mobile debugging - success if (typeof debugAlert === 'function') { debugAlert('object.js loaded successfully'); }