Meta Description" name="description" />
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>IGI 3D Mobile - High Graphics</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<style>
body { margin: 0; overflow: hidden; background: #000; touch-action: none; font-family: 'Courier New', Courier, monospace; }
#ui-layer { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 10; }
/* Joysticks & Buttons */
.controls { position: absolute; bottom: 30px; pointer-events: auto; }
#move-joy { left: 30px; width: 120px; height: 120px; background: rgba(255,255,255,0.1); border-radius: 50%; border: 2px solid rgba(0,255,0,0.3); }
#stick { position: absolute; width: 50px; height: 50px; background: rgba(0,255,0,0.5); border-radius: 50%; top: 35px; left: 35px; }
#fire-btn { right: 30px; bottom: 40px; width: 90px; height: 90px; background: rgba(255,0,0,0.4); border: 3px solid #ff0000; border-radius: 50%; color: white; display: flex; align-items: center; justify-content: center; font-weight: bold; font-size: 20px; pointer-events: auto; }
#crosshair { position: absolute; top: 50%; left: 50%; width: 24px; height: 24px; border: 2px solid #00ff00; transform: translate(-50%, -50%); border-radius: 50%; }
#crosshair::after { content: ''; position: absolute; top: 50%; left: 50%; width: 2px; height: 2px; background: #00ff00; transform: translate(-50%, -50%); }
.stats { position: absolute; top: 20px; left: 20px; color: #00ff00; font-size: 18px; text-shadow: 2px 2px #000; }
#loading { position: fixed; inset: 0; background: #000; color: #00ff00; display: flex; align-items: center; justify-content: center; z-index: 100; font-size: 24px; }
</style>
</head>
<body>
<div id="loading">INITIALIZING MISSION...</div>
<div id="ui-layer">
<div class="stats">
<div>HEALTH: 100%</div>
<div>OBJECTIVE: ELIMINATE GUARDS</div>
</div>
<div id="crosshair"></div>
<div id="move-joy" class="controls">
<div id="stick"></div>
</div>
<div id="fire-btn" class="controls">FIRE</div>
</div>
<script>
let scene, camera, renderer, player, clock;
let moveForward = false, moveBackward = false, moveLeft = false, moveRight = false;
let joystick = { x: 0, y: 0, active: false };
let enemies = [];
function init() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0x87ceeb); // Sky color
scene.fog = new THREE.Fog(0x87ceeb, 0, 100);
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
clock = new THREE.Clock();
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);
// Lights
const ambientLight = new THREE.AmbientLight(0x404040, 2);
scene.add(ambientLight);
const sunLight = new THREE.DirectionalLight(0xffffff, 1);
sunLight.position.set(10, 20, 10);
sunLight.castShadow = true;
scene.add(sunLight);
// Ground (Grass)
const groundGeo = new THREE.PlaneGeometry(1000, 1000);
const groundMat = new THREE.MeshStandardMaterial({ color: 0x2d4c1e });
const ground = new THREE.Mesh(groundGeo, groundMat);
ground.rotation.x = -Math.PI / 2;
ground.receiveShadow = true;
scene.add(ground);
// Buildings (GTA/IGI Style)
for(let i=0; i<15; i++) {
createBuilding(Math.random()*100 - 50, Math.random()*100 - 50);
}
// Enemies
for(let i=0; i<5; i++) {
createEnemy(Math.random()*40 - 20, Math.random()*40 - 20);
}
// Player setup
player = new THREE.Group();
player.position.set(0, 1.6, 0);
scene.add(player);
player.add(camera);
// Weapon Placeholder (Gun model)
const gunGeo = new THREE.BoxGeometry(0.1, 0.1, 0.5);
const gunMat = new THREE.MeshStandardMaterial({ color: 0x222222 });
const gun = new THREE.Mesh(gunGeo, gunMat);
gun.position.set(0.3, -0.3, -0.5);
camera.add(gun);
document.getElementById('loading').style.display = 'none';
setupControls();
animate();
}
function createBuilding(x, z) {
const h = 5 + Math.random() * 10;
const geo = new THREE.BoxGeometry(5, h, 5);
const mat = new THREE.MeshStandardMaterial({ color: 0x808080 });
const b = new THREE.Mesh(geo, mat);
b.position.set(x, h/2, z);
b.castShadow = true;
b.receiveShadow = true;
scene.add(b);
}
function createEnemy(x, z) {
const geo = new THREE.CapsuleGeometry(0.4, 1, 4, 8);
const mat = new THREE.MeshStandardMaterial({ color: 0x990000 });
const e = new THREE.Mesh(geo, mat);
e.position.set(x, 1, z);
e.castShadow = true;
scene.add(e);
enemies.push(e);
}
function setupControls() {
const joy = document.getElementById('move-joy');
const stick = document.getElementById('stick');
joy.addEventListener('touchstart', (e) => { joystick.active = true; });
document.addEventListener('touchmove', (e) => {
if(!joystick.active) return;
const touch = e.touches[0];
const rect = joy.getBoundingClientRect();
const cx = rect.left + 60, cy = rect.top + 60;
let dx = touch.clientX - cx, dy = touch.clientY - cy;
const dist = Math.sqrt(dx*dx + dy*dy);
if(dist > 40) { dx *= 40/dist; dy *= 40/dist; }
stick.style.transform = `translate(${dx}px, ${dy}px)`;
joystick.x = dx / 40;
joystick.y = dy / 40;
});
document.addEventListener('touchend', () => {
joystick.active = false;
stick.style.transform = `translate(0,0)`;
joystick.x = 0; joystick.y = 0;
});
// Shooting
document.getElementById('fire-btn').addEventListener('touchstart', (e) => {
e.preventDefault();
shoot();
});
}
function shoot() {
// Raycaster for hit detection
const raycaster = new THREE.Raycaster();
raycaster.setFromCamera(new THREE.Vector2(0,0), camera);
const intersects = raycaster.intersectObjects(enemies);
if(intersects.length > 0) {
const hit = intersects[0].object;
hit.scale.y = 0.1; // Flatten enemy on death
hit.position.y = 0.1;
setTimeout(() => scene.remove(hit), 2000);
}
}
function animate() {
requestAnimationFrame(animate);
const delta = clock.getDelta();
if(joystick.active) {
player.translateZ(joystick.y * 0.15);
player.translateX(joystick.x * 0.1);
}
// Camera rotation (Simulation of looking around - auto rotate for mobile demo)
// In a real game, you'd add a second joystick for looking.
player.rotation.y -= joystick.x * 0.02;
renderer.render(scene, camera);
}
window.onload = init;
</script>
</body>
</html>
2
2
127KB
597KB
206.0ms
212.0ms
206.0ms