حرب الدول اللانهائية - CountryWar.io
by BlazingWizard12503 lines20.1 KB
<!DOCTYPE html>
<html lang="ar">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>حرب الدول اللانهائية - CountryWar.io</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none;
-webkit-tap-highlight-color: transparent;
}
body {
background: #0f172a;
overflow: hidden;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
touch-action: none;
}
canvas {
display: block;
width: 100vw;
height: 100vh;
cursor: crosshair;
}
#ui {
position: fixed;
top: 15px;
left: 15px;
background: rgba(0,0,0,0.7);
backdrop-filter: blur(4px);
padding: 8px 18px;
border-radius: 30px;
color: #facc15;
font-weight: bold;
font-size: 1.2rem;
font-family: monospace;
pointer-events: none;
z-index: 20;
border-left: 4px solid #facc15;
box-shadow: 0 2px 10px rgba(0,0,0,0.3);
}
#leaderboard {
position: fixed;
top: 15px;
right: 15px;
background: rgba(0,0,0,0.7);
backdrop-filter: blur(4px);
padding: 8px 15px;
border-radius: 16px;
color: #e2e8f0;
font-size: 0.8rem;
font-weight: bold;
text-align: right;
direction: rtl;
pointer-events: none;
z-index: 20;
font-family: monospace;
min-width: 150px;
border-right: 3px solid #facc15;
}
#leaderboard strong {
color: #ffd966;
display: block;
margin-bottom: 4px;
}
#restartBtn {
position: fixed;
bottom: 20px;
left: 20px;
background: #dc2626;
color: white;
border: none;
padding: 8px 18px;
border-radius: 40px;
font-weight: bold;
font-size: 0.9rem;
z-index: 30;
cursor: pointer;
box-shadow: 0 2px 8px black;
font-family: monospace;
transition: 0.2s;
pointer-events: auto;
}
#restartBtn:active {
transform: scale(0.96);
background: #b91c1c;
}
.controls-hint {
position: fixed;
bottom: 20px;
right: 20px;
background: rgba(0,0,0,0.5);
color: #ccc;
font-size: 11px;
padding: 5px 10px;
border-radius: 20px;
font-family: monospace;
pointer-events: none;
z-index: 20;
}
@media (max-width: 600px) {
#ui { font-size: 1rem; padding: 5px 12px; }
#leaderboard { font-size: 0.7rem; min-width: 120px; }
#restartBtn { padding: 6px 14px; font-size: 0.8rem; }
}
</style>
</head>
<body>
<div id="ui">🇪🇬 حجم دولتك: <span id="mySize">25</span> طن</div>
<div id="leaderboard">
<strong>🏆 ترتيب القوى العظمى</strong>
<span id="p1">-</span><br>
<span id="p2">-</span><br>
<span id="p3">-</span>
</div>
<button id="restartBtn">🔄 إعلان حرب جديدة</button>
<div class="controls-hint">👆 اسحب الإصبع / الفأرة لتحريك دولتك</div>
<canvas id="gameCanvas"></canvas>
<script>
(function(){
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
// عالم كبير 3000x3000
const WORLD_W = 3000;
const WORLD_H = 3000;
let gameOver = false;
// الكاميرا
let camera = { x: 0, y: 0 };
// اللاعب (مصر)
const myCountry = {
x: WORLD_W / 2,
y: WORLD_H / 2,
radius: 25,
color: '#05c46b',
name: '🇪🇬 مصر',
speedBase: 4.2
};
// قوائم اللعبة
let botCountries = [];
let foods = [];
// أسماء وألوان للبوتات
const countryNames = ['🇺🇸 أمريكا', '🇨🇳 الصين', '🇷🇺 روسيا', '🇧🇷 البرازيل', '🇩🇪 ألمانيا', '🇸🇦 السعودية', '🇯🇵 اليابان', '🇫🇷 فرنسا', '🇬🇧 بريطانيا', '🇮🇹 إيطاليا', '🇨🇦 كندا', '🇦🇺 أستراليا', '🇰🇷 كوريا', '🇮🇳 الهند'];
const botColors = ['#ef5777', '#575fcf', '#4bcffa', '#34e7e4', '#ffdd59', '#ff5e57', '#ffa801', '#ffd32a', '#0be881', '#a55eea', '#fd9644'];
// تحكم باللمس والفأرة
let targetX = myCountry.x;
let targetY = myCountry.y;
let isPointerActive = false;
// وظيفة لتوليد طعام جديد
function spawnFood() {
foods.push({
x: Math.random() * WORLD_W,
y: Math.random() * WORLD_H,
radius: 3 + Math.random() * 5,
color: botColors[Math.floor(Math.random() * botColors.length)]
});
}
// توليد بوت جديد
function spawnBot() {
botCountries.push({
x: Math.random() * WORLD_W,
y: Math.random() * WORLD_H,
radius: 12 + Math.random() * 38,
color: botColors[Math.floor(Math.random() * botColors.length)],
name: countryNames[Math.floor(Math.random() * countryNames.length)] + " 🤖",
vx: (Math.random() - 0.5) * 2.8,
vy: (Math.random() - 0.5) * 2.8
});
}
// تهيئة العالم
function initWorld() {
foods = [];
for (let i = 0; i < 400; i++) spawnFood();
botCountries = [];
for (let i = 0; i < 24; i++) spawnBot();
}
// إعادة التشغيل الكامل
function restartGame() {
gameOver = false;
myCountry.radius = 25;
myCountry.x = WORLD_W / 2;
myCountry.y = WORLD_H / 2;
targetX = myCountry.x;
targetY = myCountry.y;
isPointerActive = false;
document.getElementById('mySize').innerText = Math.floor(myCountry.radius);
initWorld();
}
// تحديث ترتيب المتصدرين
function updateLeaderboard() {
let all = [...botCountries, myCountry];
all.sort((a,b) => b.radius - a.radius);
let p1 = all[0];
let p2 = all[1];
let p3 = all[2];
document.getElementById('p1').innerHTML = `🥇 ${p1.name} (${Math.floor(p1.radius)})`;
document.getElementById('p2').innerHTML = p2 ? `🥈 ${p2.name} (${Math.floor(p2.radius)})` : "---";
document.getElementById('p3').innerHTML = p3 ? `🥉 ${p3.name} (${Math.floor(p3.radius)})` : "---";
}
// أحداث التحكم (لمس + فأرة)
function handlePointerStart(e) {
e.preventDefault();
isPointerActive = true;
const rect = canvas.getBoundingClientRect();
const scaleX = canvas.width / rect.width;
const scaleY = canvas.height / rect.height;
let clientX, clientY;
if (e.touches) {
clientX = e.touches[0].clientX;
clientY = e.touches[0].clientY;
} else {
clientX = e.clientX;
clientY = e.clientY;
}
const canvasX = (clientX - rect.left) * scaleX;
const canvasY = (clientY - rect.top) * scaleY;
targetX = canvasX + camera.x;
targetY = canvasY + camera.y;
}
function handlePointerMove(e) {
if (!isPointerActive && !gameOver) return;
e.preventDefault();
const rect = canvas.getBoundingClientRect();
const scaleX = canvas.width / rect.width;
const scaleY = canvas.height / rect.height;
let clientX, clientY;
if (e.touches) {
clientX = e.touches[0].clientX;
clientY = e.touches[0].clientY;
} else {
clientX = e.clientX;
clientY = e.clientY;
}
const canvasX = (clientX - rect.left) * scaleX;
const canvasY = (clientY - rect.top) * scaleY;
targetX = canvasX + camera.x;
targetY = canvasY + camera.y;
}
function handlePointerEnd(e) {
isPointerActive = false;
e.preventDefault();
}
canvas.addEventListener('touchstart', handlePointerStart, {passive: false});
canvas.addEventListener('touchmove', handlePointerMove, {passive: false});
canvas.addEventListener('touchend', handlePointerEnd);
canvas.addEventListener('mousedown', handlePointerStart);
window.addEventListener('mousemove', (e) => {
if (isPointerActive && !gameOver) handlePointerMove(e);
});
window.addEventListener('mouseup', handlePointerEnd);
// زر إعادة التشغيل
document.getElementById('restartBtn').addEventListener('click', () => {
restartGame();
});
// ========== منطق اللعبة الأساسي ==========
function update() {
if (gameOver) return;
// 1. تحريك اللاعب باتجاه المؤشر
if (isPointerActive) {
let dx = targetX - myCountry.x;
let dy = targetY - myCountry.y;
let dist = Math.hypot(dx, dy);
if (dist > 1) {
let speed = Math.max(1.8, myCountry.speedBase - (myCountry.radius * 0.012));
let move = Math.min(speed, dist);
myCountry.x += (dx / dist) * move;
myCountry.y += (dy / dist) * move;
}
}
// حدود العالم للاعب
myCountry.x = Math.min(Math.max(myCountry.x, myCountry.radius), WORLD_W - myCountry.radius);
myCountry.y = Math.min(Math.max(myCountry.y, myCountry.radius), WORLD_H - myCountry.radius);
// تحديث الكاميرا
camera.x = myCountry.x - canvas.width / 2;
camera.y = myCountry.y - canvas.height / 2;
camera.x = Math.min(Math.max(camera.x, 0), WORLD_W - canvas.width);
camera.y = Math.min(Math.max(camera.y, 0), WORLD_H - canvas.height);
// 2. تحديث البوتات
for (let i = 0; i < botCountries.length; i++) {
const bot = botCountries[i];
// حركة عشوائية ذكية
if (Math.random() < 0.02) {
bot.vx += (Math.random() - 0.5) * 0.8;
bot.vy += (Math.random() - 0.5) * 0.8;
let maxSpeed = 2.5;
bot.vx = Math.min(Math.max(bot.vx, -maxSpeed), maxSpeed);
bot.vy = Math.min(Math.max(bot.vy, -maxSpeed), maxSpeed);
}
bot.x += bot.vx;
bot.y += bot.vy;
bot.x = Math.min(Math.max(bot.x, bot.radius), WORLD_W - bot.radius);
bot.y = Math.min(Math.max(bot.y, bot.radius), WORLD_H - bot.radius);
// أكل الطعام
for (let j = foods.length-1; j >= 0; j--) {
const f = foods[j];
if (Math.hypot(f.x - bot.x, f.y - bot.y) < bot.radius) {
bot.radius += 0.25;
foods.splice(j,1);
spawnFood();
}
}
// التفاعل مع اللاعب
const distToPlayer = Math.hypot(myCountry.x - bot.x, myCountry.y - bot.y);
if (distToPlayer < myCountry.radius + bot.radius) {
if (myCountry.radius > bot.radius * 1.08) {
// اللاعب يأكل البوت
myCountry.radius += bot.radius * 0.25;
document.getElementById('mySize').innerText = Math.floor(myCountry.radius);
botCountries.splice(i,1);
spawnBot();
i--;
continue;
} else if (bot.radius > myCountry.radius * 1.08) {
gameOver = true;
return;
} else {
// تصادم عادي بدون افتراس - ارتداد بسيط
let angle = Math.atan2(myCountry.y - bot.y, myCountry.x - bot.x);
let overlap = (myCountry.radius + bot.radius) - distToPlayer;
let moveX = Math.cos(angle) * overlap * 0.5;
let moveY = Math.sin(angle) * overlap * 0.5;
myCountry.x += moveX;
myCountry.y += moveY;
bot.x -= moveX;
bot.y -= moveY;
}
}
}
// تفاعل البوتات مع بعضها
for (let i = 0; i < botCountries.length; i++) {
for (let j = i+1; j < botCountries.length; j++) {
const a = botCountries[i];
const b = botCountries[j];
const dist = Math.hypot(a.x - b.x, a.y - b.y);
if (dist < a.radius + b.radius) {
if (a.radius > b.radius * 1.1) {
a.radius += b.radius * 0.2;
botCountries.splice(j,1);
spawnBot();
j--;
} else if (b.radius > a.radius * 1.1) {
b.radius += a.radius * 0.2;
botCountries.splice(i,1);
spawnBot();
i--;
break;
} else {
let angle = Math.atan2(b.y - a.y, b.x - a.x);
let overlap = (a.radius + b.radius) - dist;
let moveX = Math.cos(angle) * overlap * 0.5;
let moveY = Math.sin(angle) * overlap * 0.5;
a.x -= moveX;
a.y -= moveY;
b.x += moveX;
b.y += moveY;
}
}
}
}
// أكل الطعام من اللاعب
for (let i = foods.length-1; i >= 0; i--) {
const food = foods[i];
if (Math.hypot(food.x - myCountry.x, food.y - myCountry.y) < myCountry.radius) {
myCountry.radius += 0.35;
document.getElementById('mySize').innerText = Math.floor(myCountry.radius);
foods.splice(i,1);
spawnFood();
}
}
updateLeaderboard();
}
// رسم كل شيء
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.translate(-camera.x, -camera.y);
// رسم شبكة خلفية
ctx.strokeStyle = '#2d3e50';
ctx.lineWidth = 0.8;
for (let x = 0; x <= WORLD_W; x += 120) {
ctx.beginPath();
ctx.moveTo(x, 0);
ctx.lineTo(x, WORLD_H);
ctx.stroke();
}
for (let y = 0; y <= WORLD_H; y += 120) {
ctx.beginPath();
ctx.moveTo(0, y);
ctx.lineTo(WORLD_W, y);
ctx.stroke();
}
// الطعام
for (const f of foods) {
ctx.fillStyle = f.color;
ctx.shadowBlur = 0;
ctx.beginPath();
ctx.arc(f.x, f.y, f.radius, 0, Math.PI*2);
ctx.fill();
}
// البوتات
for (const bot of botCountries) {
ctx.fillStyle = bot.color;
ctx.beginPath();
ctx.arc(bot.x, bot.y, bot.radius, 0, Math.PI*2);
ctx.fill();
ctx.fillStyle = '#f8fafc';
ctx.font = `bold ${Math.max(11, Math.floor(bot.radius/2.5))}px "Segoe UI", Arial`;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.shadowBlur = 2;
ctx.fillText(bot.name, bot.x, bot.y);
}
// رسم اللاعب
ctx.shadowBlur = 8;
ctx.shadowColor = "#00ffaa";
ctx.fillStyle = myCountry.color;
ctx.beginPath();
ctx.arc(myCountry.x, myCountry.y, myCountry.radius, 0, Math.PI*2);
ctx.fill();
ctx.strokeStyle = 'white';
ctx.lineWidth = 3;
ctx.stroke();
ctx.fillStyle = 'white';
ctx.font = `bold ${Math.max(14, Math.floor(myCountry.radius/2.2))}px "Segoe UI", Arial`;
ctx.fillText(myCountry.name, myCountry.x, myCountry.y);
ctx.shadowBlur = 0;
ctx.restore();
// شاشة game over
if (gameOver) {
ctx.fillStyle = 'rgba(0,0,0,0.85)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#ef4444';
ctx.font = 'bold 28px "Segoe UI"';
ctx.textAlign = 'center';
ctx.fillText('💀 تم احتلال دولتك 💀', canvas.width/2, canvas.height/2 - 30);
ctx.fillStyle = '#facc15';
ctx.font = '20px monospace';
ctx.fillText('اضغط زر "إعلان حرب جديدة" بالأسفل', canvas.width/2, canvas.height/2 + 30);
}
}
// بدء اللعبة
initWorld();
updateLeaderboard();
function gameLoop() {
update();
draw();
requestAnimationFrame(gameLoop);
}
gameLoop();
// التأكد من أن الكاميرا لا تخرج عن الحدود بعد كل إطار
})();
</script>
</body>
</html>Game Source: حرب الدول اللانهائية - CountryWar.io
Creator: BlazingWizard12
Libraries: none
Complexity: complex (503 lines, 20.1 KB)
The full source code is displayed above on this page.
Remix Instructions
To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: countrywar-io-blazingwizard12-mq83crj5" to link back to the original. Then publish at arcadelab.ai/publish.