Update index.html
Browse files- index.html +126 -138
index.html
CHANGED
|
@@ -1,153 +1,141 @@
|
|
| 1 |
<!DOCTYPE html>
|
| 2 |
<html>
|
| 3 |
<head>
|
| 4 |
-
|
| 5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
</head>
|
| 7 |
<body>
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
|
|
|
| 23 |
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
};
|
| 50 |
-
var skyGeo = new THREE.SphereGeometry(5000, 32, 15);
|
| 51 |
-
var skyMat = new THREE.ShaderMaterial({
|
| 52 |
-
vertexShader, fragmentShader, uniforms: skyUniforms, side: THREE.BackSide
|
| 53 |
-
});
|
| 54 |
-
var sky = new THREE.Mesh(skyGeo, skyMat);
|
| 55 |
-
scene.add(sky);
|
| 56 |
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
var ground = new THREE.Mesh(groundGeo, groundMat);
|
| 61 |
-
ground.rotation.x = -Math.PI / 2;
|
| 62 |
-
scene.add(ground);
|
| 63 |
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
var wingGeo = new THREE.BoxGeometry(10, 1, 1);
|
| 71 |
-
var wingMat = new THREE.MeshLambertMaterial({ color: 0xFF0000 }); // red
|
| 72 |
-
var leftWing = new THREE.Mesh(wingGeo, wingMat);
|
| 73 |
-
leftWing.position.x = -5;
|
| 74 |
-
planeGeo.add(leftWing);
|
| 75 |
-
var rightWing = new THREE.Mesh(wingGeo, wingMat);
|
| 76 |
-
rightWing.position.x = 5;
|
| 77 |
-
planeGeo.add(rightWing);
|
| 78 |
-
var tailGeo = new THREE.ConeGeometry(1, 2, 10);
|
| 79 |
-
var tailMat = new THREE.MeshLambertMaterial({ color: 0x0000FF }); // blue
|
| 80 |
-
var tail = new THREE.Mesh(tailGeo, tailMat);
|
| 81 |
-
tail.position.z = -5;
|
| 82 |
-
planeGeo.add(tail);
|
| 83 |
-
scene.add(planeGeo);
|
| 84 |
-
var plane = planeGeo; // we'll move this
|
| 85 |
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
//
|
| 111 |
-
var
|
| 112 |
-
|
| 113 |
-
var
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
plane.position.y = 0; // don't go underground
|
| 136 |
-
velocity.y = 0;
|
| 137 |
-
}
|
| 138 |
-
if (altitude > maxAltitude) {
|
| 139 |
-
plane.position.y = maxAltitude; // don't go too high
|
| 140 |
-
velocity.y = 0;
|
| 141 |
-
}
|
| 142 |
-
velocity.multiplyScalar(0.99); // friction
|
| 143 |
-
|
| 144 |
-
// CAMERA FOLLOW
|
| 145 |
-
camera.lookAt(plane.position);
|
| 146 |
-
|
| 147 |
-
// RENDER
|
| 148 |
-
renderer.render(scene, camera);
|
| 149 |
}
|
| 150 |
-
|
| 151 |
-
|
|
|
|
|
|
|
|
|
|
| 152 |
</body>
|
| 153 |
</html>
|
|
|
|
| 1 |
<!DOCTYPE html>
|
| 2 |
<html>
|
| 3 |
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<title>Flight Sim by Three.js</title>
|
| 6 |
+
<style>
|
| 7 |
+
body { margin: 0; background-color: #87CEEB; } /* Sky blue */
|
| 8 |
+
canvas { display: block; }
|
| 9 |
+
</style>
|
| 10 |
</head>
|
| 11 |
<body>
|
| 12 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
|
| 13 |
+
<script>
|
| 14 |
+
// SET UP SCENE, CAMERA, RENDERER
|
| 15 |
+
var scene = new THREE.Scene();
|
| 16 |
+
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 10000);
|
| 17 |
+
var renderer = new THREE.WebGLRenderer();
|
| 18 |
+
renderer.setSize(window.innerWidth, window.innerHeight);
|
| 19 |
+
document.body.appendChild(renderer.domElement);
|
| 20 |
|
| 21 |
+
// GENERATE SIMPLE TERRAIN (a big flat plane)
|
| 22 |
+
var terrainGeo = new THREE.PlaneGeometry(1000, 1000, 100, 100); // 1km x 1km
|
| 23 |
+
var terrainMat = new THREE.MeshLambertMaterial({color: 0x228B22}); // Forest green
|
| 24 |
+
var terrain = new THREE.Mesh(terrainGeo, terrainMat);
|
| 25 |
+
terrain.rotation.x = -Math.PI / 2; // Lay it flat
|
| 26 |
+
terrain.position.y = -50; // Sink it a bit so plane starts "on ground"
|
| 27 |
+
scene.add(terrain);
|
| 28 |
|
| 29 |
+
// GENERATE SIMPLE AIRPLANE (just some colored cubes + lines, lol what a plane)
|
| 30 |
+
var planeGeo = new THREE.BoxGeometry(10, 2, 5); // fuselage
|
| 31 |
+
var planeMat = new THREE.MeshLambertMaterial({color: 0xFF9900}); // Orange
|
| 32 |
+
var plane = new THREE.Mesh(planeGeo, planeMat);
|
| 33 |
+
var wingGeo = new THREE.BoxGeometry(15, 0.5, 2);
|
| 34 |
+
var wingMat = new THREE.MeshLambertMaterial({color: 0xFFFFFF}); // White
|
| 35 |
+
var leftWing = new THREE.Mesh(wingGeo, wingMat);
|
| 36 |
+
leftWing.position.x = -7.5;
|
| 37 |
+
leftWing.position.y = 1;
|
| 38 |
+
plane.add(leftWing);
|
| 39 |
+
var rightWing = leftWing.clone();
|
| 40 |
+
rightWing.position.x *= -1;
|
| 41 |
+
plane.add(rightWing);
|
| 42 |
+
var tailGeo = new THREE.BoxGeometry(2, 4, 0.5);
|
| 43 |
+
var tailMat = new THREE.MeshLambertMaterial({color: 0xFF0000}); // Red
|
| 44 |
+
var tail = new THREE.Mesh(tailGeo, tailMat);
|
| 45 |
+
tail.position.z = -5;
|
| 46 |
+
tail.position.y = 2;
|
| 47 |
+
plane.add(tail);
|
| 48 |
+
var cockpitGeo = new THREE.SphereGeometry(1, 16, 16);
|
| 49 |
+
var cockpitMat = new THREE.MeshLambertMaterial({color: 0x444444}); // Dark gray
|
| 50 |
+
var cockpit = new THREE.Mesh(cockpitGeo, cockpitMat);
|
| 51 |
+
cockpit.position.z = 4;
|
| 52 |
+
plane.add(cockpit);
|
| 53 |
+
scene.add(plane);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
|
| 55 |
+
// CAMERA RIG: attach camera to plane (like we're sitting in cockpit)
|
| 56 |
+
camera.position.set(0, 2, -10); // behind & above cockpit
|
| 57 |
+
plane.add(camera); // now cam moves with plane!
|
|
|
|
|
|
|
|
|
|
| 58 |
|
| 59 |
+
// LIGHTING (simple sun + ambient so we can see stuff)
|
| 60 |
+
var sunLight = new THREE.DirectionalLight(0xFFFFFF, 1);
|
| 61 |
+
sunLight.position.set(100, 200, 50);
|
| 62 |
+
scene.add(sunLight);
|
| 63 |
+
var ambLight = new THREE.AmbientLight(0x444444);
|
| 64 |
+
scene.add(ambLight);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
|
| 66 |
+
// PHYSICS VARIABLES & SETTINGS
|
| 67 |
+
var planePos = new THREE.Vector3(0, 0, 0); // start at origin (middle of terrain)
|
| 68 |
+
var planeVel = new THREE.Vector3(0, 0, 0); // not moving yet
|
| 69 |
+
var planeRot = new THREE.Euler(); // for pitch, yaw, roll
|
| 70 |
+
plane.rotation.setFromEuler(planeRot);
|
| 71 |
+
var throttle = 0; // 0 to 1
|
| 72 |
+
var pitchRate = 0; // -1 to 1 (up/down stick)
|
| 73 |
+
var yawRate = 0; // -1 to 1 (left/right stick)
|
| 74 |
+
var rollRate = 0; // -1 to 1 (ailerons)
|
| 75 |
+
var maxSpeed = 50; // units per sec (pretty fast)
|
| 76 |
+
var liftCoeff = 0.05; // magic number makes flying feel right
|
| 77 |
+
var gravity = new THREE.Vector3(0, -9.8, 0);
|
| 78 |
|
| 79 |
+
// CONTROLS (keyboard)
|
| 80 |
+
var keyState = {};
|
| 81 |
+
document.addEventListener('keydown', (k) => keyState[k.key] = true);
|
| 82 |
+
document.addEventListener('keyup', (k) => keyState[k.key] = false);
|
| 83 |
+
function getControlState() {
|
| 84 |
+
if (keyState['w'] || keyState['ArrowUp']) pitchRate = -0.5; else
|
| 85 |
+
if (keyState['s'] || keyState['ArrowDown']) pitchRate = 0.5; else
|
| 86 |
+
pitchRate = 0;
|
| 87 |
+
if (keyState['a'] || keyState['ArrowLeft']) yawRate = -0.5; else
|
| 88 |
+
if (keyState['d'] || keyState['ArrowRight']) yawRate = 0.5; else
|
| 89 |
+
yawRate = 0;
|
| 90 |
+
if (keyState['q']) rollRate = -0.5; else
|
| 91 |
+
if (keyState['e']) rollRate = 0.5; else
|
| 92 |
+
rollRate = 0;
|
| 93 |
+
if (keyState['Shift']) throttle = Math.min(throttle + 0.01, 1); else
|
| 94 |
+
if (keyState['Control']) throttle = Math.max(throttle - 0.01, 0);
|
| 95 |
+
}
|
| 96 |
|
| 97 |
+
// MAIN UPDATE LOOP
|
| 98 |
+
function animate(t) {
|
| 99 |
+
requestAnimationFrame(animate);
|
| 100 |
+
|
| 101 |
+
getControlState(); // read keyboard
|
| 102 |
+
|
| 103 |
+
// ROTATE PLANE (pitch, yaw from controls)
|
| 104 |
+
planeRot.x += pitchRate * 0.01; // integrate pitch
|
| 105 |
+
planeRot.y += yawRate * 0.01; // integrate yaw
|
| 106 |
+
planeRot.z += rollRate * 0.005; // a bit of roll (less intuitive)
|
| 107 |
+
plane.rotation.setFromEuler(planeRot);
|
| 108 |
+
|
| 109 |
+
// FORWARD VELOCITY (based on throttle & direction)
|
| 110 |
+
var forward = new THREE.Vector3(0, 0, 1);
|
| 111 |
+
forward.applyEuler(planeRot); // where are we pointing?
|
| 112 |
+
var desiredVel = forward.multiplyScalar(throttle * maxSpeed);
|
| 113 |
+
|
| 114 |
+
// LIFT FORCE (magic makes plane want to go up when moving fast)
|
| 115 |
+
var lift = forward.clone().multiplyScalar(liftCoeff * throttle * maxSpeed);
|
| 116 |
+
lift.y = Math.abs(lift.z); // up vector scales with forward speed
|
| 117 |
+
|
| 118 |
+
// SUM FORCES (thrust, lift, gravity)
|
| 119 |
+
var accel = desiredVel.clone().sub(planeVel).multiplyScalar(0.05); // gentle accel
|
| 120 |
+
accel.add(lift.multiplyScalar(0.01)); // tiny bit of lift helps
|
| 121 |
+
accel.add(gravity); // always pulled down
|
| 122 |
+
|
| 123 |
+
// INTEGRATE VELOCITY & POSITION
|
| 124 |
+
planeVel.add(accel);
|
| 125 |
+
planePos.add(planeVel.multiplyScalar(0.016)); // assume ~60fps = 0.016 s/step
|
| 126 |
+
|
| 127 |
+
// UPDATE PLANE POSITION
|
| 128 |
+
plane.position.copy(planePos);
|
| 129 |
+
|
| 130 |
+
// KEEP PLANE ABOVE TERRAIN (crude collision)
|
| 131 |
+
if (planePos.y < -45) { // hit ground?
|
| 132 |
+
planePos.y = -45; // stick to ground
|
| 133 |
+
planeVel.y = Math.max(planeVel.y, 0); // no bounce
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 134 |
}
|
| 135 |
+
|
| 136 |
+
renderer.render(scene, camera);
|
| 137 |
+
}
|
| 138 |
+
animate();
|
| 139 |
+
</script>
|
| 140 |
</body>
|
| 141 |
</html>
|