// Debug alert for mobile debugging
if (typeof debugAlert === 'function') {
debugAlert('object.js starting to load');
}
/**
* Open the game controller overlay
*/
function openGameOverlay() {
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
*/
function renderProjectOverview() {
const container = document.getElementById('projectOverview');
if (!container) return;
container.innerHTML = '';
// Create main sections
const sections = [
createTileGroupsSection(),
createTilemapsSection(),
createProjectStatsSection()
];
sections.forEach(section => {
if (section) {
container.appendChild(section);
}
});
}
/**
* Create tile groups section
*/
function createTileGroupsSection() {
const section = document.createElement('div');
section.style.cssText = 'margin-bottom: 20px; padding: 15px; background: #1a1a1a; border-radius: 8px;';
const title = document.createElement('h3');
title.textContent = 'Tile Groups';
title.style.cssText = 'margin: 0 0 10px 0; color: #6cf; font-size: 18px;';
section.appendChild(title);
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;';
const detailsHTML = [
`<div><strong>URL:</strong> ${group.url || 'None'}</div>`,
`<div><strong>Group ID:</strong> ${group.id || index}</div>`
];
if (group.tiles && group.tiles.length > 0) {
const firstTile = group.tiles[0];
detailsHTML.push(`<div><strong>Tile Size:</strong> ${firstTile.size || 'Unknown'}px</div>`);
detailsHTML.push(`<div><strong>Tile IDs:</strong> ${group.tiles.map(t => t.uniqueId).join(', ')}</div>`);
}
details.innerHTML = detailsHTML.join('');
groupDiv.appendChild(details);
// Tile previews
if (group.tiles && group.tiles.length > 0) {
const previewDiv = document.createElement('div');
previewDiv.style.cssText = 'margin-top: 10px; display: flex; gap: 5px; flex-wrap: wrap;';
group.tiles.slice(0, 10).forEach(tile => { // Show max 10 previews
const canvas = document.createElement('canvas');
canvas.width = 32;
canvas.height = 32;
canvas.style.cssText = 'border: 1px solid #666; border-radius: 4px;';
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);
previewDiv.appendChild(canvas);
});
if (group.tiles.length > 10) {
const moreText = document.createElement('span');
moreText.textContent = `+${group.tiles.length - 10} more`;
moreText.style.cssText = 'color: #888; font-size: 11px; align-self: center;';
previewDiv.appendChild(moreText);
}
groupDiv.appendChild(previewDiv);
}
section.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;';
section.appendChild(noGroups);
}
return section;
}
/**
* Create tilemaps section
*/
function createTilemapsSection() {
const section = document.createElement('div');
section.style.cssText = 'margin-bottom: 20px; padding: 15px; background: #1a1a1a; border-radius: 8px;';
const title = document.createElement('h3');
title.textContent = 'Tilemaps';
title.style.cssText = 'margin: 0 0 10px 0; color: #6cf; font-size: 18px;';
section.appendChild(title);
if (typeof tilemaps !== 'undefined' && tilemaps && tilemaps.length > 0) {
tilemaps.forEach((tilemap, index) => {
const tilemapDiv = document.createElement('div');
tilemapDiv.style.cssText = 'margin-bottom: 15px; padding: 10px; background: #2a2a2a; border-radius: 6px;';
// Tilemap header
const header = document.createElement('div');
const isActive = typeof currentTilemapIndex !== 'undefined' && currentTilemapIndex === index;
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;';
const totalTiles = tilemap.data ? tilemap.data.filter(t => t !== 0).length : 0;
const totalCells = tilemap.width * tilemap.height;
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>Map ID:</strong> ${tilemap.id}</div>
`;
tilemapDiv.appendChild(details);
// Usage statistics
if (tilemap.data && totalTiles > 0) {
const usageDiv = document.createElement('div');
usageDiv.style.cssText = 'margin-top: 8px; font-size: 11px; color: #aaa;';
const usedTileIds = [...new Set(tilemap.data.filter(t => t !== 0))];
const fillPercent = ((totalTiles / totalCells) * 100).toFixed(1);
usageDiv.innerHTML = `
<div><strong>Fill:</strong> ${fillPercent}% (${totalTiles}/${totalCells})</div>
<div><strong>Unique Tiles Used:</strong> ${usedTileIds.length} (IDs: ${usedTileIds.join(', ')})</div>
`;
tilemapDiv.appendChild(usageDiv);
}
section.appendChild(tilemapDiv);
});
} else {
const noTilemaps = document.createElement('div');
noTilemaps.textContent = 'No tilemaps created yet. Use the Tilemap Editor to create maps.';
noTilemaps.style.cssText = 'color: #888; font-style: italic; padding: 10px;';
section.appendChild(noTilemaps);
}
return section;
}
/**
* Create project statistics section
*/
function createProjectStatsSection() {
const section = document.createElement('div');
section.style.cssText = 'margin-bottom: 20px; padding: 15px; background: #1a1a1a; border-radius: 8px;';
const title = document.createElement('h3');
title.textContent = 'Project Statistics';
title.style.cssText = 'margin: 0 0 10px 0; color: #6cf; font-size: 18px;';
section.appendChild(title);
const stats = calculateProjectStats();
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> ${stats.totalGroups}</div>
<div style="margin-bottom: 8px;"><strong>Total Unique Tiles:</strong> ${stats.totalTiles}</div>
<div style="margin-bottom: 8px;"><strong>Total Tilemaps:</strong> ${stats.totalMaps}</div>
<div style="margin-bottom: 8px;"><strong>Total Placed Tiles:</strong> ${stats.totalPlacedTiles}</div>
<div style="margin-bottom: 8px;"><strong>Source Images:</strong> ${stats.sourceImages}</div>
<div style="margin-bottom: 8px;"><strong>Tile Sizes Used:</strong> ${stats.tileSizes.join('px, ')}px</div>
`;
section.appendChild(statsDiv);
// Add export button
const exportBtn = document.createElement('button');
exportBtn.textContent = 'Export Project Data';
exportBtn.style.cssText = `
margin-top: 15px; background: #4a4; color: white; border: none;
padding: 8px 16px; border-radius: 6px; cursor: pointer; font-size: 14px;
`;
exportBtn.addEventListener('click', exportProjectData);
section.appendChild(exportBtn);
return section;
}
/**
* 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;
}
/**
* Export project data
*/
function exportProjectData() {
const projectData = {
metadata: {
exportDate: new Date().toISOString(),
version: "1.0"
},
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!');
}
// Debug alert for mobile debugging - success
if (typeof debugAlert === 'function') {
debugAlert('object.js loaded successfully');
}