Edita código
Copiar al portapapeles
Ejecutar »
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=yes,minimal-ui"> <meta name="mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <title>Monument Matching Test</title> <style> @import url('https://fonts.googleapis.com/css2?family=Fredoka+One&family=Roboto:wght@400;700&display=swap'); body { font-family: 'Roboto', sans-serif; background-color: #f0f0f0; padding: 20px; text-align: center; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; } .container { background-color: white; border-radius: 10px; padding: 20px; margin: 0 auto; position: relative; box-shadow: 0 0 10px rgba(0,0,0,0.1); max-width: 90%; width: 640px; } .matching-columns { display: flex; justify-content: space-between; flex-wrap: wrap; } .column { width: 42%; } .matching-item { display: flex; align-items: center; margin-bottom: 20px; position: relative; } .monument-name, .description { background-color: #e8f5e9; padding: 10px; border-radius: 5px; flex-grow: 1; font-size: 18px; padding-left: 20px; } .description { background-color: #e3f2fd; } .connection-point { width: 15px; height: 15px; border-radius: 50%; background-color: white; border: 4px solid orange; position: absolute; top: 50%; transform: translateY(-50%); cursor: pointer; } .left .connection-point { right: -12px; } .right .connection-point { left: -12px; } .timer, .score { font-size: 24px; font-weight: bold; margin-bottom: 20px; display: inline-block; padding: 10px; border-radius: 10px; background: linear-gradient(45deg, #FFC107, #FFEB3B); box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1); border: 1px solid #FFEB3B; } #dragLine { position: absolute; background-color: #000; height: 2px; pointer-events: none; z-index: 1000; } .connection-line { position: absolute; background-color: #000; height: 2px; pointer-events: none; } .incorrect { background-color: #FF6347 !important; border-color: #FF4500 !important; } .correct { background-color: #4CAF50 !important; border-color: #388E3C !important; } .hidden { display: none; } .controls { display: none; margin-top: 20px; } .control-btn { margin: 10px; padding: 10px 20px; font-size: 18px; border: none; border-radius: 10px; background: linear-gradient(45deg, #64B5F6, #42A5F5); color: white; cursor: pointer; box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1); } .control-btn:active { box-shadow: inset 2px 2px 5px rgba(0, 0, 0, 0.1); } .connection-point.solution { background-color: #2196F3; } </style> </head> <body> <div class="container" id="matchingContainer"> <div class="timer" id="timer">02:00</div> <div class="score">Emparejamientos correctos: <span id="correctMatches">0</span>/6</div> <div id="dragLine"></div> <div class="matching-columns"> <div class="column left"> <div class="matching-item"> <div class="monument-name">Taj Mahal</div> <div class="connection-point" data-id="1"></div> </div> <div class="matching-item"> <div class="monument-name">Torre Eiffel</div> <div class="connection-point" data-id="2"></div> </div> <div class="matching-item"> <div class="monument-name">Estatua de la Libertad</div> <div class="connection-point" data-id="3"></div> </div> <div class="matching-item"> <div class="monument-name">La Gran Muralla China</div> <div class="connection-point" data-id="4"></div> </div> <div class="matching-item"> <div class="monument-name">Machu Picchu</div> <div class="connection-point" data-id="5"></div> </div> <div class="matching-item"> </div> </div> <div class="column right"> <div class="matching-item"> <div class="connection-point" data-id="4"></div> <div class="description">Fortificaciones en el norte de China</div> </div> <div class="matching-item"> <div class="connection-point" data-id="2"></div> <div class="description">Torre de celosÃa de hierro en ParÃs</div> </div> <div class="matching-item"> <div class="connection-point" data-id="5"></div> <div class="description">Ciudadela inca del siglo XV en Perú</div> </div> <div class="matching-item"> <div class="connection-point" data-id="1"></div> <div class="description">Mausoleo icónico en Agra, India</div> </div> <div class="matching-item"> <div class="connection-point" data-id="3"></div> <div class="description">Escultura neoclásica colosal en Nueva York</div> </div> </div> </div> </div> <div class="controls" id="controls"> <button class="control-btn" id="newGameBtn">Nueva Partida</button> <button class="control-btn" id="showSolutionsBtn">Mostrar Soluciones</button> </div> <script> window.onload = function () { shufflePositions(); // Barajar posiciones al inicio const container = document.getElementById('matchingContainer'); const dragLine = document.getElementById('dragLine'); const display = document.querySelector('#timer'); const scoreDisplay = document.getElementById('correctMatches'); const controls = document.getElementById('controls'); const newGameBtn = document.getElementById('newGameBtn'); const showSolutionsBtn = document.getElementById('showSolutionsBtn'); let correctMatches = 0; let startPoint = null; let timerInterval = startTimer(120, display); let gameEnded = false; const connections = { 1: "Taj Mahal", 2: "Eiffel Tower", 3: "Statue of Liberty", 4: "Great Wall of China", 5: "Machu Picchu", 6: "Colosseum" }; function enableConnections(enable) { document.querySelectorAll('.connection-point').forEach(point => { point.style.pointerEvents = enable ? 'auto' : 'none'; }); } enableConnections(true); document.querySelectorAll('.connection-point').forEach(point => { point.addEventListener('mousedown', (e) => { if (!startPoint && !gameEnded) { startPoint = e.target; dragLine.classList.remove('hidden'); } }); }); container.addEventListener('mousemove', (e) => { if (startPoint && !gameEnded) { drawDragLine(e); } }); container.addEventListener('mouseup', (e) => { if (startPoint && !gameEnded) { const endPoint = document.elementFromPoint(e.clientX, e.clientY); if (endPoint && endPoint.classList.contains('connection-point') && startPoint !== endPoint) { if (startPoint.dataset.id === endPoint.dataset.id) { correctMatches++; scoreDisplay.textContent = correctMatches; drawLine(startPoint, endPoint, '#4CAF50'); startPoint.classList.add('correct'); endPoint.classList.add('correct'); if (correctMatches === 6) { clearInterval(timerInterval); endGame(true); } } else { const tempLine = drawLine(startPoint, endPoint, '#FF4500'); markIncorrect(startPoint, endPoint, tempLine); } } startPoint = null; dragLine.classList.add('hidden'); } }); newGameBtn.addEventListener('click', () => { location.reload(); }); showSolutionsBtn.addEventListener('click', showSolutions); function drawDragLine(e) { const containerRect = container.getBoundingClientRect(); const x1 = startPoint.getBoundingClientRect().left + startPoint.offsetWidth / 2 - containerRect.left; const y1 = startPoint.getBoundingClientRect().top + startPoint.offsetHeight / 2 - containerRect.top; const x2 = e.clientX - containerRect.left; const y2 = e.clientY - containerRect.top; const length = Math.sqrt(Math.pow(x2 - x1, 2) + (y2 - y1) ** 2); const angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI; dragLine.style.width = `${length}px`; dragLine.style.left = `${x1}px`; dragLine.style.top = `${y1}px`; dragLine.style.transform = `rotate(${angle}deg)`; dragLine.style.transformOrigin = '0 0'; } function drawLine(from, to, color) { const line = document.createElement("div"); line.className = "connection-line"; line.style.backgroundColor = color; const fromRect = from.getBoundingClientRect(); const toRect = to.getBoundingClientRect(); const containerRect = container.getBoundingClientRect(); const x1 = fromRect.left + fromRect.width / 2 - containerRect.left; const y1 = fromRect.top + fromRect.height / 2 - containerRect.top; const x2 = toRect.left + toRect.width / 2 - containerRect.left; const y2 = toRect.top + toRect.height / 2 - containerRect.top; const length = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2); const angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI; line.style.width = `${length}px`; line.style.left = `${x1}px`; line.style.top = `${y1}px`; line.style.transform = `rotate(${angle}deg)`; line.style.transformOrigin = '0 0'; container.appendChild(line); return line; } function markIncorrect(from, to, line) { from.classList.add('incorrect'); to.classList.add('incorrect'); setTimeout(() => { from.classList.remove('incorrect'); to.classList.remove('incorrect'); container.removeChild(line); }, 1000); } function endGame(allMatched) { gameEnded = true; enableConnections(false); controls.style.display = 'block'; if (allMatched) { showSolutionsBtn.style.display = 'none'; } else { showSolutionsBtn.style.display = 'inline-block'; // Mostrar botón de soluciones si no todos los emparejamientos son correctos } } function showSolutions() { const correctConnections = document.querySelectorAll('.correct'); const connectedIds = Array.from(correctConnections).map(point => point.dataset.id); for (let [id, name] of Object.entries(connections)) { if (!connectedIds.includes(id)) { const from = document.querySelector(`.left .connection-point[data-id="${id}"]`); const to = document.querySelector(`.right .connection-point[data-id="${id}"]`); drawLine(from, to, '#2196F3'); from.classList.add('solution'); to.classList.add('solution'); } } showSolutionsBtn.style.display = 'none'; } function startTimer(duration, display) { let timer = duration, minutes, seconds; const interval = setInterval(function () { minutes = parseInt(timer / 60, 10); seconds = parseInt(timer % 60, 10); minutes = minutes < 10 ? "0" + minutes : minutes; seconds = seconds < 10 ? "0" + seconds : seconds; display.textContent = minutes + ":" + seconds; if (--timer < 0) { clearInterval(interval); gameEnded = true; // Evitar dibujar más lÃneas tras finalizar el tiempo endGame(false); } }, 1000); return interval; } function shuffle(array) { for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } return array; } function shufflePositions() { const leftColumn = document.querySelector('.column.left'); const rightColumn = document.querySelector('.column.right'); const leftItems = Array.from(leftColumn.children); const rightItems = Array.from(rightColumn.children); shuffle(leftItems); shuffle(rightItems); leftItems.forEach(item => leftColumn.appendChild(item)); rightItems.forEach(item => rightColumn.appendChild(item)); } }; </script> </body> </html>
Resultado
Instrucciones