|
|
<!DOCTYPE html> |
|
|
<html lang="en"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>Pyramid Builder Adventure - Game</title> |
|
|
<script src="https://cdn.tailwindcss.com"></script> |
|
|
<script src="https://unpkg.com/feather-icons"></script> |
|
|
<style> |
|
|
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap'); |
|
|
|
|
|
body { |
|
|
font-family: 'Poppins', sans-serif; |
|
|
background-color: #1a1a2e; |
|
|
color: #e6e6e6; |
|
|
overflow: hidden; |
|
|
} |
|
|
.game-container { |
|
|
perspective: 1000px; |
|
|
position: relative; |
|
|
height: 100vh; |
|
|
width: 100vw; |
|
|
overflow: hidden; |
|
|
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); |
|
|
} |
|
|
|
|
|
.block { |
|
|
background: #fff; |
|
|
box-shadow: 0 4px 15px rgba(0,0,0,0.1); |
|
|
transition: all 0.2s ease; |
|
|
} |
|
|
.block:hover { |
|
|
transform: scale(1.1); |
|
|
box-shadow: 0 6px 20px rgba(0,0,0,0.15); |
|
|
} |
|
|
.block:active { |
|
|
cursor: grabbing; |
|
|
transform: scale(0.95); |
|
|
} |
|
|
.block-dragged { |
|
|
position: absolute; |
|
|
pointer-events: none; |
|
|
z-index: 100; |
|
|
transform: rotate(5deg); |
|
|
box-shadow: 0 10px 30px rgba(0,0,0,0.2); |
|
|
} |
|
|
|
|
|
.construction-zone { |
|
|
background: #f0f4f8; |
|
|
border-top: 2px dashed #cbd5e0; |
|
|
} |
|
|
|
|
|
.pyramid-block { |
|
|
background: #4fd1c5; |
|
|
box-shadow: 0 2px 5px rgba(0,0,0,0.1); |
|
|
transition: all 0.3s ease; |
|
|
} |
|
|
|
|
|
.particle { |
|
|
position: absolute; |
|
|
background-color: #4fd1c5; |
|
|
border-radius: 50%; |
|
|
pointer-events: none; |
|
|
opacity: 0.8; |
|
|
} |
|
|
|
|
|
.game-ui { |
|
|
background-color: white; |
|
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1); |
|
|
border-radius: 12px; |
|
|
} |
|
|
.btn-game { |
|
|
transition: all 0.2s ease; |
|
|
color: #4a5568; |
|
|
} |
|
|
|
|
|
.btn-game:hover { |
|
|
transform: scale(1.1); |
|
|
background-color: #e6fffa; |
|
|
color: #2c5282; |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body> |
|
|
<div class="game-container"> |
|
|
|
|
|
<div class="absolute top-4 left-4 z-10 game-ui rounded-lg p-3 flex items-center"> |
|
|
<span id="blocks-counter" class="font-bold text-gray-700">Blocks: 0/10</span> |
|
|
</div> |
|
|
<div class="absolute top-4 right-4 z-10 flex space-x-2"> |
|
|
<button id="pause-btn" class="game-ui p-2 rounded-lg btn-game"> |
|
|
<i data-feather="pause" class="text-gray-700"></i> |
|
|
</button> |
|
|
<button id="restart-btn" class="game-ui p-2 rounded-lg btn-game"> |
|
|
<i data-feather="refresh-cw" class="text-gray-700"></i> |
|
|
</button> |
|
|
<button id="home-btn" class="game-ui p-2 rounded-lg btn-game"> |
|
|
<i data-feather="home" class="text-gray-700"></i> |
|
|
</button> |
|
|
<button id="sound-btn" class="game-ui p-2 rounded-lg btn-game"> |
|
|
<i data-feather="volume-2" class="text-gray-700"></i> |
|
|
</button> |
|
|
<button id="language-btn" class="game-ui p-2 rounded-lg btn-game"> |
|
|
<img src="https://flagcdn.com/w20/gb.png" class="w-5 h-5"> |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
<div class="absolute inset-0 flex flex-col"> |
|
|
|
|
|
<div id="blocks-area" class="h-1/2 p-6 flex flex-wrap justify-center gap-6 content-start bg-white"> |
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="construction-area" class="h-1/2 relative construction-zone flex items-end justify-center"> |
|
|
<div id="pyramid-base" class="w-64 h-8 bg-teal-100 rounded-sm"></div> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div id="game-overlay" class="absolute inset-0 bg-white bg-opacity-90 hidden flex-col items-center justify-center z-20"> |
|
|
<h2 id="pause-title" class="text-4xl font-bold mb-8 text-gray-800">Game Paused</h2> |
|
|
<button id="resume-btn" class="px-8 py-3 bg-teal-500 text-white rounded-full text-xl font-semibold mb-4 hover:bg-teal-600 transition"> |
|
|
Resume Game |
|
|
</button> |
|
|
<button id="menu-btn" class="px-8 py-3 bg-gray-200 text-gray-800 rounded-full text-xl font-semibold hover:bg-gray-300 transition"> |
|
|
Back to Menu |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
<div id="language-selector" class="absolute top-16 right-4 z-30 bg-white rounded-xl shadow-lg p-2 hidden"> |
|
|
<div class="flex flex-col space-y-1"> |
|
|
<button class="language-option flex items-center px-4 py-3 rounded-lg hover:bg-teal-50 transition" data-lang="en"> |
|
|
<img src="https://flagcdn.com/w20/gb.png" class="w-5 h-5 mr-2"> English |
|
|
</button> |
|
|
<button class="language-option flex items-center px-4 py-3 rounded-lg hover:bg-teal-50 transition" data-lang="ar"> |
|
|
<img src="https://flagcdn.com/w20/sa.png" class="w-5 h-5 mr-2"> العربية |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<script> |
|
|
feather.replace(); |
|
|
|
|
|
const gameState = { |
|
|
blocksStacked: 0, |
|
|
isPaused: false, |
|
|
isMuted: false, |
|
|
language: 'en', |
|
|
heldBlock: null, |
|
|
blocksInRow: {0: 0} |
|
|
}; |
|
|
|
|
|
const translations = { |
|
|
en: { |
|
|
blocks: "Blocks", |
|
|
pause: "Pause", |
|
|
resume: "Resume", |
|
|
gamePaused: "Game Paused", |
|
|
backToMenu: "Back to Menu", |
|
|
gameComplete: "Pyramid Complete!", |
|
|
restart: "Restart" |
|
|
}, |
|
|
ar: { |
|
|
blocks: "الكتل", |
|
|
pause: "إيقاف مؤقت", |
|
|
resume: "استئناف", |
|
|
gamePaused: "اللعبة متوقفة", |
|
|
backToMenu: "العودة إلى القائمة", |
|
|
gameComplete: "اكتمل الهرم!", |
|
|
restart: "إعادة التشغيل" |
|
|
} |
|
|
}; |
|
|
|
|
|
const blocksCounter = document.getElementById('blocks-counter'); |
|
|
const pauseBtn = document.getElementById('pause-btn'); |
|
|
const restartBtn = document.getElementById('restart-btn'); |
|
|
const homeBtn = document.getElementById('home-btn'); |
|
|
const soundBtn = document.getElementById('sound-btn'); |
|
|
const languageBtn = document.getElementById('language-btn'); |
|
|
const player = document.getElementById('player'); |
|
|
const stonesContainer = document.getElementById('stones-container'); |
|
|
const pyramidArea = document.getElementById('pyramid-area'); |
|
|
const collectedStones = document.getElementById('collected-stones'); |
|
|
const gameOverlay = document.getElementById('game-overlay'); |
|
|
const pauseTitle = document.getElementById('pause-title'); |
|
|
const resumeBtn = document.getElementById('resume-btn'); |
|
|
const menuBtn = document.getElementById('menu-btn'); |
|
|
const languageSelector = document.getElementById('language-selector'); |
|
|
|
|
|
function initGame() { |
|
|
updateLanguage(gameState.language); |
|
|
generateBlocks(); |
|
|
setupEventListeners(); |
|
|
|
|
|
|
|
|
document.addEventListener('mousemove', (e) => { |
|
|
if (gameState.heldBlock) { |
|
|
gameState.heldBlock.style.left = `${e.clientX - 30}px`; |
|
|
gameState.heldBlock.style.top = `${e.clientY - 30}px`; |
|
|
} |
|
|
}); |
|
|
} |
|
|
|
|
|
function generateBlocks() { |
|
|
const blocksArea = document.getElementById('blocks-area'); |
|
|
blocksArea.innerHTML = ''; |
|
|
|
|
|
for (let i = 0; i < 10; i++) { |
|
|
const block = document.createElement('div'); |
|
|
block.className = 'block w-14 h-14 bg-white rounded-md cursor-grab flex items-center justify-center'; |
|
|
block.innerHTML = '<div class="w-10 h-10 bg-teal-100 rounded-sm"></div>'; |
|
|
block.style.position = 'relative'; |
|
|
block.style.transform = `rotate(${Math.random() * 6 - 3}deg)`; |
|
|
block.dataset.id = `block-${i}`; |
|
|
block.addEventListener('mousedown', startDrag); |
|
|
blocksArea.appendChild(block); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function startDrag(e) { |
|
|
if (gameState.isPaused) return; |
|
|
|
|
|
const block = e.target; |
|
|
gameState.draggedBlock = block; |
|
|
|
|
|
|
|
|
gameState.dragStartX = e.clientX; |
|
|
gameState.dragStartY = e.clientY; |
|
|
gameState.blockStartX = block.getBoundingClientRect().left; |
|
|
gameState.blockStartY = block.getBoundingClientRect().top; |
|
|
|
|
|
|
|
|
block.style.position = 'fixed'; |
|
|
block.style.zIndex = '100'; |
|
|
block.style.transform = 'rotate(5deg)'; |
|
|
block.style.filter = 'drop-shadow(0 0 5px rgba(0,0,0,0.5))'; |
|
|
block.style.left = `${gameState.blockStartX}px`; |
|
|
block.style.top = `${gameState.blockStartY}px`; |
|
|
|
|
|
document.addEventListener('mousemove', dragBlock); |
|
|
document.addEventListener('mouseup', stopDrag); |
|
|
|
|
|
e.preventDefault(); |
|
|
} |
|
|
|
|
|
|
|
|
function dragBlock(e) { |
|
|
if (!gameState.draggedBlock) return; |
|
|
|
|
|
const block = gameState.draggedBlock; |
|
|
const dx = e.clientX - gameState.dragStartX; |
|
|
const dy = e.clientY - gameState.dragStartY; |
|
|
|
|
|
block.style.left = `${gameState.blockStartX + dx}px`; |
|
|
block.style.top = `${gameState.blockStartY + dy}px`; |
|
|
} |
|
|
|
|
|
|
|
|
function stopDrag(e) { |
|
|
if (!gameState.draggedBlock) return; |
|
|
|
|
|
const block = gameState.draggedBlock; |
|
|
const constructionArea = document.getElementById('construction-area'); |
|
|
const areaRect = constructionArea.getBoundingClientRect(); |
|
|
|
|
|
|
|
|
if (e.clientX >= areaRect.left && e.clientX <= areaRect.right && |
|
|
e.clientY >= areaRect.top && e.clientY <= areaRect.bottom) { |
|
|
|
|
|
placeInPyramid(block); |
|
|
} else { |
|
|
|
|
|
block.style.position = 'relative'; |
|
|
block.style.left = 'auto'; |
|
|
block.style.top = 'auto'; |
|
|
block.style.zIndex = 'auto'; |
|
|
block.style.transform = ''; |
|
|
block.style.filter = ''; |
|
|
|
|
|
|
|
|
document.getElementById('blocks-area').appendChild(block); |
|
|
} |
|
|
|
|
|
document.removeEventListener('mousemove', dragBlock); |
|
|
document.removeEventListener('mouseup', stopDrag); |
|
|
gameState.draggedBlock = null; |
|
|
} |
|
|
} |
|
|
|
|
|
function placeInPyramid(block) { |
|
|
if (gameState.isPaused) return; |
|
|
|
|
|
|
|
|
const baseWidth = 5; |
|
|
const row = Math.floor(Math.sqrt(gameState.blocksStacked * 2)); |
|
|
const blocksInRow = baseWidth - row; |
|
|
|
|
|
|
|
|
if (blocksInRow > 0) { |
|
|
block.className = 'pyramid-block w-14 h-14 rounded-md shadow-sm absolute flex items-center justify-center'; |
|
|
block.innerHTML = '<div class="w-12 h-12 bg-teal-400 rounded-sm"></div>'; |
|
|
block.style.position = 'absolute'; |
|
|
block.style.cursor = 'default'; |
|
|
|
|
|
const rowY = 14 + (row * 14); |
|
|
const spacing = (320 - (blocksInRow * 56)) / (blocksInRow + 1); |
|
|
const blockX = spacing + ((gameState.blocksInRow[row] || 0) * (56 + spacing)); |
|
|
block.style.bottom = `${rowY}px`; |
|
|
block.style.left = `${blockX}px`; |
|
|
|
|
|
document.getElementById('construction-area').appendChild(block); |
|
|
|
|
|
|
|
|
gameState.blocksStacked++; |
|
|
gameState.blocksInRow[row] = (gameState.blocksInRow[row] || 0) + 1; |
|
|
|
|
|
|
|
|
if (gameState.blocksInRow[row] >= blocksInRow) { |
|
|
gameState.blocksInRow[row + 1] = 0; |
|
|
} |
|
|
|
|
|
updateUI(); |
|
|
|
|
|
|
|
|
if (gameState.blocksStacked >= 10) { |
|
|
pauseGame(); |
|
|
pauseTitle.textContent = translations[gameState.language].gameComplete; |
|
|
} |
|
|
|
|
|
|
|
|
createParticles(block); |
|
|
} else { |
|
|
|
|
|
block.style.position = 'relative'; |
|
|
block.style.left = 'auto'; |
|
|
block.style.top = 'auto'; |
|
|
block.style.zIndex = 'auto'; |
|
|
block.style.transform = ''; |
|
|
block.style.filter = ''; |
|
|
|
|
|
document.getElementById('blocks-area').appendChild(block); |
|
|
} |
|
|
} |
|
|
|
|
|
function createParticles(element) { |
|
|
const rect = element.getBoundingClientRect(); |
|
|
const centerX = rect.left + rect.width / 2; |
|
|
const centerY = rect.top + rect.height / 2; |
|
|
|
|
|
for (let i = 0; i < 15; i++) { |
|
|
const particle = document.createElement('div'); |
|
|
particle.className = 'particle'; |
|
|
|
|
|
const size = Math.random() * 5 + 2; |
|
|
particle.style.width = `${size}px`; |
|
|
particle.style.height = `${size}px`; |
|
|
|
|
|
const angle = Math.random() * Math.PI * 2; |
|
|
const distance = Math.random() * 30 + 10; |
|
|
const duration = Math.random() * 1 + 0.5; |
|
|
|
|
|
particle.style.left = `${centerX}px`; |
|
|
particle.style.top = `${centerY}px`; |
|
|
|
|
|
document.body.appendChild(particle); |
|
|
|
|
|
setTimeout(() => { |
|
|
particle.style.transform = `translate(${Math.cos(angle) * distance}px, ${Math.sin(angle) * distance}px)`; |
|
|
particle.style.opacity = '0'; |
|
|
}, 10); |
|
|
|
|
|
setTimeout(() => { |
|
|
particle.remove(); |
|
|
}, duration * 1000); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function pauseGame() { |
|
|
gameState.isPaused = true; |
|
|
gameOverlay.classList.remove('hidden'); |
|
|
pauseBtn.innerHTML = `<i data-feather="play"></i>`; |
|
|
feather.replace(); |
|
|
} |
|
|
|
|
|
function resumeGame() { |
|
|
gameState.isPaused = false; |
|
|
gameOverlay.classList.add('hidden'); |
|
|
pauseBtn.innerHTML = `<i data-feather="pause"></i>`; |
|
|
feather.replace(); |
|
|
} |
|
|
|
|
|
|
|
|
function toggleSound() { |
|
|
gameState.isMuted = !gameState.isMuted; |
|
|
soundBtn.innerHTML = `<i data-feather="${gameState.isMuted ? 'volume-x' : 'volume-2'}"></i>`; |
|
|
feather.replace(); |
|
|
} |
|
|
|
|
|
|
|
|
function updateLanguage(lang) { |
|
|
gameState.language = lang; |
|
|
document.documentElement.lang = lang; |
|
|
document.documentElement.dir = lang === 'ar' ? 'rtl' : 'ltr'; |
|
|
|
|
|
const texts = translations[lang]; |
|
|
|
|
|
|
|
|
blocksCounter.textContent = `${texts.blocks}: ${gameState.blocksStacked}/10`; |
|
|
pauseBtn.innerHTML = `<i data-feather="pause"></i>`; |
|
|
restartBtn.innerHTML = `<i data-feather="refresh-cw"></i>`; |
|
|
pauseTitle.textContent = texts.gamePaused; |
|
|
resumeBtn.textContent = texts.resume; |
|
|
menuBtn.textContent = texts.backToMenu; |
|
|
|
|
|
|
|
|
languageBtn.innerHTML = `<img src="https://flagcdn.com/w20/${lang === 'en' ? 'gb' : 'sa'}.png" class="w-5 h-5">`; |
|
|
|
|
|
feather.replace(); |
|
|
} |
|
|
|
|
|
|
|
|
function updateUI() { |
|
|
blocksCounter.textContent = `${translations[gameState.language].blocks}: ${gameState.blocksStacked}/10`; |
|
|
} |
|
|
|
|
|
function setupEventListeners() { |
|
|
pauseBtn.addEventListener('click', () => { |
|
|
if (gameState.isPaused) { |
|
|
resumeGame(); |
|
|
} else { |
|
|
pauseGame(); |
|
|
} |
|
|
}); |
|
|
restartBtn.addEventListener('click', () => { |
|
|
|
|
|
gameState.blocksStacked = 0; |
|
|
gameState.isPaused = false; |
|
|
|
|
|
|
|
|
|
|
|
document.getElementById('construction-area').innerHTML = |
|
|
'<div id="pyramid-base" class="w-64 h-8 bg-yellow-800 rounded-sm"></div>'; |
|
|
|
|
|
|
|
|
gameState.blocksInRow = {0: 0}; |
|
|
|
|
|
|
|
|
generateBlocks(); |
|
|
|
|
|
updateUI(); |
|
|
gameOverlay.classList.add('hidden'); |
|
|
pauseBtn.innerHTML = `<i data-feather="pause"></i>`; |
|
|
feather.replace(); |
|
|
}); |
|
|
|
|
|
soundBtn.addEventListener('click', toggleSound); |
|
|
|
|
|
languageBtn.addEventListener('click', () => { |
|
|
languageSelector.classList.toggle('hidden'); |
|
|
}); |
|
|
|
|
|
resumeBtn.addEventListener('click', resumeGame); |
|
|
menuBtn.addEventListener('click', () => { |
|
|
window.location.href = 'index.html'; |
|
|
}); |
|
|
|
|
|
homeBtn.addEventListener('click', () => { |
|
|
window.location.href = 'index.html'; |
|
|
}); |
|
|
|
|
|
document.querySelectorAll('.language-option').forEach(option => { |
|
|
option.addEventListener('click', () => { |
|
|
updateLanguage(option.dataset.lang); |
|
|
languageSelector.classList.add('hidden'); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
initGame(); |
|
|
</script> |
|
|
</body> |
|
|
</html> |
|
|
|