Meta Description" name="description" />
<!DOCTYPE html>
<html lang="ur">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>KALIM - Mobile Shooter</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; font-family: Arial, sans-serif; }
body { background: #000; overflow: hidden; touch-action: none; }
canvas { display: block; width: 100vw; height: 100vh; background: #080415; }
#mainMenu { position: fixed; inset: 0; background: radial-gradient(ellipse at center, #1a0f2e 0%, #000 75%); display: flex; flex-direction: column; justify-content: center; align-items: center; color: #ffb733; z-index: 100; }
#mainMenu h1 { font-size: 14vw; letter-spacing: 4px; text-shadow: 0 0 25px #ff9900; margin-bottom: 10px; }
.menu-btn { width: 60vw; padding: 14px; margin: 10px 0; font-size: 6vw; background: #d48828; border: none; border-radius: 12px; color: white; box-shadow: 0 0 15px #ff9900; }
#ui { position: fixed; top: 15px; left: 15px; color: white; font-size: 5vw; font-weight: bold; z-index: 10; display: none; }
#pauseBtn { position: fixed; top: 15px; right: 15px; width: 12vw; height: 12vw; background: #ff4444; border-radius: 50%; color: white; font-size: 5vw; border: none; z-index: 11; display: none; }
#controls { position: fixed; inset: 0; z-index: 20; pointer-events: none; display: none; }
#joystick { position: absolute; bottom: 30px; left: 30px; width: 22vw; height: 22vw; background: rgba(255,255,255,0.2); border-radius: 50%; pointer-events: auto; }
#joystickKnob { width: 10vw; height: 10vw; background: rgba(255,255,255,0.8); border-radius: 50%; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
#fireBtn { position: absolute; bottom: 30px; right: 30px; width: 20vw; height: 20vw; background: #ff3333; border-radius: 50%; color: white; font-size: 7vw; font-weight: bold; display: flex; justify-content: center; align-items: center; box-shadow: 0 0 20px #ff2222; pointer-events: auto; border: none; }
#gameOver { position: fixed; inset: 0; background: rgba(0,0,0,0.9); display: none; flex-direction: column; justify-content: center; align-items: center; color: #ff4444; z-index: 90; }
</style>
</head>
<body>
<div id="mainMenu">
<h1>KALIM</h1>
<h2>DESERT SIEGE</h2>
<button class="menu-btn" onclick="startGame()">🎮 گیم شروع کریں</button>
<button class="menu-btn" onclick="openHelp()">❓ کھیلنے کا طریقہ</button>
<button class="menu-btn" onclick="exitGame()">❓ باہر نکلیں</button>
</div>
<div id="ui">سکور: <span id="scoreText">0</span> | جان: <span id="livesText">3</span> | لہر: <span id="waveText">1</span></div>
<button id="pauseBtn" onclick="togglePause()">⏸️</button>
<div id="controls">
<div id="joystick"><div id="joystickKnob"></div></div>
<button id="fireBtn">فائر</button>
</div>
<div id="gameOver">
<h1>ختم ہو گیا</h1>
<button class="menu-btn" onclick="restartGame()">🔄 دوبارہ کھیلیں</button>
<button class="menu-btn" onclick="backToMenu()">🏠 مینو</button>
</div>
<canvas id="gameCanvas"></canvas>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
let gameRunning = false, gamePaused = false, gameOver = false, score = 0, lives = 3, wave = 1, frameCount = 0;
const player = { x: 0, y: 0, w: 56, h: 56, speed: 6, bullets: [], invulnerable: false, invulTimer: 0 };
let enemies = [], particles = [], enemySpeed = 2, spawnRate = 75;
const joystick = document.getElementById('joystick'), joystickKnob = document.getElementById('joystickKnob'), fireBtn = document.getElementById('fireBtn');
let joyActive = false, joyX = 0, joyY = 0, fireHold = false;
function resizeCanvas() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; player.x = canvas.width / 2 - player.w / 2; player.y = canvas.height - 100; }
resizeCanvas(); window.addEventListener('resize', resizeCanvas);
function startGame() { document.getElementById('mainMenu').style.display = 'none'; document.getElementById('ui').style.display = 'block'; document.getElementById('pauseBtn').style.display = 'block'; document.getElementById('controls').style.display = 'block'; resetGame(); gameRunning = true; }
function backToMenu() { document.getElementById('gameOver').style.display = 'none'; document.getElementById('ui').style.display = 'none'; document.getElementById('pauseBtn').style.display = 'none'; document.getElementById('controls').style.display = 'none'; document.getElementById('mainMenu').style.display = 'flex'; gameRunning = false; }
function openHelp() { alert('حرکت: بائیں جانب کے گول بٹن کو گھسیٹیں\nگولی چلائیں: سرخ فائر بٹن دبائیں\nروکیں: اوپر دائیں بٹن'); }
function exitGame() { if(confirm('کیا آپ باہر نکلنا چاہتے ہیں؟')) window.close(); }
function togglePause() { gamePaused = !gamePaused; document.getElementById('pauseBtn').innerText = gamePaused ? '▶️' : '⏸️'; }
function resetGame() { score = 0; lives = 3; wave = 1; enemySpeed = 2; spawnRate = 75; player.bullets = []; enemies = []; particles = []; gameOver = false; }
function restartGame() { document.getElementById('gameOver').style.display = 'none'; resetGame(); gameRunning = true; }
joystick.addEventListener('touchstart', e => { joyActive = true; updateJoystick(e.touches[0]); e.preventDefault(); });
joystick.addEventListener('touchmove', e => { if(joyActive) updateJoystick(e.touches[0]); e.preventDefault(); });
joystick.addEventListener('touchend', () => { joyActive = false; joyX = 0; joyY = 0; joystickKnob.style.transform = 'translate(-50%, -50%)'; });
function updateJoystick(touch) { const rect = joystick.getBoundingClientRect(); const cx = rect.left + rect.width/2, cy = rect.top + rect.height/2; const max = rect.width/2 - 20; let dx = touch.clientX - cx, dy = touch.clientY - cy; const dist = Math.hypot(dx, dy); if(dist > max) { dx *= max/dist; dy *= max/dist; } joyX = dx/max; joyY = dy/max; joystickKnob.style.transform = `translate(calc(-50% + ${dx}px), calc(-50% + ${dy}px))`; }
fireBtn.addEventListener('touchstart', () => fireHold = true); fireBtn.addEventListener('touchend', () => fireHold = false);
function drawPlayer() { if(player.invulnerable && frameCount % 8 < 4) return; ctx.fillStyle = '#3399ff'; ctx.beginPath(); ctx.moveTo(player.x + player.w/2, player.y); ctx.lineTo(player.x, player.y + player.h); ctx.lineTo(player.x + player.w, player.y + player.h); ctx.closePath(); ctx.fill(); ctx.fillStyle = '#88ccff'; ctx.fillRect(player.x + player.w/2 - 6, player.y + 10, 12, 30); }
function movePlayer() { if(!joyActive) return; player.x += joyX * player.speed; player.y += joyY * player.speed; player.x = Math.max(0, Math.min(canvas.width - player.w, player.x)); player.y = Math.max(canvas.height/2, Math.min(canvas.height - player.h, player.y)); if(player.invulnerable) { player.invulTimer--; if(player.invulTimer <= 0) player.invulnerable = false; } }
function handleFire() { if(fireHold && frameCount % 12 === 0) player.bullets.push({x: player.x + player.w/2 - 3, y: player.y - 10, w:6, h:18, speed:9}); }
function updateBullets() { ctx.fillStyle = '#ffdd44'; player.bullets.forEach((b,i) => { b.y -= b.speed; ctx.fillRect(b.x, b.y, b.w, b.h); if(b.y < 0) player.bullets.splice(i,1); }); }
function spawnEnemies() { if(frameCount % spawnRate === 0) enemies.push({x: Math.random()*(canvas.width-45), y:-45, w:45, h:45, speed: enemySpeed}); ctx.fillStyle = '#ff6622'; enemies.forEach((e,i) => { e.y += e.speed; ctx.fillRect(e.x, e.y, e.w, e.h); if(e.y > canvas.height) { enemies.splice(i,1); takeDamage(); } }); }
function createExplosion(x,y) { for(let i=0;i<20;i++) particles.push({x,y,vx:(Math.random()-0.5)*4,vy:(Math.random()-0.5)*4,size:Math.random()*5+2,color:['#ff8800','#ffcc22','#774422','#332211'][Math.floor(Math.random()*4)],life:35}); }
function updateParticles() { particles.forEach((p,i) => { p.x += p.vx; p.y += p.vy; p.life--; p.size *= 0.96; ctx.globalAlpha = p.life/35; ctx.fillStyle = p.color; ctx.fillRect(p.x, p.y, p.size, p.size); ctx.globalAlpha = 1; if(p.life <= 0) particles.splice(i,1); }); }
function takeDamage() { lives--; if(lives <= 0) { gameOver = true; document.getElementById('gameOver').style.display = 'flex'; } else { player.invulnerable = true; player.invulTimer = 90; } }
function checkCollisions() { player.bullets.forEach((b,bi) => { enemies.forEach((e,ei) => { if(b.x < e.x + e.w && b.x + b.w > e.x && b.y < e.y + e.h && b.y + b.h > e.y) { player.bullets.splice(bi,1); enemies.splice(ei,1); createExplosion(e.x+e.w/2, e.y+e.h/2); score += 15; if(score % 220 === 0) { wave++; enemySpeed += 0.3; spawnRate = Math.max(30, spawnRate - 5); } } }); }); if(!player.invulnerable) { enemies.forEach(e => { if(player.x < e.x + e.w && player.x + player.w > e.x && player.y < e.y + e.h && player.y + player.h > e.y) { takeDamage(); createExplosion(player.x+player.w/2, player.y+player.h/2); } }); } }
function drawUI() { document.getElementById('scoreText').textContent = score; document.getElementById('livesText').textContent = lives; document.getElementById('waveText').textContent = wave; }
function gameLoop() { if(!gameRunning || gamePaused) { requestAnimationFrame(gameLoop); return; } ctx.clearRect(0,0,canvas.width,canvas.height); drawPlayer(); movePlayer(); handleFire(); updateBullets(); spawnEnemies(); updateParticles(); checkCollisions(); drawUI(); frameCount++; requestAnimationFrame(gameLoop); }
gameLoop();
</script>
</body>
</html>
1
1
10KB
10KB
109.0ms
140.0ms
109.0ms