<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>3D Battle Ground</title>
<style>
body {
margin:0;
overflow:hidden;
background:#000;
font-family:Arial;
}
#ui {
position:fixed;
top:10px;
left:10px;
color:white;
z-index:10;
font-size:18px;
}
#controls {
position:fixed;
bottom:25px;
width:100%;
display:flex;
justify-content:space-around;
z-index:10;
}
button {
padding:17px;
border:0;
border-radius:50%;
background:#222c;
color:white;
font-weight:bold;
}
</style>
</head>
<body>
<div id="ui">
❤️ Health: <span id="hp">100</span>
<br>
🎯 Score: <span id="score">0</span>
</div>
<div id="controls">
<button id="left">⬅️</button>
<button id="shoot">🔫 FIRE</button>
<button id="right">➡️</button>
<button id="jump">⬆️</button>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x87ceeb);
const camera = new THREE.PerspectiveCamera(
75, window.innerWidth/window.innerHeight, 0.1, 1000
);
const renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(window.innerWidth,window.innerHeight);
document.body.appendChild(renderer.domElement);
scene.add(new THREE.HemisphereLight(0xffffff,0x555555,2));
const light = new THREE.DirectionalLight(0xffffff,2);
light.position.set(10,20,10);
scene.add(light);
// Ground
const ground = new THREE.Mesh(
new THREE.PlaneGeometry(200,200),
new THREE.MeshStandardMaterial({color:0x398b35})
);
ground.rotation.x=-Math.PI/2;
scene.add(ground);
// Player
const player = new THREE.Group();
const body = new THREE.Mesh(
new THREE.BoxGeometry(1,1.5,0.6),
new THREE.MeshStandardMaterial({color:0x1565c0})
);
body.position.y=1;
player.add(body);
const head = new THREE.Mesh(
new THREE.SphereGeometry(0.4,16,16),
new THREE.MeshStandardMaterial({color:0xffcc99})
);
head.position.y=2;
player.add(head);
scene.add(player);
player.position.set(0,0,5);
// Trees
for(let i=0;i<35;i++){
const tree=new THREE.Group();
const trunk=new THREE.Mesh(
new THREE.CylinderGeometry(.2,.3,2),
new THREE.MeshStandardMaterial({color:0x754321})
);
trunk.position.y=1;
tree.add(trunk);
const leaves=new THREE.Mesh(
new THREE.ConeGeometry(1.2,3,8),
new THREE.MeshStandardMaterial({color:0x08752c})
);
leaves.position.y=3;
tree.add(leaves);
tree.position.set(
Math.random()*80-40,0,
Math.random()*-80
);
scene.add(tree);
}
// Enemies
let enemies=[];
for(let i=0;i<8;i++){
const enemy=new THREE.Mesh(
new THREE.BoxGeometry(1,2,1),
new THREE.MeshStandardMaterial({color:0xd32f2f})
);
enemy.position.set(Math.random()*30-15,1,-10-Math.random()*35);
scene.add(enemy);
enemies.push(enemy);
}
camera.position.set(0,5,12);
camera.lookAt(player.position);
// Movement
let move=0;
let score=0;
let health=100;
document.getElementById("left").ontouchstart=()=>move=-1;
document.getElementById("right").ontouchstart=()=>move=1;
document.getElementById("left").ontouchend=()=>move=0;
document.getElementById("right").ontouchend=()=>move=0;
document.getElementById("jump").onclick=()=>{
player.position.y=2;
setTimeout(()=>player.position.y=0,500);
};
// Shooting
document.getElementById("shoot").onclick=()=>{
let target=null;
let min=Infinity;
enemies.forEach(enemy=>{
const d=enemy.position.distanceTo(player.position);
if(enemy.visible && d<min){
min=d;
target=enemy;
}
});
if(target && min<25){
target.visible=false;
score+=10;
document.getElementById("score").innerText=score;
}
};
function animate(){
requestAnimationFrame(animate);
player.position.x+=move*0.15;
player.position.x=Math.max(-15,Math.min(15,player.position.x));
camera.position.x=player.position.x;
camera.position.z=player.position.z+9;
camera.lookAt(player.position.x,1,player.position.z-5);
renderer.render(scene,camera);
}
animate();
window.onresize=()=>{
camera.aspect=window.innerWidth/window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth,window.innerHeight);
};
</script>
</body>
</html>
2
2
123KB
594KB
1,896.0ms
192.0ms
1,896.0ms