手机3D自由跑酷
by PixelHawk74106 lines4.5 KB🛠️ Three.js (3D graphics)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>手机3D自由跑酷</title>
<style>
*{margin:0;padding:0;touch-action:none;}
body{overflow:hidden;background:#111;color:#fff;font-size:14px;}
#tip{position:absolute;top:10px;left:10px;z-index:99;background:rgba(0,0,0,0.4);padding:6px;border-radius:6px;}
/* 虚拟触屏按键 */
.ctrl{position:absolute;width:70px;height:70px;border-radius:50%;background:rgba(255,255,255,0.15);border:1px solid #fff;display:flex;align-items:center;justify-content:center;font-size:24px;user-select:none;}
#btnW{left:50%;transform:translateX(-50%);bottom:110px;}
#btnA{left:20px;bottom:40px;}
#btnD{right:20px;bottom:40px;}
#btnJump{left:50%;transform:translateX(-50%);bottom:20px;width:120px;height:60px;border-radius:12px;background:rgba(60,180,255,0.3);}
</style>
</head>
<body>
<div id="tip">滑动屏幕转动视角<br>点击画面锁定镜头</div>
<div class="ctrl" id="btnW">前</div>
<div class="ctrl" id="btnA">左</div>
<div class="ctrl" id="btnD">右</div>
<div class="ctrl" id="btnJump">跳跃</div>
<script src="https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.160.0/examples/js/controls/PointerLockControls.js"></script>
<script>
let scene, camera, renderer, controls;
let playerVelocity = new THREE.Vector3();
let moveForward = false, moveLeft = false, moveRight = false;
let canJump = false;
const gravity = -0.012;
init();
animate();
function init(){
scene = new THREE.Scene();
scene.background = new THREE.Color(0x87ceeb);
camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
camera.position.set(0, 1.8, 0);
renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
controls = new THREE.PointerLockControls(camera, document.body);
document.body.addEventListener('click', ()=>controls.lock());
// 场景光照
const dirLight = new THREE.DirectionalLight(0xffffff,1);
dirLight.position.set(50,100,50);
scene.add(dirLight);
scene.add(new THREE.AmbientLight(0xcccccc,0.4));
// 长条跑道地面
const groundGeo = new THREE.PlaneGeometry(200,20);
const groundMat = new THREE.MeshLambertMaterial({color:0x337733});
const ground = new THREE.Mesh(groundGeo, groundMat);
ground.rotation.x = -Math.PI/2;
ground.position.y = 0;
scene.add(ground);
// 随机高低跳台障碍
for(let i=1; i<=30; i++){
const h = Math.random()*1.5 + 0.3;
const platGeo = new THREE.BoxGeometry(4, h, 3);
const platMat = new THREE.MeshLambertMaterial({color:0x664422});
const plat = new THREE.Mesh(platGeo, platMat);
plat.position.set((Math.random()-0.5)*8, h/2, -i*12);
scene.add(plat);
}
// 触屏按键逻辑
const btnW = document.getElementById('btnW');
const btnA = document.getElementById('btnA');
const btnD = document.getElementById('btnD');
const btnJump = document.getElementById('btnJump');
btnW.addEventListener('touchstart',()=>moveForward=true);
btnW.addEventListener('touchend',()=>moveForward=false);
btnA.addEventListener('touchstart',()=>moveLeft=true);
btnA.addEventListener('touchend',()=>moveLeft=false);
btnD.addEventListener('touchstart',()=>moveRight=true);
btnD.addEventListener('touchend',()=>moveRight=false);
btnJump.addEventListener('touchstart',()=>{if(canJump) playerVelocity.y = 0.22});
window.addEventListener('resize', onWindowResize);
}
function onWindowResize(){
camera.aspect = window.innerWidth/window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate(){
requestAnimationFrame(animate);
playerVelocity.x *= 0.88;
playerVelocity.z *= 0.88;
playerVelocity.y += gravity;
canJump = false;
if(moveForward) playerVelocity.z -= 0.15;
if(moveLeft) playerVelocity.x -= 0.15;
if(moveRight) playerVelocity.x += 0.15;
controls.moveRight(-playerVelocity.x);
controls.moveForward(-playerVelocity.z);
camera.position.y += playerVelocity.y;
// 落地判定
if(camera.position.y <= 1.8){
playerVelocity.y = 0;
camera.position.y = 1.8;
canJump = true;
}
renderer.render(scene, camera);
}
</script>
</body>Game Source: 手机3D自由跑酷
Creator: PixelHawk74
Libraries: three
Complexity: moderate (106 lines, 4.5 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: 3d-pixelhawk74" to link back to the original. Then publish at arcadelab.ai/publish.