File size: 3,697 Bytes
bba8bcb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
document.addEventListener('DOMContentLoaded', () => {
// DOM elements
const canvas = document.getElementById('unscramble-canvas');
const ctx = canvas.getContext('2d');
const loadingMessage = document.getElementById('loading-message');
// Prevent right-click on the canvas
canvas.oncontextmenu = (e) => {
e.preventDefault();
return false;
};
// --- Main Unscrambling Logic ---
async function unscramble() {
try {
// 1. Fetch the map data and the scrambled image simultaneously
const [mapResponse, scrambledImage] = await Promise.all([
fetch('assets/map.json'),
loadImage('assets/scrambled.png')
]);
if (!mapResponse.ok) {
throw new Error(`Failed to load map.json: ${mapResponse.statusText}`);
}
const mapData = await mapResponse.json();
const { gridSize, scrambleMap, width, height } = mapData;
// Hide the loading message and set canvas dimensions
loadingMessage.style.display = 'none';
canvas.width = width;
canvas.height = height;
// 2. Calculate the tile dimensions
const tileW = canvas.width / gridSize;
const tileH = canvas.height / gridSize;
// 3. Create an "inverse map" for easy unscrambling.
// The scrambleMap tells us: new_position -> original_position
// We need to know where the tile for an original_position is located now.
const inverseMap = new Array(scrambleMap.length);
for (let newIndex = 0; newIndex < scrambleMap.length; newIndex++) {
const originalIndex = scrambleMap[newIndex];
inverseMap[originalIndex] = newIndex;
}
// 4. Loop through each TILE of the FINAL image and draw it on the canvas
for (let originalIndex = 0; originalIndex < scrambleMap.length; originalIndex++) {
// Find where this tile is located in the SCRAMBLED image
const scrambledIndex = inverseMap[originalIndex];
// Calculate source (from scrambled.png) and destination (on canvas) coordinates
const sourceX = (scrambledIndex % gridSize) * tileW;
const sourceY = Math.floor(scrambledIndex / gridSize) * tileH;
const destX = (originalIndex % gridSize) * tileW;
const destY = Math.floor(originalIndex / gridSize) * tileH;
// Copy the rectangular tile from the hidden scrambled image to the visible canvas
ctx.drawImage(
scrambledImage, // The source image
sourceX, sourceY, // Top-left corner of the source tile
tileW, tileH, // Dimensions of the source tile
destX, destY, // Top-left corner of the destination on the canvas
tileW, tileH // Dimensions of the destination tile
);
}
} catch (error) {
console.error("Unscrambling failed:", error);
loadingMessage.textContent = `Error: ${error.message}`;
loadingMessage.style.color = 'red';
}
}
// Helper function to load an image and return a promise
function loadImage(src) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = (err) => reject(new Error(`Failed to load image: ${src}`));
img.src = src;
});
}
// Run the main function
unscramble();
}); |