|
|
<!DOCTYPE html> |
|
|
<html lang="ar" dir="rtl"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>لعبة العداء القوية</title> |
|
|
<script src="https://cdn.tailwindcss.com"></script> |
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
|
|
<style> |
|
|
@import url('https://fonts.googleapis.com/css2?family=Tajawal:wght@400;700;900&display=swap'); |
|
|
|
|
|
body { |
|
|
font-family: 'Tajawal', sans-serif; |
|
|
background-color: #1a1a2e; |
|
|
color: white; |
|
|
overflow-x: hidden; |
|
|
} |
|
|
|
|
|
.game-container { |
|
|
position: relative; |
|
|
height: 500px; |
|
|
overflow: hidden; |
|
|
background: linear-gradient(to bottom, #16213e, #0f3460); |
|
|
border-radius: 15px; |
|
|
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5); |
|
|
} |
|
|
|
|
|
.player { |
|
|
position: absolute; |
|
|
width: 60px; |
|
|
height: 80px; |
|
|
bottom: 100px; |
|
|
left: 50px; |
|
|
transition: transform 0.1s; |
|
|
z-index: 10; |
|
|
} |
|
|
|
|
|
.obstacle { |
|
|
position: absolute; |
|
|
width: 50px; |
|
|
height: 50px; |
|
|
bottom: 100px; |
|
|
right: -50px; |
|
|
z-index: 5; |
|
|
} |
|
|
|
|
|
.coin { |
|
|
position: absolute; |
|
|
width: 30px; |
|
|
height: 30px; |
|
|
z-index: 5; |
|
|
animation: spin 2s linear infinite; |
|
|
} |
|
|
|
|
|
.ground { |
|
|
position: absolute; |
|
|
bottom: 0; |
|
|
width: 100%; |
|
|
height: 100px; |
|
|
background-color: #533d2b; |
|
|
z-index: 1; |
|
|
} |
|
|
|
|
|
.jump { |
|
|
animation: jump 0.8s linear; |
|
|
} |
|
|
|
|
|
@keyframes jump { |
|
|
0% { transform: translateY(0); } |
|
|
50% { transform: translateY(-150px); } |
|
|
100% { transform: translateY(0); } |
|
|
} |
|
|
|
|
|
@keyframes spin { |
|
|
0% { transform: rotate(0deg); } |
|
|
100% { transform: rotate(360deg); } |
|
|
} |
|
|
|
|
|
.moving-bg { |
|
|
position: absolute; |
|
|
top: 0; |
|
|
left: 0; |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
background-image: url('https://images.unsplash.com/photo-1506318137071-a8e063b4bec0?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80'); |
|
|
background-size: cover; |
|
|
opacity: 0.2; |
|
|
z-index: 0; |
|
|
} |
|
|
|
|
|
.power-up { |
|
|
position: absolute; |
|
|
width: 40px; |
|
|
height: 40px; |
|
|
right: -40px; |
|
|
z-index: 5; |
|
|
animation: pulse 1s infinite; |
|
|
} |
|
|
|
|
|
@keyframes pulse { |
|
|
0% { transform: scale(1); } |
|
|
50% { transform: scale(1.2); } |
|
|
100% { transform: scale(1); } |
|
|
} |
|
|
|
|
|
.game-over { |
|
|
transform: scale(1.5) rotate(5deg); |
|
|
transition: all 0.5s; |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body class="min-h-screen flex flex-col items-center justify-center p-4"> |
|
|
<div class="w-full max-w-4xl mx-auto"> |
|
|
<h1 class="text-4xl font-bold text-center mb-6 text-yellow-400"> |
|
|
<i class="fas fa-running mr-2"></i> لعبة العداء القوية |
|
|
</h1> |
|
|
|
|
|
<div class="flex justify-between items-center mb-4 px-4"> |
|
|
<div class="flex items-center"> |
|
|
<span class="text-xl font-bold text-yellow-400 mr-2"> |
|
|
<i class="fas fa-coins"></i> <span id="score">0</span> |
|
|
</span> |
|
|
<span class="text-xl font-bold text-red-500 ml-4"> |
|
|
<i class="fas fa-heart"></i> <span id="lives">3</span> |
|
|
</span> |
|
|
</div> |
|
|
|
|
|
<div class="flex items-center"> |
|
|
<span class="text-xl font-bold text-blue-400"> |
|
|
<i class="fas fa-bolt"></i> <span id="power">0</span>% |
|
|
</span> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="game-container relative" id="gameContainer"> |
|
|
<div class="moving-bg"></div> |
|
|
<div class="ground"></div> |
|
|
|
|
|
<div id="player" class="player"> |
|
|
<img src="https://cdn-icons-png.flaticon.com/512/3899/3899618.png" alt="العداء" class="w-full h-full"> |
|
|
</div> |
|
|
|
|
|
<div id="gameOver" class="hidden absolute inset-0 flex flex-col items-center justify-center bg-black bg-opacity-70 z-20"> |
|
|
<h2 class="text-4xl font-bold text-red-500 mb-4">انتهت اللعبة!</h2> |
|
|
<p class="text-2xl mb-6">النقاط: <span id="finalScore">0</span></p> |
|
|
<button id="restartBtn" class="px-6 py-3 bg-yellow-500 text-black font-bold rounded-full hover:bg-yellow-400 transition"> |
|
|
<i class="fas fa-redo mr-2"></i> إعادة المحاولة |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="mt-6 flex justify-between items-center"> |
|
|
<div class="flex space-x-4"> |
|
|
<button id="jumpBtn" class="px-6 py-3 bg-blue-600 text-white font-bold rounded-full hover:bg-blue-500 transition"> |
|
|
<i class="fas fa-arrow-up mr-2"></i> قفز |
|
|
</button> |
|
|
<button id="powerBtn" class="px-6 py-3 bg-purple-600 text-white font-bold rounded-full hover:bg-purple-500 transition disabled:opacity-50" disabled> |
|
|
<i class="fas fa-bolt mr-2"></i> سرعة خارقة |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
<div class="flex items-center"> |
|
|
<span class="text-lg mr-2">المستوى:</span> |
|
|
<select id="levelSelect" class="bg-gray-800 text-white px-3 py-2 rounded"> |
|
|
<option value="1">سهل</option> |
|
|
<option value="2">متوسط</option> |
|
|
<option value="3">صعب</option> |
|
|
</select> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="mt-8 bg-gray-900 bg-opacity-50 p-4 rounded-lg"> |
|
|
<h3 class="text-xl font-bold mb-2 text-yellow-400"> |
|
|
<i class="fas fa-info-circle mr-2"></i> تعليمات اللعبة |
|
|
</h3> |
|
|
<ul class="list-disc list-inside space-y-1"> |
|
|
<li>اضغط زر القفز أو مفتاح المسافة للقفز فوق العقبات</li> |
|
|
<li>اجمع العملات لزيادة نقاطك</li> |
|
|
<li>اجمع وحدات الطاقة لتفعيل السرعة الخارقة</li> |
|
|
<li>استخدم السرعة الخارقة لاجتياز العقبات الصعبة</li> |
|
|
<li>لديك 3 محاولات فقط!</li> |
|
|
</ul> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<script> |
|
|
document.addEventListener('DOMContentLoaded', () => { |
|
|
|
|
|
const gameContainer = document.getElementById('gameContainer'); |
|
|
const player = document.getElementById('player'); |
|
|
const scoreElement = document.getElementById('score'); |
|
|
const livesElement = document.getElementById('lives'); |
|
|
const powerElement = document.getElementById('power'); |
|
|
const gameOverScreen = document.getElementById('gameOver'); |
|
|
const finalScoreElement = document.getElementById('finalScore'); |
|
|
const restartBtn = document.getElementById('restartBtn'); |
|
|
const jumpBtn = document.getElementById('jumpBtn'); |
|
|
const powerBtn = document.getElementById('powerBtn'); |
|
|
const levelSelect = document.getElementById('levelSelect'); |
|
|
|
|
|
|
|
|
let score = 0; |
|
|
let lives = 3; |
|
|
let power = 0; |
|
|
let isJumping = false; |
|
|
let isGameOver = false; |
|
|
let gameSpeed = 5; |
|
|
let isPowerActive = false; |
|
|
let powerTimeout; |
|
|
let gameInterval; |
|
|
let obstacleInterval; |
|
|
let coinInterval; |
|
|
let powerUpInterval; |
|
|
|
|
|
|
|
|
const levels = { |
|
|
1: { speed: 5, obstacleFreq: 2000, coinFreq: 1500, powerFreq: 10000 }, |
|
|
2: { speed: 8, obstacleFreq: 1500, coinFreq: 1200, powerFreq: 8000 }, |
|
|
3: { speed: 12, obstacleFreq: 1000, coinFreq: 1000, powerFreq: 6000 } |
|
|
}; |
|
|
|
|
|
|
|
|
function initGame() { |
|
|
score = 0; |
|
|
lives = 3; |
|
|
power = 0; |
|
|
isGameOver = false; |
|
|
isPowerActive = false; |
|
|
|
|
|
scoreElement.textContent = score; |
|
|
livesElement.textContent = lives; |
|
|
powerElement.textContent = power; |
|
|
|
|
|
gameOverScreen.classList.add('hidden'); |
|
|
player.classList.remove('game-over'); |
|
|
|
|
|
|
|
|
document.querySelectorAll('.obstacle, .coin, .power-up').forEach(el => el.remove()); |
|
|
|
|
|
|
|
|
const level = parseInt(levelSelect.value); |
|
|
gameSpeed = levels[level].speed; |
|
|
|
|
|
|
|
|
startIntervals(level); |
|
|
|
|
|
|
|
|
if (gameInterval) clearInterval(gameInterval); |
|
|
gameInterval = setInterval(updateGame, 20); |
|
|
} |
|
|
|
|
|
|
|
|
function startIntervals(level) { |
|
|
if (obstacleInterval) clearInterval(obstacleInterval); |
|
|
if (coinInterval) clearInterval(coinInterval); |
|
|
if (powerUpInterval) clearInterval(powerUpInterval); |
|
|
|
|
|
obstacleInterval = setInterval(createObstacle, levels[level].obstacleFreq); |
|
|
coinInterval = setInterval(createCoin, levels[level].coinFreq); |
|
|
powerUpInterval = setInterval(createPowerUp, levels[level].powerFreq); |
|
|
} |
|
|
|
|
|
|
|
|
function updateGame() { |
|
|
if (isGameOver) return; |
|
|
|
|
|
|
|
|
document.querySelectorAll('.obstacle').forEach(obstacle => { |
|
|
const obstacleRight = parseInt(window.getComputedStyle(obstacle).getPropertyValue('right')); |
|
|
const newRight = obstacleRight + gameSpeed; |
|
|
obstacle.style.right = `${newRight}px`; |
|
|
|
|
|
|
|
|
if (checkCollision(player, obstacle)) { |
|
|
handleCollision(); |
|
|
obstacle.remove(); |
|
|
} |
|
|
|
|
|
|
|
|
if (newRight > gameContainer.offsetWidth + 50) { |
|
|
obstacle.remove(); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
document.querySelectorAll('.coin').forEach(coin => { |
|
|
const coinRight = parseInt(window.getComputedStyle(coin).getPropertyValue('right')); |
|
|
const newRight = coinRight + gameSpeed; |
|
|
coin.style.right = `${newRight}px`; |
|
|
|
|
|
|
|
|
if (checkCollision(player, coin)) { |
|
|
score += 10; |
|
|
scoreElement.textContent = score; |
|
|
coin.remove(); |
|
|
playSound('coin'); |
|
|
} |
|
|
|
|
|
|
|
|
if (newRight > gameContainer.offsetWidth + 50) { |
|
|
coin.remove(); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
document.querySelectorAll('.power-up').forEach(powerUp => { |
|
|
const powerUpRight = parseInt(window.getComputedStyle(powerUp).getPropertyValue('right')); |
|
|
const newRight = powerUpRight + gameSpeed; |
|
|
powerUp.style.right = `${newRight}px`; |
|
|
|
|
|
|
|
|
if (checkCollision(player, powerUp)) { |
|
|
power = Math.min(100, power + 25); |
|
|
powerElement.textContent = power; |
|
|
powerUp.remove(); |
|
|
playSound('power'); |
|
|
updatePowerButton(); |
|
|
} |
|
|
|
|
|
|
|
|
if (newRight > gameContainer.offsetWidth + 50) { |
|
|
powerUp.remove(); |
|
|
} |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
function createObstacle() { |
|
|
if (isGameOver) return; |
|
|
|
|
|
const obstacle = document.createElement('div'); |
|
|
obstacle.className = 'obstacle'; |
|
|
|
|
|
|
|
|
const obstacleTypes = [ |
|
|
{ img: 'https://cdn-icons-png.flaticon.com/512/2821/2821637.png', height: 50 }, |
|
|
{ img: 'https://cdn-icons-png.flaticon.com/512/2821/2821772.png', height: 60 }, |
|
|
{ img: 'https://cdn-icons-png.flaticon.com/512/2821/2821797.png', height: 70 } |
|
|
]; |
|
|
|
|
|
const type = obstacleTypes[Math.floor(Math.random() * obstacleTypes.length)]; |
|
|
obstacle.style.height = `${type.height}px`; |
|
|
|
|
|
const img = document.createElement('img'); |
|
|
img.src = type.img; |
|
|
img.className = 'w-full h-full'; |
|
|
obstacle.appendChild(img); |
|
|
|
|
|
|
|
|
const bottom = Math.random() > 0.5 ? 100 : 80; |
|
|
obstacle.style.bottom = `${bottom}px`; |
|
|
|
|
|
gameContainer.appendChild(obstacle); |
|
|
} |
|
|
|
|
|
|
|
|
function createCoin() { |
|
|
if (isGameOver) return; |
|
|
|
|
|
const coin = document.createElement('div'); |
|
|
coin.className = 'coin'; |
|
|
|
|
|
const img = document.createElement('img'); |
|
|
img.src = 'https://cdn-icons-png.flaticon.com/512/2821/2821970.png'; |
|
|
img.className = 'w-full h-full'; |
|
|
coin.appendChild(img); |
|
|
|
|
|
|
|
|
const top = 100 + Math.random() * 200; |
|
|
coin.style.top = `${top}px`; |
|
|
coin.style.right = '0px'; |
|
|
|
|
|
gameContainer.appendChild(coin); |
|
|
} |
|
|
|
|
|
|
|
|
function createPowerUp() { |
|
|
if (isGameOver) return; |
|
|
|
|
|
const powerUp = document.createElement('div'); |
|
|
powerUp.className = 'power-up'; |
|
|
|
|
|
const img = document.createElement('img'); |
|
|
img.src = 'https://cdn-icons-png.flaticon.com/512/3520/3520766.png'; |
|
|
img.className = 'w-full h-full'; |
|
|
powerUp.appendChild(img); |
|
|
|
|
|
|
|
|
const top = 100 + Math.random() * 200; |
|
|
powerUp.style.top = `${top}px`; |
|
|
powerUp.style.right = '0px'; |
|
|
|
|
|
gameContainer.appendChild(powerUp); |
|
|
} |
|
|
|
|
|
|
|
|
function checkCollision(player, element) { |
|
|
const playerRect = player.getBoundingClientRect(); |
|
|
const elementRect = element.getBoundingClientRect(); |
|
|
|
|
|
return !( |
|
|
playerRect.right < elementRect.left + 20 || |
|
|
playerRect.left > elementRect.right - 20 || |
|
|
playerRect.bottom < elementRect.top + 20 || |
|
|
playerRect.top > elementRect.bottom - 20 |
|
|
); |
|
|
} |
|
|
|
|
|
|
|
|
function handleCollision() { |
|
|
if (isPowerActive) return; |
|
|
|
|
|
lives--; |
|
|
livesElement.textContent = lives; |
|
|
player.classList.add('game-over'); |
|
|
playSound('hit'); |
|
|
|
|
|
setTimeout(() => { |
|
|
player.classList.remove('game-over'); |
|
|
}, 300); |
|
|
|
|
|
if (lives <= 0) { |
|
|
endGame(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function endGame() { |
|
|
isGameOver = true; |
|
|
clearInterval(gameInterval); |
|
|
clearInterval(obstacleInterval); |
|
|
clearInterval(coinInterval); |
|
|
clearInterval(powerUpInterval); |
|
|
|
|
|
finalScoreElement.textContent = score; |
|
|
gameOverScreen.classList.remove('hidden'); |
|
|
playSound('gameover'); |
|
|
} |
|
|
|
|
|
|
|
|
function jump() { |
|
|
if (isJumping || isGameOver) return; |
|
|
|
|
|
isJumping = true; |
|
|
player.classList.add('jump'); |
|
|
playSound('jump'); |
|
|
|
|
|
setTimeout(() => { |
|
|
player.classList.remove('jump'); |
|
|
isJumping = false; |
|
|
}, 800); |
|
|
} |
|
|
|
|
|
|
|
|
function activatePower() { |
|
|
if (power < 100 || isPowerActive || isGameOver) return; |
|
|
|
|
|
isPowerActive = true; |
|
|
power = 0; |
|
|
powerElement.textContent = power; |
|
|
powerBtn.disabled = true; |
|
|
player.style.filter = 'drop-shadow(0 0 10px gold)'; |
|
|
playSound('powerup'); |
|
|
|
|
|
|
|
|
const originalSpeed = gameSpeed; |
|
|
gameSpeed *= 1.5; |
|
|
|
|
|
powerTimeout = setTimeout(() => { |
|
|
isPowerActive = false; |
|
|
gameSpeed = originalSpeed; |
|
|
player.style.filter = 'none'; |
|
|
updatePowerButton(); |
|
|
}, 3000); |
|
|
} |
|
|
|
|
|
|
|
|
function updatePowerButton() { |
|
|
powerBtn.disabled = power < 100; |
|
|
} |
|
|
|
|
|
|
|
|
function playSound(type) { |
|
|
|
|
|
console.log(`Playing sound: ${type}`); |
|
|
} |
|
|
|
|
|
|
|
|
document.addEventListener('keydown', (e) => { |
|
|
if (e.code === 'Space') { |
|
|
e.preventDefault(); |
|
|
jump(); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
jumpBtn.addEventListener('click', jump); |
|
|
powerBtn.addEventListener('click', activatePower); |
|
|
restartBtn.addEventListener('click', initGame); |
|
|
|
|
|
|
|
|
levelSelect.addEventListener('change', () => { |
|
|
if (!isGameOver) { |
|
|
const level = parseInt(levelSelect.value); |
|
|
gameSpeed = levels[level].speed; |
|
|
startIntervals(level); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
initGame(); |
|
|
}); |
|
|
</script> |
|
|
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=gghjgff/https-huggingface-co-spaces-enzostvs-deepsite" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
|
|
</html> |