Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>J-10C vs Rafale Combat</title> | |
| <style> | |
| body { | |
| margin: 0; | |
| padding: 0; | |
| background: linear-gradient(135deg, #000428 0%, #004e92 100%); | |
| font-family: 'Courier New', monospace; | |
| color: white; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| min-height: 100vh; | |
| } | |
| .game-container { | |
| display: flex; | |
| gap: 20px; | |
| align-items: center; | |
| } | |
| .game-info { | |
| background: rgba(0, 0, 0, 0.8); | |
| padding: 20px; | |
| border-radius: 15px; | |
| border: 2px solid #00ffff; | |
| box-shadow: 0 0 20px rgba(0, 255, 255, 0.3); | |
| min-width: 200px; | |
| } | |
| #gameCanvas { | |
| background: radial-gradient(ellipse at center, #001122 0%, #000000 100%); | |
| border: 3px solid #00ffff; | |
| box-shadow: 0 0 30px #00ffff; | |
| border-radius: 10px; | |
| } | |
| .aircraft-count { | |
| color: #00ff00; | |
| font-size: 18px; | |
| font-weight: bold; | |
| margin: 10px 0; | |
| } | |
| .health-display { | |
| margin: 15px 0; | |
| padding: 10px; | |
| background: rgba(255, 255, 255, 0.1); | |
| border-radius: 8px; | |
| } | |
| .player-info { | |
| color: #00ff00; | |
| } | |
| .enemy-info { | |
| color: #ff4444; | |
| } | |
| .controls { | |
| margin-top: 20px; | |
| padding: 15px; | |
| background: rgba(255, 255, 255, 0.1); | |
| border-radius: 8px; | |
| font-size: 12px; | |
| } | |
| #gameOver { | |
| position: fixed; | |
| top: 50%; | |
| left: 50%; | |
| transform: translate(-50%, -50%); | |
| background: rgba(0, 0, 0, 0.95); | |
| padding: 40px; | |
| border-radius: 20px; | |
| border: 3px solid #00ffff; | |
| text-align: center; | |
| display: none; | |
| z-index: 1000; | |
| } | |
| button { | |
| background: linear-gradient(45deg, #00ffff, #0088ff); | |
| color: #000; | |
| border: none; | |
| padding: 12px 25px; | |
| border-radius: 8px; | |
| cursor: pointer; | |
| font-weight: bold; | |
| margin-top: 15px; | |
| transition: all 0.3s; | |
| } | |
| button:hover { | |
| transform: scale(1.05); | |
| box-shadow: 0 0 15px rgba(0, 255, 255, 0.5); | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="game-container"> | |
| <div class="game-info"> | |
| <div class="aircraft-count"> | |
| گرے ہوئے طیارے: <span id="destroyedCount">0</span> | |
| </div> | |
| <div class="health-display player-info"> | |
| <div><strong>🇵🇰 J-10C (پاکستان)</strong></div> | |
| <div>صحت: <span id="playerHealth">100</span>/100</div> | |
| </div> | |
| <div class="health-display enemy-info"> | |
| <div><strong>🇫🇷🇮🇳 Rafale (فرانس/بھارت)</strong></div> | |
| <div>صحت: <span id="enemyHealth">100</span>/100</div> | |
| </div> | |
| <div class="controls"> | |
| <div><strong>کنٹرولز:</strong></div> | |
| <div>↑↓← → تمام سمتیں</div> | |
| <div>SPACE: دستی فائر</div> | |
| <div>خودکار نشانہ: فعال</div> | |
| </div> | |
| </div> | |
| <canvas id="gameCanvas" width="900" height="700"></canvas> | |
| <div class="game-info"> | |
| <div style="text-align: center; font-size: 16px; color: #00ffff;"> | |
| <div><strong>🎯 جنگی میدان</strong></div> | |
| <div style="margin: 15px 0; font-size: 14px;"> | |
| پاکستانی J-10C برابر | |
| <br> | |
| فرانسیسی-بھارتی Rafale | |
| </div> | |
| <div style="color: #ffff00; font-size: 12px;"> | |
| * خودکار فائر ہر 333ms میں | |
| <br> | |
| * قریب ترین دشمن کو نشانہ | |
| <br> | |
| * مکمل 3D حرکت | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div id="gameOver"> | |
| <h2 id="gameResult"></h2> | |
| <p>تباہ شدہ طیارے: <span id="finalDestroyed"></span></p> | |
| <button onclick="restartGame()">دوبارہ جنگ شروع کریں</button> | |
| </div> | |
| <script> | |
| const canvas = document.getElementById('gameCanvas'); | |
| const ctx = canvas.getContext('2d'); | |
| // Game state | |
| let gameRunning = true; | |
| let destroyedAircraft = 0; | |
| let lastAutoFire = 0; | |
| const autoFireRate = 333; // 3 fires per second | |
| // Player (J-10C with Pakistani flag) | |
| const player = { | |
| x: canvas.width / 2, | |
| y: canvas.height - 100, | |
| width: 80, | |
| height: 50, | |
| speed: 6, | |
| health: 100, | |
| maxHealth: 100, | |
| animOffset: 0 | |
| }; | |
| // Enemy (Rafale with French-Indian flags) | |
| const enemy = { | |
| x: canvas.width / 2, | |
| y: 80, | |
| width: 80, | |
| height: 50, | |
| speed: 3, | |
| health: 100, | |
| maxHealth: 100, | |
| direction: 1, | |
| verticalDirection: 1, | |
| animOffset: 0 | |
| }; | |
| // Bullets and particles | |
| let playerBullets = []; | |
| let enemyBullets = []; | |
| let explosions = []; | |
| // Stars for background | |
| let stars = []; | |
| for (let i = 0; i < 150; i++) { | |
| stars.push({ | |
| x: Math.random() * canvas.width, | |
| y: Math.random() * canvas.height, | |
| size: Math.random() * 3, | |
| twinkle: Math.random() * 100 | |
| }); | |
| } | |
| // Input handling | |
| const keys = {}; | |
| document.addEventListener('keydown', (e) => { | |
| keys[e.code] = true; | |
| }); | |
| document.addEventListener('keyup', (e) => { | |
| keys[e.code] = false; | |
| }); | |
| // Draw functions | |
| function drawStars() { | |
| stars.forEach(star => { | |
| star.twinkle += 2; | |
| const alpha = (Math.sin(star.twinkle * 0.05) + 1) * 0.5; | |
| ctx.fillStyle = `rgba(255, 255, 255, ${alpha})`; | |
| ctx.beginPath(); | |
| ctx.arc(star.x, star.y, star.size, 0, Math.PI * 2); | |
| ctx.fill(); | |
| }); | |
| } | |
| function drawPakistaniFlag(x, y, size) { | |
| // Pakistani flag on J-10C | |
| const flagWidth = size * 0.8; | |
| const flagHeight = size * 0.5; | |
| // Green background | |
| ctx.fillStyle = '#01411C'; | |
| ctx.fillRect(x - flagWidth/2, y - flagHeight/2, flagWidth, flagHeight); | |
| // White stripe | |
| ctx.fillStyle = 'white'; | |
| ctx.fillRect(x - flagWidth/2, y - flagHeight/2, flagWidth * 0.25, flagHeight); | |
| // Crescent and star (simplified) | |
| ctx.fillStyle = 'white'; | |
| ctx.beginPath(); | |
| ctx.arc(x + flagWidth * 0.1, y, size * 0.15, 0, Math.PI * 2); | |
| ctx.fill(); | |
| // Star | |
| ctx.beginPath(); | |
| ctx.arc(x + flagWidth * 0.25, y - size * 0.05, size * 0.1, 0, Math.PI * 2); | |
| ctx.fill(); | |
| } | |
| function drawFrenchFlag(x, y, size) { | |
| const flagWidth = size * 0.6; | |
| const flagHeight = size * 0.4; | |
| // Blue | |
| ctx.fillStyle = '#002395'; | |
| ctx.fillRect(x - flagWidth/2, y - flagHeight/2, flagWidth/3, flagHeight); | |
| // White | |
| ctx.fillStyle = 'white'; | |
| ctx.fillRect(x - flagWidth/6, y - flagHeight/2, flagWidth/3, flagHeight); | |
| // Red | |
| ctx.fillStyle = '#ED2939'; | |
| ctx.fillRect(x + flagWidth/6, y - flagHeight/2, flagWidth/3, flagHeight); | |
| } | |
| function drawIndianFlag(x, y, size) { | |
| const flagWidth = size * 0.6; | |
| const flagHeight = size * 0.4; | |
| // Orange | |
| ctx.fillStyle = '#FF9933'; | |
| ctx.fillRect(x - flagWidth/2, y - flagHeight/2, flagWidth, flagHeight/3); | |
| // White | |
| ctx.fillStyle = 'white'; | |
| ctx.fillRect(x - flagWidth/2, y - flagHeight/6, flagWidth, flagHeight/3); | |
| // Green | |
| ctx.fillStyle = '#138808'; | |
| ctx.fillRect(x - flagWidth/2, y + flagHeight/6, flagWidth, flagHeight/3); | |
| // Chakra (simplified) | |
| ctx.strokeStyle = '#000080'; | |
| ctx.lineWidth = 2; | |
| ctx.beginPath(); | |
| ctx.arc(x, y, size * 0.1, 0, Math.PI * 2); | |
| ctx.stroke(); | |
| } | |
| function drawJ10C(x, y, animOffset) { | |
| ctx.save(); | |
| // Animation bobbing | |
| const bobY = y + Math.sin(animOffset * 0.1) * 2; | |
| // Main fuselage (Pakistani J-10C) | |
| ctx.fillStyle = '#2C5F2D'; | |
| ctx.beginPath(); | |
| ctx.ellipse(x, bobY, 40, 15, 0, 0, Math.PI * 2); | |
| ctx.fill(); | |
| // Nose cone | |
| ctx.fillStyle = '#1A4B1C'; | |
| ctx.beginPath(); | |
| ctx.ellipse(x, bobY - 20, 12, 8, 0, 0, Math.PI * 2); | |
| ctx.fill(); | |
| // Wings (delta wing design) | |
| ctx.fillStyle = '#397D3C'; | |
| ctx.beginPath(); | |
| ctx.moveTo(x - 45, bobY + 10); | |
| ctx.lineTo(x - 15, bobY - 5); | |
| ctx.lineTo(x + 15, bobY - 5); | |
| ctx.lineTo(x + 45, bobY + 10); | |
| ctx.lineTo(x + 25, bobY + 20); | |
| ctx.lineTo(x - 25, bobY + 20); | |
| ctx.closePath(); | |
| ctx.fill(); | |
| // Canard wings | |
| ctx.fillStyle = '#2C5F2D'; | |
| ctx.beginPath(); | |
| ctx.ellipse(x, bobY - 10, 25, 5, 0, 0, Math.PI * 2); | |
| ctx.fill(); | |
| // Cockpit | |
| ctx.fillStyle = '#4A90E2'; | |
| ctx.beginPath(); | |
| ctx.ellipse(x, bobY - 8, 8, 6, 0, 0, Math.PI * 2); | |
| ctx.fill(); | |
| // Engine exhaust | |
| ctx.fillStyle = '#FF6B35'; | |
| ctx.beginPath(); | |
| ctx.ellipse(x, bobY + 25, 10, 6, 0, 0, Math.PI * 2); | |
| ctx.fill(); | |
| // Afterburner glow | |
| if (Math.random() > 0.7) { | |
| ctx.fillStyle = '#FFD700'; | |
| ctx.beginPath(); | |
| ctx.ellipse(x, bobY + 30, 15, 4, 0, 0, Math.PI * 2); | |
| ctx.fill(); | |
| } | |
| // Pakistani flag | |
| drawPakistaniFlag(x - 30, bobY - 5, 20); | |
| ctx.restore(); | |
| } | |
| function drawRafale(x, y, animOffset) { | |
| ctx.save(); | |
| // Animation movement | |
| const bobY = y + Math.sin(animOffset * 0.08) * 3; | |
| const bobX = x + Math.cos(animOffset * 0.06) * 1; | |
| // Main fuselage (Rafale) | |
| ctx.fillStyle = '#4A4A4A'; | |
| ctx.beginPath(); | |
| ctx.ellipse(bobX, bobY, 38, 14, 0, 0, Math.PI * 2); | |
| ctx.fill(); | |
| // Nose cone | |
| ctx.fillStyle = '#333333'; | |
| ctx.beginPath(); | |
| ctx.ellipse(bobX, bobY - 18, 10, 7, 0, 0, Math.PI * 2); | |
| ctx.fill(); | |
| // Delta wings | |
| ctx.fillStyle = '#5C5C5C'; | |
| ctx.beginPath(); | |
| ctx.moveTo(bobX - 42, bobY + 8); | |
| ctx.lineTo(bobX - 18, bobY - 8); | |
| ctx.lineTo(bobX + 18, bobY - 8); | |
| ctx.lineTo(bobX + 42, bobY + 8); | |
| ctx.lineTo(bobX + 22, bobY + 18); | |
| ctx.lineTo(bobX - 22, bobY + 18); | |
| ctx.closePath(); | |
| ctx.fill(); | |
| // Canard wings | |
| ctx.fillStyle = '#4A4A4A'; | |
| ctx.beginPath(); | |
| ctx.ellipse(bobX, bobY - 12, 22, 4, 0, 0, Math.PI * 2); | |
| ctx.fill(); | |
| // Cockpit | |
| ctx.fillStyle = '#87CEEB'; | |
| ctx.beginPath(); | |
| ctx.ellipse(bobX, bobY - 6, 7, 5, 0, 0, Math.PI * 2); | |
| ctx.fill(); | |
| // Twin engines | |
| ctx.fillStyle = '#FF4500'; | |
| ctx.beginPath(); | |
| ctx.ellipse(bobX - 8, bobY + 22, 6, 4, 0, 0, Math.PI * 2); | |
| ctx.fill(); | |
| ctx.beginPath(); | |
| ctx.ellipse(bobX + 8, bobY + 22, 6, 4, 0, 0, Math.PI * 2); | |
| ctx.fill(); | |
| // Afterburner effects | |
| if (Math.random() > 0.6) { | |
| ctx.fillStyle = '#FF69B4'; | |
| ctx.beginPath(); | |
| ctx.ellipse(bobX - 8, bobY + 28, 8, 3, 0, 0, Math.PI * 2); | |
| ctx.fill(); | |
| ctx.beginPath(); | |
| ctx.ellipse(bobX + 8, bobY + 28, 8, 3, 0, 0, Math.PI * 2); | |
| ctx.fill(); | |
| } | |
| // French flag | |
| drawFrenchFlag(bobX - 25, bobY - 3, 15); | |
| // Indian flag | |
| drawIndianFlag(bobX + 25, bobY - 3, 15); | |
| ctx.restore(); | |
| } | |
| function drawBullet(x, y, color, size = 4) { | |
| ctx.save(); | |
| ctx.shadowColor = color; | |
| ctx.shadowBlur = 10; | |
| ctx.fillStyle = color; | |
| ctx.beginPath(); | |
| ctx.arc(x, y, size, 0, Math.PI * 2); | |
| ctx.fill(); | |
| // Bullet trail | |
| ctx.fillStyle = color + '50'; | |
| ctx.beginPath(); | |
| ctx.arc(x, y + 10, size * 0.5, 0, Math.PI * 2); | |
| ctx.fill(); | |
| ctx.restore(); | |
| } | |
| function drawExplosion(explosion) { | |
| ctx.save(); | |
| ctx.translate(explosion.x, explosion.y); | |
| for (let i = 0; i < explosion.particles.length; i++) { | |
| const p = explosion.particles[i]; | |
| ctx.fillStyle = p.color; | |
| ctx.globalAlpha = p.life; | |
| ctx.beginPath(); | |
| ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2); | |
| ctx.fill(); | |
| } | |
| ctx.restore(); | |
| } | |
| function createExplosion(x, y) { | |
| const explosion = { | |
| x: x, | |
| y: y, | |
| particles: [], | |
| life: 60 | |
| }; | |
| for (let i = 0; i < 20; i++) { | |
| explosion.particles.push({ | |
| x: 0, | |
| y: 0, | |
| vx: (Math.random() - 0.5) * 10, | |
| vy: (Math.random() - 0.5) * 10, | |
| size: Math.random() * 5 + 2, | |
| color: ['#FF4500', '#FF6B35', '#FFD700', '#FF0000'][Math.floor(Math.random() * 4)], | |
| life: 1 | |
| }); | |
| } | |
| explosions.push(explosion); | |
| } | |
| // Game logic | |
| function updatePlayer() { | |
| if (keys['ArrowLeft'] && player.x > 40) { | |
| player.x -= player.speed; | |
| } | |
| if (keys['ArrowRight'] && player.x < canvas.width - 40) { | |
| player.x += player.speed; | |
| } | |
| if (keys['ArrowUp'] && player.y > 40) { | |
| player.y -= player.speed; | |
| } | |
| if (keys['ArrowDown'] && player.y < canvas.height - 40) { | |
| player.y += player.speed; | |
| } | |
| player.animOffset++; | |
| // Manual fire | |
| if (keys['Space']) { | |
| keys['Space'] = false; | |
| playerBullets.push({ | |
| x: player.x, | |
| y: player.y - 25, | |
| speed: 10 | |
| }); | |
| } | |
| } | |
| function updateEnemy() { | |
| // Advanced enemy movement with full animation | |
| enemy.x += enemy.speed * enemy.direction; | |
| enemy.y += enemy.speed * 0.5 * enemy.verticalDirection; | |
| if (enemy.x <= 40 || enemy.x >= canvas.width - 40) { | |
| enemy.direction *= -1; | |
| } | |
| if (enemy.y <= 40 || enemy.y >= canvas.height / 2) { | |
| enemy.verticalDirection *= -1; | |
| } | |
| enemy.animOffset++; | |
| // Enemy shooting | |
| if (Math.random() < 0.025) { | |
| enemyBullets.push({ | |
| x: enemy.x, | |
| y: enemy.y + 25, | |
| speed: 6 | |
| }); | |
| } | |
| } | |
| function updateAutoFire() { | |
| const now = Date.now(); | |
| if (now - lastAutoFire > autoFireRate) { | |
| const distance = Math.sqrt(Math.pow(enemy.x - player.x, 2) + Math.pow(enemy.y - player.y, 2)); | |
| if (distance < 500) { | |
| playerBullets.push({ | |
| x: player.x, | |
| y: player.y - 25, | |
| speed: 10 | |
| }); | |
| lastAutoFire = now; | |
| } | |
| } | |
| } | |
| function updateBullets() { | |
| // Update player bullets | |
| playerBullets = playerBullets.filter(bullet => { | |
| bullet.y -= bullet.speed; | |
| // Check collision with enemy | |
| if (bullet.x > enemy.x - 40 && bullet.x < enemy.x + 40 && | |
| bullet.y > enemy.y - 25 && bullet.y < enemy.y + 25) { | |
| enemy.health -= 12; | |
| createExplosion(bullet.x, bullet.y); | |
| return false; | |
| } | |
| return bullet.y > 0; | |
| }); | |
| // Update enemy bullets | |
| enemyBullets = enemyBullets.filter(bullet => { | |
| bullet.y += bullet.speed; | |
| // Check collision with player | |
| if (bullet.x > player.x - 40 && bullet.x < player.x + 40 && | |
| bullet.y > player.y - 25 && bullet.y < player.y + 25) { | |
| player.health -= 10; | |
| createExplosion(bullet.x, bullet.y); | |
| return false; | |
| } | |
| return bullet.y < canvas.height; | |
| }); | |
| } | |
| function updateExplosions() { | |
| explosions = explosions.filter(explosion => { | |
| explosion.life--; | |
| explosion.particles.forEach(p => { | |
| p.x += p.vx; | |
| p.y += p.vy; | |
| p.life -= 0.02; | |
| p.vx *= 0.98; | |
| p.vy *= 0.98; | |
| }); | |
| return explosion.life > 0; | |
| }); | |
| } | |
| function checkGameOver() { | |
| if (player.health <= 0) { | |
| gameRunning = false; | |
| document.getElementById('gameResult').textContent = 'شکست! Rafale نے جیت لی'; | |
| document.getElementById('finalDestroyed').textContent = destroyedAircraft; | |
| document.getElementById('gameOver').style.display = 'block'; | |
| } else if (enemy.health <= 0) { | |
| // Enemy destroyed - reset for continuous play | |
| destroyedAircraft++; | |
| createExplosion(enemy.x, enemy.y); | |
| enemy.health = enemy.maxHealth; | |
| enemy.x = Math.random() * (canvas.width - 80) + 40; | |
| enemy.y = Math.random() * (canvas.height / 3) + 40; | |
| enemy.speed += 0.5; // Increase difficulty | |
| } | |
| } | |
| function updateUI() { | |
| document.getElementById('playerHealth').textContent = Math.max(0, player.health); | |
| document.getElementById('enemyHealth').textContent = Math.max(0, enemy.health); | |
| document.getElementById('destroyedCount').textContent = destroyedAircraft; | |
| } | |
| function draw() { | |
| // Clear canvas | |
| ctx.clearRect(0, 0, canvas.width, canvas.height); | |
| // Draw background | |
| drawStars(); | |
| // Draw fighters with full animation | |
| drawJ10C(player.x, player.y, player.animOffset); | |
| drawRafale(enemy.x, enemy.y, enemy.animOffset); | |
| // Draw bullets | |
| playerBullets.forEach(bullet => drawBullet(bullet.x, bullet.y, '#00FFFF', 5)); | |
| enemyBullets.forEach(bullet => drawBullet(bullet.x, bullet.y, '#FF4500', 4)); | |
| // Draw explosions | |
| explosions.forEach(drawExplosion); | |
| } | |
| function gameLoop() { | |
| if (gameRunning) { | |
| updatePlayer(); | |
| updateEnemy(); | |
| updateAutoFire(); | |
| updateBullets(); | |
| updateExplosions(); | |
| checkGameOver(); | |
| updateUI(); | |
| draw(); | |
| } | |
| requestAnimationFrame(gameLoop); | |
| } | |
| function restartGame() { | |
| gameRunning = true; | |
| destroyedAircraft = 0; | |
| player.health = player.maxHealth; | |
| enemy.health = enemy.maxHealth; | |
| player.x = canvas.width / 2; | |
| player.y = canvas.height - 100; | |
| enemy.x = canvas.width / 2; | |
| enemy.y = 80; | |
| enemy.speed = 3; | |
| playerBullets = []; | |
| enemyBullets = []; | |
| explosions = []; | |
| document.getElementById('gameOver').style.display = 'none'; | |
| } | |
| // Start game | |
| gameLoop(); | |
| </script> | |
| </body> | |
| </html> |