📜
files_copy.js
Back
📝 Javascript ⚡ Executable Ctrl+S: Save • Ctrl+R: Run • Ctrl+F: Find
// Debug alert for mobile debugging if (typeof debugAlert === 'function') { debugAlert('files.js loaded'); } // Global variables for file management let selectedImage = null; let selectedImageName = null; let selectedImageDiv = null; let selectedTileSize = null; // DOM elements const fileList = document.getElementById('fileList'); const breadcrumb = document.querySelector('.breadcrumb'); const preview = document.getElementById('preview'); /** * Load files from the server for a given subdirectory * @param {string} sub - The subdirectory path */ function loadFiles(sub) { fetch('media.php?sub=' + encodeURIComponent(sub)) .then(r => r.json()) .then(data => { renderBreadcrumb(data.breadcrumb); renderFiles(data); }) .catch(err => console.error('Error loading files:', err)); } /** * Render the breadcrumb navigation * @param {Array} crumbs - Array of breadcrumb objects */ function renderBreadcrumb(crumbs) { breadcrumb.innerHTML = ''; crumbs.forEach(c => { const span = document.createElement('span'); span.textContent = c.label; span.onclick = () => loadFiles(c.sub); breadcrumb.appendChild(span); }); } /** * Render the file list (folders and images) * @param {Object} data - Data object containing folders and images arrays */ function renderFiles(data) { fileList.innerHTML = ''; preview.innerHTML = ''; // Render folders data.folders.forEach(f => { const div = document.createElement('div'); div.className = 'folder'; div.textContent = f.name; div.onclick = () => { // If folder name is numeric, treat it as tile size if (/^\d+$/.test(f.name)) { selectedTileSize = parseInt(f.name, 10); loadFiles(f.sub); } else { loadFiles(f.sub); } }; fileList.appendChild(div); }); // Render images data.images.forEach(img => { const div = document.createElement('div'); div.className = 'image'; const imgElement = document.createElement('img'); imgElement.src = img.url; imgElement.alt = img.name; div.appendChild(imgElement); div.onclick = () => { // Remove previous selection if (selectedImageDiv) { selectedImageDiv.classList.remove('selected'); } // Set new selection div.classList.add('selected'); selectedImageDiv = div; selectedImage = img.url; selectedImageName = img.name; showPreview(img); }; fileList.appendChild(div); }); } /** * Show preview of selected image * @param {Object} img - Image object with name and url */ function showPreview(img) { preview.innerHTML = ` <h3>Selected: ${img.name}</h3> <img id="previewImg" src="${img.url}" alt="${img.name}"> `; // Click big preview image to open tile picker document.getElementById('previewImg').onclick = () => openOverlay('tiles'); } /** * Open overlay with specified content type * @param {string} type - Type of overlay content ('tiles', 'map', 'game') */ function openOverlay(type) { const overlay = document.getElementById('overlay'); const overlayContent = document.getElementById('overlayContent'); overlayContent.innerHTML = ''; overlay.style.display = 'block'; if (type === 'tiles') { openTilePickerOverlay(); } else if (type === 'map') { openMapOverlay(); } else if (type === 'game') { openGameOverlay(); } } /** * Open the tile picker overlay */ function openTilePickerOverlay() { const overlayContent = document.getElementById('overlayContent'); if (selectedImage && selectedTileSize) { overlayContent.innerHTML = ` <h2>Tile Picker 🧩</h2> <p>Tile size: ${selectedTileSize}</p> <div id="groupTabs"></div> <div id="pickedImages"></div> <div id="tileViewport"> <div id="tileContainer"> <img id="tileImage" src="${selectedImage}" alt="${selectedImageName}"> </div> </div> `; // Initialize tile picker functionality initializeTilePicker(); } else { overlayContent.innerHTML = ` <h2>Tile Picker 🧩</h2> <p>Select an image and a numeric folder first.</p> `; } } /** * Open the map overlay */ function openMapOverlay() { openTilemapOverlay(); } /** * Open the game overlay */ function openGameOverlay() { const overlayContent = document.getElementById('overlayContent'); overlayContent.innerHTML = ` <div style="height: 100%; overflow: auto; padding: 10px;"> <div id="gameController"></div> </div> `; renderCompleteGameController(); } /** * Render complete game controller interface */ function renderCompleteGameController() { const container = document.getElementById('gameController'); if (!container) return; container.innerHTML = ''; // Game Object Section const gameSection = document.createElement('div'); gameSection.style.cssText = 'padding: 15px; background: #1a1a1a; border-radius: 8px; margin-bottom: 20px;'; gameSection.innerHTML = ` <h3 style="color: #6cf; margin: 0 0 15px 0;">🎮 Game Object</h3> <div style="margin-bottom: 10px;"> <strong style="color: #f44;">Mandatory:</strong> <div style="margin: 8px 0; padding: 10px; background: #333; border-radius: 4px; color: #ccc; font-size: 12px;"> <div>ID: game_001</div> <div>Name: My Tile Game</div> <div>Version: 1.0.0</div> </div> </div> <div style="margin-bottom: 10px;"> <strong style="color: #4a4;">Changeable:</strong> <div style="margin: 8px 0; padding: 10px; background: #333; border-radius: 4px; color: #ccc; font-size: 12px;"> <div>Rules: {win: "reach_exit", lose: "no_health", score: "collect"}</div> <div>Physics: {gravity: 300, friction: 0.8, bounce: 0.3}</div> <div>Theme: retro-pixel</div> </div> </div> <div> <strong style="color: #888;">Optional:</strong> <div style="margin: 8px 0; padding: 10px; background: #333; border-radius: 4px; color: #ccc; font-size: 12px;"> <div>UI Layout: minimal-hud</div> <div>Progression Mode: linear</div> <div>Settings: {difficulty: "normal", mode: "single"}</div> </div> </div> `; container.appendChild(gameSection); // Tile Groups Section with images and IDs const groupsSection = document.createElement('div'); groupsSection.style.cssText = 'padding: 15px; background: #1a1a1a; border-radius: 8px; margin-bottom: 20px;'; const groupsTitle = document.createElement('h3'); groupsTitle.textContent = '🧱 Tile Groups'; groupsTitle.style.cssText = 'color: #6cf; margin: 0 0 15px 0;'; 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: 20px; padding: 15px; background: #2a2a2a; border-radius: 6px; border-left: 4px solid #6cf;'; groupDiv.innerHTML = ` <h4 style="margin: 0 0 10px 0; color: #fff;">Group ${index + 1}</h4> <div style="margin-bottom: 10px;"> <strong style="color: #f44;">Mandatory:</strong> <div style="margin: 8px 0; padding: 10px; background: #333; border-radius: 4px; color: #ccc; font-size: 12px;"> <div>ID: group_${index + 1}</div> <div>Name: ${group.name || `Tile Group ${index + 1}`}</div> <div>Atlas Key: ${group.url ? group.url.split('/').pop() : 'none'}</div> <div>Tile Size: ${group.tiles && group.tiles[0] ? group.tiles[0].size : 32}px</div> </div> </div> <div style="margin-bottom: 10px;"> <strong style="color: #4a4;">Changeable:</strong> <div style="margin: 8px 0; padding: 10px; background: #333; border-radius: 4px; color: #ccc; font-size: 12px;"> <div>Members: ${group.tiles ? group.tiles.length : 0} tiles</div> </div> </div> <div style="margin-bottom: 10px;"> <strong style="color: #888;">Optional:</strong> <div style="margin: 8px 0; padding: 10px; background: #333; border-radius: 4px; color: #ccc; font-size: 12px;"> <div>Collidable: true</div> <div>Interactions: none</div> <div>AI Profile: idle</div> </div> </div> `; // Add tile previews with ID badges if (group.tiles && group.tiles.length > 0) { const previewDiv = document.createElement('div'); previewDiv.style.cssText = 'display: flex; gap: 5px; 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 = 32; canvas.height = 32; 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, 32, 32); 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: 8px; padding: 1px 3px; border-radius: 2px; border: 1px solid #6cf; `; tileWrapper.appendChild(canvas); tileWrapper.appendChild(idBadge); previewDiv.appendChild(tileWrapper); }); groupDiv.appendChild(previewDiv); } groupsSection.appendChild(groupDiv); }); } else { groupsSection.innerHTML += '<div style="color: #888; font-style: italic; padding: 10px;">No tile groups created yet. Use the Tile Picker to create groups.</div>'; } container.appendChild(groupsSection); // Tilemaps Section with arrays const mapsSection = document.createElement('div'); mapsSection.style.cssText = 'padding: 15px; background: #1a1a1a; border-radius: 8px; margin-bottom: 20px;'; const mapsTitle = document.createElement('h3'); mapsTitle.textContent = '🗺️ Tile Maps'; mapsTitle.style.cssText = 'color: #6cf; margin: 0 0 15px 0;'; 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: 15px; background: #2a2a2a; border-radius: 6px; border-left: 4px solid #6cf;'; const isActive = typeof currentTilemapIndex !== 'undefined' && currentTilemapIndex === index; const totalTiles = tilemap.data ? tilemap.data.filter(t => t !== 0).length : 0; const fillPercent = ((totalTiles / (tilemap.width * tilemap.height)) * 100).toFixed(1); tilemapDiv.innerHTML = ` <h4 style="margin: 0 0 10px 0; color: ${isActive ? '#6cf' : '#fff'};">${tilemap.name}${isActive ? ' (Active)' : ''}</h4> <div style="margin-bottom: 10px;"> <strong style="color: #f44;">Mandatory:</strong> <div style="margin: 8px 0; padding: 10px; background: #333; border-radius: 4px; color: #ccc; font-size: 12px;"> <div>ID: map_${tilemap.id}</div> <div>Name: ${tilemap.name}</div> <div>Rows: ${tilemap.height}</div> <div>Cols: ${tilemap.width}</div> </div> </div> <div style="margin-bottom: 10px;"> <strong style="color: #4a4;">Changeable:</strong> <div style="margin: 8px 0; padding: 10px; background: #333; border-radius: 4px; color: #ccc; font-size: 12px;"> <div>Start Points: {player: {x: 0, y: 0}}</div> <div>Layer Index: 1</div> <div>Background: #2a2a2a</div> </div> </div> <div style="margin-bottom: 10px;"> <strong style="color: #888;">Optional:</strong> <div style="margin: 8px 0; padding: 10px; background: #333; border-radius: 4px; color: #ccc; font-size: 12px;"> <div>Fill: ${fillPercent}% (${totalTiles} tiles)</div> <div>Events: []</div> <div>Progression: {nextMap: "level2"}</div> </div> </div> `; // Add Phaser 2D array if there's data if (tilemap.data && tilemap.data.length > 0) { const arrayDiv = document.createElement('div'); arrayDiv.innerHTML = '<strong style="color: #6cf;">Phaser 2D Array:</strong>'; const arrayContainer = document.createElement('div'); arrayContainer.style.cssText = ` background: #1a1a1a; padding: 10px; border-radius: 4px; margin-top: 5px; font-family: 'Courier New', monospace; font-size: 10px; color: #ccc; overflow-x: auto; max-height: 150px; overflow-y: auto; `; 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 += ']'; const formattedArray = arrayText.split('\n').map(line => { return `<div style="line-height: 1.2;">${line}</div>`; }).join(''); arrayContainer.innerHTML = formattedArray; arrayDiv.appendChild(arrayContainer); 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); }); }); arrayDiv.appendChild(copyBtn); tilemapDiv.appendChild(arrayDiv); } mapsSection.appendChild(tilemapDiv); }); } else { mapsSection.innerHTML += '<div style="color: #888; font-style: italic; padding: 10px;">No tilemaps created yet. Use the Tilemap Editor to create maps.</div>'; } container.appendChild(mapsSection); // Export section const exportSection = document.createElement('div'); exportSection.style.cssText = 'padding: 15px; background: #1a1a1a; border-radius: 8px;'; exportSection.innerHTML = ` <h3 style="margin: 0 0 10px 0; color: #6cf; font-size: 18px;">Export Project</h3> <button onclick="alert('Export functionality coming soon!')" style="background: #4a4; color: white; border: none; padding: 10px 20px; border-radius: 6px; cursor: pointer; font-size: 14px;"> Export Complete Project </button> `; container.appendChild(exportSection); }