Meta Description" name="description" />
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Grand Theft Auto VI - 3D</title>
<style>
body { margin:0; overflow:hidden; background:#000; font-family:Arial; }
#title { position:absolute; top:0; left:0; width:100%; height:100%; z-index:100; background-size:cover; image-rendering:pixelated; }
#overlay { position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); color:#fff; font-size:56px; text-shadow:0 0 30px #f0f; text-align:center; pointer-events:none; z-index:101; }
canvas { display:block; }
#hud { position:absolute; bottom:15px; left:15px; color:#fff; font-size:18px; text-shadow:2px 2px #000; z-index:10; pointer-events:none; }
#mission { color:#ff0; font-weight:bold; }
#status { position:absolute; top:30%; left:50%; transform:translateX(-50%); background:rgba(0,0,0,0.8); padding:15px 30px; border-radius:10px; font-size:28px; color:#0f0; display:none; z-index:102; }
</style>
</head>
<body>
<img id="title" src="gta_title.png">
<div id="overlay">GRAND THEFT AUTO VI<br><span style="font-size:28px">CLICK SCREEN THEN PRESS ANY KEY</span></div>
<canvas id="canvas"></canvas>
<div id="hud">
<div id="mission">MISSION: Steal a car (E)</div>
<div>WANTED: <span id="stars"></span></div>
</div>
<div id="status"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.134.0/examples/js/controls/PointerLockControls.js"></script>
<script>
const scene = new THREE.Scene();
scene.fog = new THREE.Fog(0x88ccff, 80, 600);
const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({canvas:document.getElementById('canvas'), antialias:true});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
// Lights
const sun = new THREE.DirectionalLight(0xffffff, 1.3);
sun.position.set(100, 150, 100);
sun.castShadow = true;
scene.add(sun);
scene.add(new THREE.AmbientLight(0x777777));
// Ground
const ground = new THREE.Mesh(new THREE.PlaneGeometry(1000,1000), new THREE.MeshLambertMaterial({color:0x228833}));
ground.rotation.x = -Math.PI/2;
ground.receiveShadow = true;
scene.add(ground);
// Water
const water = new THREE.Mesh(new THREE.PlaneGeometry(1000,1000), new THREE.MeshLambertMaterial({color:0x0088ff, transparent:true, opacity:0.7}));
water.rotation.x = -Math.PI/2;
water.position.y = -0.2;
scene.add(water);
// Buildings & Bank
const bank = new THREE.Mesh(new THREE.BoxGeometry(40,25,40), new THREE.MeshLambertMaterial({color:0x00aaaa}));
bank.position.set(120,12.5,-80);
scene.add(bank);
function makeBuilding(x,z,w,d,h,color) {
const b = new THREE.Mesh(new THREE.BoxGeometry(w,d,h), new THREE.MeshLambertMaterial({color}));
b.position.set(x, h/2, z);
b.castShadow = b.receiveShadow = true;
scene.add(b);
}
makeBuilding(-100,50,60,50,80,0x555555);
makeBuilding(80,140,50,70,60,0x666666);
// Player
let player = {
mesh: new THREE.Mesh(new THREE.CapsuleGeometry(2.5,8,8,16), new THREE.MeshLambertMaterial({color:0x00aaff})),
velocity: new THREE.Vector3(),
speed: 0.45,
health: 100,
inCar: false,
currentCar: null
};
player.mesh.position.set(0,6,80);
player.mesh.castShadow = true;
scene.add(player.mesh);
// Camera offset (third person)
let camOffset = new THREE.Vector3(0, 18, 35);
// Controls
const controls = new THREE.PointerLockControls(camera, document.body);
document.addEventListener('click', () => controls.lock());
const keys = {};
window.addEventListener('keydown', e => keys[e.key.toLowerCase()] = true);
window.addEventListener('keyup', e => keys[e.key.toLowerCase()] = false);
// Cars
let cars = [];
function createCar(x,z,color) {
const group = new THREE.Group();
const body = new THREE.Mesh(new THREE.BoxGeometry(14,5,7), new THREE.MeshLambertMaterial({color}));
body.castShadow = true;
group.add(body);
group.position.set(x,3,z);
scene.add(group);
return {group, body, occupied:false};
}
cars.push(createCar(-60,60,0xff2222));
cars.push(createCar(140,-40,0xffaa00));
// Pedestrians
let peds = [];
for(let i=0;i<15;i++){
const ped = new THREE.Mesh(new THREE.CapsuleGeometry(1.8,5,8,16), new THREE.MeshLambertMaterial({color:0xff3333}));
ped.position.set(Math.random()*300-150, 4, Math.random()*300-150);
ped.castShadow = true;
scene.add(ped);
peds.push({mesh:ped, vx:(Math.random()-0.5)*0.8, vz:(Math.random()-0.5)*0.8});
}
// Police
let police = [];
// Mission
let missionStage = 0; // 0=steal car, 1=go to bank, 2=escape
let wantedLevel = 0;
// Title
const titleImg = document.getElementById('title');
const overlay = document.getElementById('overlay');
let gameStarted = false;
window.addEventListener('keydown', () => {
if(!gameStarted){
titleImg.style.display = 'none';
overlay.style.display = 'none';
gameStarted = true;
controls.lock();
}
});
function updateHUD(){
let txt = ["MISSION: Steal a car (E)", "MISSION: Go to BANK & press R", "MISSION: ESCAPE THE COPS!"][missionStage] || "MISSION COMPLETE!";
document.getElementById('mission').textContent = txt;
let stars = '★'.repeat(wantedLevel);
document.getElementById('stars').textContent = stars;
}
updateHUD();
function showStatus(text, color="#0f0"){
const s = document.getElementById('status');
s.textContent = text;
s.style.color = color;
s.style.display = 'block';
setTimeout(()=> s.style.display='none', 2500);
}
function respawnHospital(){
player.mesh.position.set(-180,6,180);
player.health = 100;
player.inCar = false;
wantedLevel = 0;
police = [];
showStatus("RESPAWNED AT HOSPITAL", "#0ff");
updateHUD();
}
function respawnPoliceStation(){
player.mesh.position.set(180,6,-180);
player.health = 100;
player.inCar = false;
wantedLevel = 0;
police = [];
showStatus("BUSTED! Respawned at POLICE STATION", "#f00");
updateHUD();
}
function animate(){
requestAnimationFrame(animate);
if(!gameStarted) { renderer.render(scene,camera); return; }
const forward = new THREE.Vector3(0,0,-1).applyQuaternion(controls.getObject().quaternion);
const right = new THREE.Vector3(1,0,0).applyQuaternion(controls.getObject().quaternion);
let speed = player.inCar ? 1.2 : player.speed;
if(keys['w'] || keys['arrowup']) {
if(player.inCar) player.currentCar.group.position.addScaledVector(forward, speed);
else player.mesh.position.addScaledVector(forward, speed);
}
if(keys['s'] || keys['arrowdown']) {
if(player.inCar) player.currentCar.group.position.addScaledVector(forward, -speed);
else player.mesh.position.addScaledVector(forward, -speed);
}
if(keys['a'] || keys['arrowleft']) {
if(player.inCar) player.currentCar.group.position.addScaledVector(right, -speed*0.8);
else player.mesh.position.addScaledVector(right, -speed);
}
if(keys['d'] || keys['arrowright']) {
if(player.inCar) player.currentCar.group.position.addScaledVector(right, speed*0.8);
else player.mesh.position.addScaledVector(right, speed);
}
// E - enter/exit car
if(keys['e']){
keys['e']=false;
if(player.inCar){
player.inCar = false;
player.currentCar.occupied = false;
showStatus("EXITED CAR");
}else{
for(let c of cars){
const dist = player.mesh.position.distanceTo(c.group.position);
if(dist < 18 && !c.occupied){
player.inCar = true;
player.currentCar = c;
c.occupied = true;
if(missionStage===0){
missionStage=1;
updateHUD();
}
showStatus("VEHICLE STOLEN!", "#ff0");
break;
}
}
}
}
// Space - punch
if(keys[' '] && !player.inCar){
keys[' ']=false;
for(let p of peds){
const d = player.mesh.position.distanceTo(p.mesh.position);
if(d < 12){
p.mesh.position.add(new THREE.Vector3().subVectors(p.mesh.position, player.mesh.position).multiplyScalar(4));
showStatus("PUNCHED!", "#f80");
break;
}
}
}
// R - rob bank
if(keys['r'] && missionStage===1){
keys['r']=false;
const distToBank = player.mesh.position.distanceTo(bank.position);
if(distToBank < 30){
missionStage = 2;
wantedLevel = 5;
updateHUD();
showStatus("BANK ROBBED! RUN!!!", "#f00");
// Spawn police
police = [
{group: createCar(140,-120,0x0000ff).group},
{group: createCar(100,-150,0x0000ff).group}
];
}
}
// Police chase
if(wantedLevel > 0){
for(let p of police){
const target = player.inCar ? player.currentCar.group.position : player.mesh.position;
const dir = new THREE.Vector3().subVectors(target, p.group.position).normalize();
p.group.position.addScaledVector(dir, 1.1);
const d = p.group.position.distanceTo(target);
if(d < 14){
respawnPoliceStation();
}
}
// Health loss when chased
if(Math.random()<0.04) player.health -= 1;
if(player.health <= 0){
respawnHospital();
}
}
// Update third-person camera
let targetPos = player.inCar ? player.currentCar.group.position : player.mesh.position;
const idealOffset = camOffset.clone().applyQuaternion(controls.getObject().quaternion);
camera.position.copy(targetPos).add(idealOffset);
camera.lookAt(targetPos.x, targetPos.y + 8, targetPos.z);
// Keep player & peds on ground
player.mesh.position.y = 6;
if(player.inCar) player.currentCar.group.position.y = 3;
peds.forEach(p=>{ p.mesh.position.y=4; });
// Simple ped movement
peds.forEach(p=>{
p.mesh.position.x += p.vx;
p.mesh.position.z += p.vz;
if(Math.random()<0.03){ p.vx=(Math.random()-0.5)*1.2; p.vz=(Math.random()-0.5)*1.2; }
});
renderer.render(scene, camera);
}
animate();
window.addEventListener('resize', ()=>{
camera.aspect = window.innerWidth/window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
console.log("%c3D GTA VI READY - Click screen & enjoy the chaos!", "color:#ff0;font-size:18px");
</script>
</body>
</html>4
3
136KB
618KB
345.0ms
164.0ms
345.0ms