!doctype HTML
!doctype HTML
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D Battle Royale Arena</title>
<script
src="[Link]
<link href="[Link]
family=Orbitron:wght@400;700;900&family=Rajdhani:wght@300;400;500;600;700&display=s
wap" rel="stylesheet">
<style>
:root {
--primary-blue: #0066ff;
--primary-orange: #ff6600;
--danger-red: #ff0040;
--success-green: #00ff66;
--warning-yellow: #ffcc00;
--dark-bg: #0a0a0a;
--card-bg: rgba(20, 20, 30, 0.9);
--glass-border: rgba(255, 255, 255, 0.1);
--text-primary: #ffffff;
--text-secondary: #cccccc;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Rajdhani', sans-serif;
background: var(--dark-bg);
color: var(--text-primary);
overflow: hidden;
height: 100vh;
}
#gameCanvas {
display: block;
width: 100%;
height: 100%;
cursor: none;
}
/* HUD Overlay */
.hud-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 1000;
}
.top-hud {
position: absolute;
top: 20px;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 30px;
align-items: center;
background: var(--card-bg);
backdrop-filter: blur(20px);
padding: 15px 30px;
border-radius: 15px;
border: 1px solid var(--glass-border);
}
.health-shield {
display: flex;
gap: 20px;
align-items: center;
}
.stat-bar {
display: flex;
align-items: center;
gap: 8px;
}
.bar {
width: 120px;
height: 8px;
background: rgba(255, 255, 255, 0.2);
border-radius: 4px;
overflow: hidden;
}
.bar-fill {
height: 100%;
transition: width 0.3s ease;
}
.health-fill {
background: linear-gradient(90deg, var(--danger-red), var(--success-
green));
}
.shield-fill {
background: linear-gradient(90deg, var(--primary-blue), var(--primary-
orange));
}
.players-alive {
font-family: 'Orbitron', monospace;
font-weight: 700;
font-size: 1.2rem;
color: var(--primary-orange);
}
.storm-timer {
font-family: 'Orbitron', monospace;
font-weight: 700;
font-size: 1.1rem;
color: var(--warning-yellow);
}
/* Crosshair */
.crosshair {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 20px;
height: 20px;
pointer-events: none;
}
.crosshair::before,
.crosshair::after {
content: '';
position: absolute;
background: var(--text-primary);
box-shadow: 0 0 5px rgba(255, 255, 255, 0.5);
}
.crosshair::before {
width: 2px;
height: 20px;
left: 50%;
transform: translateX(-50%);
}
.crosshair::after {
width: 20px;
height: 2px;
top: 50%;
transform: translateY(-50%);
}
/* Weapon HUD */
.weapon-hud {
position: absolute;
bottom: 30px;
right: 30px;
background: var(--card-bg);
backdrop-filter: blur(20px);
padding: 20px;
border-radius: 15px;
border: 1px solid var(--glass-border);
min-width: 200px;
}
.weapon-info {
text-align: center;
margin-bottom: 15px;
}
.weapon-name {
font-family: 'Orbitron', monospace;
font-size: 1.2rem;
font-weight: 700;
color: var(--primary-orange);
margin-bottom: 5px;
}
.ammo-count {
font-size: 1.5rem;
font-weight: 700;
color: var(--text-primary);
}
.weapon-slots {
display: flex;
gap: 10px;
justify-content: center;
}
.weapon-slot {
width: 50px;
height: 50px;
background: rgba(255, 255, 255, 0.1);
border: 2px solid var(--glass-border);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.5rem;
transition: all 0.3s ease;
}
.[Link] {
border-color: var(--primary-orange);
background: rgba(255, 102, 0, 0.2);
box-shadow: 0 0 15px rgba(255, 102, 0, 0.3);
}
/* Minimap */
.minimap {
position: absolute;
top: 30px;
right: 30px;
width: 200px;
height: 200px;
background: var(--card-bg);
backdrop-filter: blur(20px);
border-radius: 15px;
border: 1px solid var(--glass-border);
padding: 15px;
}
.minimap-title {
text-align: center;
font-family: 'Orbitron', monospace;
font-size: 0.9rem;
color: var(--primary-blue);
margin-bottom: 10px;
}
.minimap-canvas {
width: 100%;
height: 150px;
background: linear-gradient(45deg, #2d5016, #4a7c59);
border-radius: 8px;
position: relative;
overflow: hidden;
}
.mini-player {
position: absolute;
width: 8px;
height: 8px;
background: var(--primary-blue);
border-radius: 50%;
border: 2px solid white;
transform: translate(-50%, -50%);
z-index: 10;
}
.mini-enemy {
position: absolute;
width: 6px;
height: 6px;
background: var(--danger-red);
border-radius: 50%;
transform: translate(-50%, -50%);
}
.mini-storm {
position: absolute;
border: 2px solid var(--danger-red);
border-radius: 50%;
background: rgba(255, 0, 64, 0.1);
transform: translate(-50%, -50%);
}
/* Controls Info */
.controls {
position: absolute;
bottom: 30px;
left: 30px;
background: var(--card-bg);
backdrop-filter: blur(20px);
padding: 20px;
border-radius: 15px;
border: 1px solid var(--glass-border);
font-size: 0.9rem;
line-height: 1.6;
}
.controls h4 {
font-family: 'Orbitron', monospace;
color: var(--success-green);
margin-bottom: 10px;
}
/* Kill Feed */
.kill-feed {
position: absolute;
top: 120px;
right: 30px;
width: 300px;
max-height: 200px;
overflow-y: auto;
}
.kill-message {
background: var(--card-bg);
backdrop-filter: blur(20px);
padding: 10px 15px;
margin-bottom: 5px;
border-radius: 8px;
border: 1px solid var(--glass-border);
font-size: 0.9rem;
animation: slideIn 0.3s ease-out;
}
@keyframes slideIn {
from { opacity: 0; transform: translateX(100%); }
to { opacity: 1; transform: translateX(0); }
}
.[Link] {
border-left: 3px solid var(--danger-red);
}
.[Link] {
border-left: 3px solid var(--warning-yellow);
}
/* Loading Screen */
.loading-screen {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(135deg, var(--dark-bg) 0%, #1a1a2e 50%,
#16213e 100%);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 2000;
transition: opacity 0.5s ease;
}
.loading-title {
font-family: 'Orbitron', monospace;
font-size: 3rem;
font-weight: 900;
background: linear-gradient(135deg, var(--primary-blue), var(--primary-
orange));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin-bottom: 2rem;
text-align: center;
}
.loading-bar {
width: 400px;
height: 8px;
background: rgba(255, 255, 255, 0.1);
border-radius: 4px;
overflow: hidden;
margin-bottom: 1rem;
}
.loading-fill {
height: 100%;
background: linear-gradient(90deg, var(--primary-blue), var(--primary-
orange));
width: 0%;
transition: width 0.3s ease;
}
.loading-text {
font-size: 1.2rem;
color: var(--text-secondary);
text-align: center;
}
/* Victory/Defeat Screen */
.game-end-screen {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.9);
display: none;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 3000;
}
.end-title {
font-family: 'Orbitron', monospace;
font-size: 4rem;
font-weight: 900;
margin-bottom: 2rem;
text-align: center;
}
.victory {
color: var(--success-green);
text-shadow: 0 0 30px var(--success-green);
}
.defeat {
color: var(--danger-red);
text-shadow: 0 0 30px var(--danger-red);
}
.stats {
background: var(--card-bg);
backdrop-filter: blur(20px);
padding: 2rem;
border-radius: 15px;
border: 1px solid var(--glass-border);
text-align: center;
margin-bottom: 2rem;
}
.restart-btn {
padding: 15px 30px;
background: linear-gradient(135deg, var(--primary-blue), var(--primary-
orange));
border: none;
border-radius: 10px;
color: white;
font-family: 'Rajdhani', sans-serif;
font-size: 1.2rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
pointer-events: auto;
}
.restart-btn:hover {
transform: translateY(-2px);
box-shadow: 0 10px 30px rgba(0, 102, 255, 0.3);
}
.minimap, .controls {
display: none;
}
.weapon-hud {
bottom: 20px;
right: 20px;
left: 20px;
display: flex;
justify-content: space-between;
align-items: center;
}
}
</style>
</head>
<body>
<!-- Loading Screen -->
<div class="loading-screen" id="loadingScreen">
<div class="loading-title">🎮 3D BATTLE ROYALE</div>
<div class="loading-bar">
<div class="loading-fill" id="loadingFill"></div>
</div>
<div class="loading-text" id="loadingText">Initializing 3D Engine...</div>
</div>
<script>
// Game state
let gameState = {
scene: null,
camera: null,
renderer: null,
player: null,
enemies: [],
buildings: [],
terrain: null,
playerHealth: 100,
playerShield: 100,
playersAlive: 50,
stormTimer: 180,
currentWeapon: 0,
weapons: [
{ name: 'ASSAULT RIFLE', icon: '🔫', ammo: 30, maxAmmo: 120, damage:
35 },
{ name: 'SNIPER RIFLE', icon: '🏹', ammo: 5, maxAmmo: 25, damage: 85
},
{ name: 'GRENADES', icon: '💣', ammo: 3, maxAmmo: 3, damage: 100 }
],
keys: {},
mouse: { x: 0, y: 0 },
isPointerLocked: false,
gameStarted: false,
gameEnded: false,
kills: 0,
damageDealt: 0,
startTime: [Link]()
};
setTimeout(() => {
hideLoadingScreen();
start2DMode();
}, 500);
}, 1000);
}
// Fallback 2D mode
function start2DMode() {
[Link]('Starting 2D mode');
[Link]('gameCanvas').[Link] = 'none';
// Create 2D enemies
for (let i = 0; i < 15; i++) {
[Link]({
x: [Link]() * ([Link] - 100) + 50,
y: [Link]() * ([Link] - 100) + 50,
size: 16,
health: 100,
vx: ([Link]() - 0.5) * 2,
vy: ([Link]() - 0.5) * 2
});
}
// 2D game loop
function animate2D() {
if ([Link]) return;
// Draw player
[Link] = '#0066ff';
[Link] = '#ffffff';
[Link] = 3;
[Link]();
[Link](player2D.x, player2D.y, [Link], 0, [Link] * 2);
[Link]();
[Link]();
// Update position
enemy.x += [Link];
enemy.y += [Link];
// Keep in bounds
enemy.x = [Link]([Link], [Link]([Link] -
[Link], enemy.x));
enemy.y = [Link]([Link], [Link]([Link] -
[Link], enemy.y));
// Draw enemy
[Link] = '#ff0040';
[Link] = '#ffffff';
[Link] = 2;
[Link]();
[Link](enemy.x, enemy.y, [Link], 0, [Link] * 2);
[Link]();
[Link]();
[Link] = '#333';
[Link](enemy.x - barWidth/2, enemy.y - [Link] -
10, barWidth, barHeight);
[Link] = healthPercent > 0.5 ? '#00ff66' :
'#ff0040';
[Link](enemy.x - barWidth/2, enemy.y - [Link] -
10, barWidth * healthPercent, barHeight);
}
});
requestAnimationFrame(animate2D);
}
// 2D controls
[Link]('mousemove', (e) => {
const rect = [Link]();
player2D.x = [Link] - [Link];
player2D.y = [Link] - [Link];
});
// Visual feedback
[Link] = '#ffff00';
[Link]();
[Link](clickX, clickY, 10, 0, [Link] * 2);
[Link]();
// Find nearest enemy and damage
let nearest = null;
let minDist = Infinity;
[Link](enemy => {
if ([Link] > 0) {
const dist = [Link]((enemy.x - player2D.x)**2 + (enemy.y
- player2D.y)**2);
if (dist < minDist && dist < 150) {
minDist = dist;
nearest = enemy;
}
}
});
if (nearest) {
const weapon = [Link][[Link]];
[Link] -= [Link];
[Link] += [Link];
if ([Link] <= 0) {
[Link]++;
[Link]--;
updatePlayersUI();
addKillFeedMessage('💀 Enemy eliminated!', 'elimination');
} else {
addKillFeedMessage(`🎯 Hit for ${[Link]} damage!`,
'system');
}
// Use ammo
[Link] = [Link](0, [Link] - 1);
updateWeaponUI();
} else {
addKillFeedMessage('❌ Shot missed!', 'system');
}
});
animate2D();
addKillFeedMessage('🎮 2D Battle Mode! Move mouse to move, click to
shoot enemies!', 'system');
}
// Setup 3D scene
function setupScene() {
// Create scene
[Link] = new [Link]();
[Link] = new [Link](0x87CEEB); // Sky blue
[Link] = new [Link](0x87CEEB, 100, 1000);
// Create camera
[Link] = new [Link](75, [Link] /
[Link], 0.1, 2000);
[Link](0, 10, 0);
// Create renderer
const canvas = [Link]('gameCanvas');
[Link] = new [Link]({ canvas: canvas,
antialias: true });
[Link]([Link], [Link]);
[Link] = true;
[Link] = [Link];
// Add lighting
const ambientLight = new [Link](0x404040, 0.6);
[Link](ambientLight);
// Setup player
function setupPlayer() {
// Player is represented by the camera (first-person view)
[Link] = {
position: [Link],
velocity: new THREE.Vector3(0, 0, 0),
onGround: false,
health: 100,
shield: 100
};
}
// Setup terrain
function setupTerrain() {
// Create large terrain plane
const terrainGeometry = new [Link](2000, 2000, 100, 100);
// Create tree
function createTree(x, z) {
const treeGroup = new [Link]();
// Trunk
const trunkGeometry = new [Link](2, 3, 15, 8);
const trunkMaterial = new [Link]({ color:
0x8B4513 });
const trunk = new [Link](trunkGeometry, trunkMaterial);
[Link].y = 7.5;
[Link] = true;
[Link](trunk);
// Leaves
const leavesGeometry = new [Link](8, 8, 6);
const leavesMaterial = new [Link]({ color:
0x228B22 });
const leaves = new [Link](leavesGeometry, leavesMaterial);
[Link].y = 20;
[Link] = true;
[Link](leaves);
[Link](x, 0, z);
[Link](treeGroup);
}
// Create rock
function createRock(x, z) {
const rockGeometry = new [Link](3 + [Link]() *
3, 0);
const rockMaterial = new [Link]({ color:
0x696969 });
const rock = new [Link](rockGeometry, rockMaterial);
[Link](x, 2, z);
[Link] = true;
[Link] = true;
[Link](rock);
}
// Setup enemies
function setupEnemies() {
for (let i = 0; i < 20; i++) {
createEnemy(
([Link]() - 0.5) * 1000,
([Link]() - 0.5) * 1000
);
}
}
// Create enemy
function createEnemy(x, z) {
const enemyGeometry = new [Link](2, 8, 4, 8);
const enemyMaterial = new [Link]({ color:
0xff0040 });
const enemy = new [Link](enemyGeometry, enemyMaterial);
[Link](x, 5, z);
[Link] = true;
const enemyData = {
mesh: enemy,
health: 100,
position: [Link],
velocity: new THREE.Vector3(0, 0, 0),
lastMove: [Link]()
};
[Link](enemyData);
[Link](enemy);
}
// Setup buildings
function setupBuildings() {
// Create some buildings scattered around
for (let i = 0; i < 30; i++) {
createBuilding(
([Link]() - 0.5) * 1200,
([Link]() - 0.5) * 1200
);
}
}
// Create building
function createBuilding(x, z) {
const buildingGroup = new [Link]();
// Main building
const buildingGeometry = new [Link](width, height, depth);
const buildingMaterial = new [Link]({
color: new [Link]().setHSL(0.1, 0.2, 0.3 + [Link]() *
0.3)
});
const building = new [Link](buildingGeometry, buildingMaterial);
[Link].y = height / 2;
[Link] = true;
[Link] = true;
[Link](building);
// Roof
const roofGeometry = new [Link](width * 0.7, 8, 4);
const roofMaterial = new [Link]({ color:
0x8B4513 });
const roof = new [Link](roofGeometry, roofMaterial);
[Link].y = height + 4;
[Link] = true;
[Link](roof);
[Link](x, 0, z);
[Link](buildingGroup);
[Link](buildingGroup);
}
// Setup controls
function setupControls() {
// Keyboard events
[Link]('keydown', (event) => {
[Link][[Link]] = true;
// Weapon switching
if ([Link] === 'Digit1') selectWeapon(0);
if ([Link] === 'Digit2') selectWeapon(1);
if ([Link] === 'Digit3') selectWeapon(2);
if ([Link] === 'KeyR') reload();
});
// Mouse events
[Link]('mousemove', (event) => {
if ([Link]) {
const sensitivity = 0.002;
[Link].y -= [Link] * sensitivity;
[Link].x -= [Link] * sensitivity;
[Link].x = [Link](-[Link]/2,
[Link]([Link]/2, [Link].x));
}
});
[Link]('click', () => {
if ([Link] && ![Link]) {
shoot();
}
});
// Pointer lock
[Link]('pointerlockchange', () => {
[Link] = [Link] ===
[Link]('gameCanvas');
});
// Window resize
[Link]('resize', () => {
[Link] = [Link] / [Link];
[Link]();
[Link]([Link], [Link]);
});
}
// Player movement
function updatePlayer() {
if (![Link] || [Link]) return;
// Movement
if ([Link]['KeyW']) velocity.z -= moveSpeed * sprintMultiplier;
if ([Link]['KeyS']) velocity.z += moveSpeed * sprintMultiplier;
if ([Link]['KeyA']) velocity.x -= moveSpeed * sprintMultiplier;
if ([Link]['KeyD']) velocity.x += moveSpeed * sprintMultiplier;
// Update position
[Link](velocity);
// Boundary check
const boundary = 900;
[Link].x = [Link](-boundary, [Link](boundary,
[Link].x));
[Link].z = [Link](-boundary, [Link](boundary,
[Link].z));
// Update minimap
updateMinimap();
}
// Update enemies
function updateEnemies() {
[Link]((enemy, index) => {
if ([Link] <= 0) return;
// Simple AI movement
if ([Link]() - [Link] > 2000) {
const direction = new THREE.Vector3(
([Link]() - 0.5) * 2,
0,
([Link]() - 0.5) * 2
).normalize();
[Link] = [Link](0.2);
[Link] = [Link]();
}
// Apply movement
[Link]([Link]);
// Boundary check
const boundary = 800;
[Link].x = [Link](-boundary, [Link](boundary,
[Link].x));
[Link].z = [Link](-boundary, [Link](boundary,
[Link].z));
});
}
// Shooting
function shoot() {
const weapon = [Link][[Link]];
if ([Link] <= 0) {
addKillFeedMessage('🔫 Need to reload!', 'system');
return;
}
[Link]--;
updateWeaponUI();
if ([Link] > 0) {
const hitEnemy = [Link](e => [Link] ===
intersects[0].object);
if (hitEnemy) {
damageEnemy(hitEnemy, [Link]);
}
}
// Damage enemy
function damageEnemy(enemy, damage) {
[Link] -= damage;
[Link] += damage;
if ([Link] <= 0) {
// Enemy eliminated
[Link] = false;
[Link]++;
[Link]--;
addKillFeedMessage(`💀 You eliminated an enemy! (+${damage}
damage)`, 'elimination');
[Link]([Link]).add([Link](2));
[Link](flash);
setTimeout(() => {
[Link](flash);
}, 50);
}
// Weapon selection
function selectWeapon(index) {
if (index >= 0 && index < [Link]) {
[Link] = index;
updateWeaponUI();
// Reload
function reload() {
const weapon = [Link][[Link]];
if ([Link] < [Link]) {
[Link] = [Link];
updateWeaponUI();
addKillFeedMessage('🔄 Reloaded!', 'system');
}
}
// Update weapon UI
function updateWeaponUI() {
const weapon = [Link][[Link]];
[Link]('weaponName').textContent = [Link];
[Link]('currentAmmo').textContent = [Link];
[Link]('totalAmmo').textContent = [Link];
}
// Update minimap
function updateMinimap() {
const miniPlayer = [Link]('miniPlayer');
const mapSize = 170; // Size of minimap canvas
const worldSize = 1800; // Size of game world
[Link] = x + 'px';
[Link] = y + 'px';
}
// Setup UI
function setupUI() {
updateWeaponUI();
updateHealthUI();
updatePlayersUI();
updateStormTimer();
}
// Update health UI
function updateHealthUI() {
[Link]('healthBar').[Link] =
[Link] + '%';
[Link]('healthText').textContent =
[Link];
[Link]('shieldBar').[Link] =
[Link] + '%';
[Link]('shieldText').textContent =
[Link];
}
// Update players UI
function updatePlayersUI() {
[Link]('playersCount').textContent =
[Link];
}
[Link](messageEl);
// Game loop
function startGameLoop() {
[Link]('Starting game loop...');
if ([Link] === 0) {
addKillFeedMessage(' Storm has moved! Players eliminated!',
'system');
[Link] = 120; // Reset
// Random eliminations
if ([Link]() < 0.03 && [Link] > 2) {
[Link]--;
updatePlayersUI();
addKillFeedMessage('💀 Player eliminated!', 'elimination');
}
// End game
function endGame(victory) {
[Link] = true;
const endScreen = [Link]('gameEndScreen');
const endTitle = [Link]('endTitle');
if (victory) {
[Link] = '🏆 VICTORY ROYALE!';
[Link] = 'end-title victory';
} else {
[Link] = '💀 ELIMINATED';
[Link] = 'end-title defeat';
}
// Update stats
const survivalTime = [Link](([Link]() - [Link]) /
1000);
const minutes = [Link](survivalTime / 60);
const seconds = survivalTime % 60;
[Link]('finalKills').textContent = [Link];
[Link]('finalDamage').textContent =
[Link];
[Link]('survivalTime').textContent = `${minutes}:$
{[Link]().padStart(2, '0')}`;
[Link]('finalPosition').textContent = victory ? '#1' :
`#${[Link] + 1}`;
[Link] = 'flex';
}
// Restart game
function restartGame() {
[Link]();
}