akhaliq HF Staff commited on
Commit
c1f40ba
·
verified ·
1 Parent(s): 8b6ea51

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +161 -161
index.html CHANGED
@@ -19,192 +19,192 @@ let renderer = new THREE.WebGLRenderer();
19
  renderer.setSize(window.innerWidth, window.innerHeight);
20
  document.body.appendChild(renderer.domElement);
21
 
22
- // SKY, SUN, AMBIENT LIGHT
23
- scene.background = new THREE.Color(0x87CEEB); // sky blue
24
- let sun = new THREE.DirectionalLight(0xffffff, 1);
25
- sun.position.set(10, 20, 10);
26
- scene.add(sun);
27
- let ambient = new THREE.AmbientLight(0x666666);
28
- scene.add(ambient);
 
 
 
 
 
 
 
 
 
 
29
 
30
- // CLOUDS (just a few big transparent billboards)
31
  function makeCloud(x, y, z) {
32
- let geo = new THREE.PlaneGeometry(5, 2);
33
- let mat = new THREE.MeshBasicMaterial({
34
- map: new THREE.CanvasTexture(makeCloudCanvas()),
35
- transparent: true,
36
- depthWrite: false
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  });
38
- let cloud = new THREE.Mesh(geo, mat);
39
  cloud.position.set(x, y, z);
40
- cloud.rotation.y = Math.random() * Math.PI * 2; // random rotation
41
  scene.add(cloud);
42
- // animate cloud floating
43
- let phase = Math.random() * Math.PI * 2;
44
- function animateCloud() {
45
- requestAnimationFrame(animateCloud);
46
- cloud.position.y = y + Math.sin(phase + Date.now() * 0.001) * 0.2;
47
- }
48
- animateCloud();
49
- }
50
- function makeCloudCanvas() {
51
- let canvas = document.createElement('canvas');
52
- canvas.width = 256;
53
- canvas.height = 128;
54
- let ctx = canvas.getContext('2d');
55
- ctx.fillStyle = 'white';
56
- ctx.beginPath();
57
- for (let i = 0; i < 10; i++) {
58
- ctx.arc(Math.random() * 256, Math.random() * 128, Math.random() * 20 + 10, 0, Math.PI * 2);
59
- }
60
- ctx.fill();
61
- return canvas;
62
  }
63
- makeCloud(10, 8, -20);
64
- makeCloud(-15, 7, -10);
65
- makeCloud(5, 9, -30);
66
 
67
- // MOUNTAINS (simple low-poly)
68
- let mountainGeo = new THREE.BufferGeometry();
69
- let mountainVerts = new Float32Array([
70
- 0, 0, 0, 5, 0, 0, 10, 0, 0,
71
- 5, 5, -5, 5, 5, 5, 0, 0, 0,
72
- 10, 0, 0, 15, 0, 0, 10, 5,-5,
73
- 10, 5,-5, 15, 0, 0, 10, 0, 5
 
 
 
 
 
 
 
 
 
 
 
74
  ]);
75
- mountainGeo.setAttribute('position', new THREE.BufferAttribute(mountainVerts, 3));
76
- let mountainMat = new THREE.MeshLambertMaterial({ color: 0x888888 });
77
- for (let i = 0; i < 5; i++) {
78
- let m = new THREE.Mesh(mountainGeo, mountainMat);
79
- m.position.x = -20 + i * 10;
80
- m.position.z = -40;
81
- m.scale.y = 2 + Math.random() * 2;
82
- scene.add(m);
83
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
- // ROAD (long thin box)
86
- let roadGeo = new THREE.BoxGeometry(1000, 0.1, 10);
87
- let roadMat = new THREE.MeshLambertMaterial({ color: 0x444444 });
88
- let road = new THREE.Mesh(roadGeo, roadMat);
89
- road.position.z = -50;
 
90
  scene.add(road);
91
- // dashed line in the middle of the road
92
- let lineGeo = new THREE.PlaneGeometry(1000, 0.2);
93
- let lineMat = new THREE.MeshBasicMaterial({ color: 'yellow' });
94
- let line = new THREE.Mesh(lineGeo, lineMat);
95
- line.position.z = -50;
96
- line.position.y = 0.11; // on top of road
97
- line.rotation.x = -Math.PI / 2;
98
- scene.add(line);
99
- // make dashes (ugly simple way)
100
- for (let d = -500; d < 500; d += 20) {
101
- let dash = new THREE.Mesh(new THREE.PlaneGeometry(5, 0.2), lineMat);
102
- dash.position.z = -50;
103
- dash.position.x = d;
104
- dash.position.y = 0.11;
105
- dash.rotation.x = -Math.PI / 2;
106
- scene.add(dash);
107
- }
108
 
109
- // TREES (green cylinders with sphere tops)
110
  function makeTree(x, z) {
111
- let trunk = new THREE.Mesh(new THREE.CylinderGeometry(0.5, 0.5, 2), new THREE.MeshLambertMaterial({ color: 0x663300 }));
112
- trunk.position.y = 1;
113
- trunk.position.x = x;
114
- trunk.position.z = z;
115
- let leaf = new THREE.Mesh(new THREE.SphereGeometry(1.5), new THREE.MeshLambertMaterial({ color: 0x00CC00 }));
116
- leaf.position.y = 3.5;
117
- leaf.position.x = x;
118
- leaf.position.z = z;
 
 
119
  scene.add(trunk);
120
- scene.add(leaf);
121
  }
122
- // put trees along road sides
123
- for (let z = -40; z > -200; z -= 10) {
124
- makeTree(-5, z);
125
- makeTree(5, z);
126
  }
127
 
128
- // TRAIN (body is box, wheels circles, goes in circle)
129
- let trainBody = new THREE.Mesh(new THREE.BoxGeometry(4, 2, 2), new THREE.MeshLambertMaterial({ color: 'red' }));
130
- trainBody.position.y = 1;
131
- let trainWheel1 = new THREE.Mesh(new THREE.CylinderGeometry(0.5, 0.5, 1), new THREE.MeshLambertMaterial({ color: 'black' }));
132
- trainWheel1.rotation.z = Math.PI / 2;
133
- trainWheel1.position.x = -1.5;
134
- trainWheel1.position.y = 0.5;
135
- let trainWheel2 = trainWheel1.clone();
136
- trainWheel2.position.x = 1.5;
137
- trainBody.add(trainWheel1);
138
- trainBody.add(trainWheel2);
139
- scene.add(trainBody);
140
- trainBody.position.x = 20;
141
- let trainAngle = 0;
142
- function animateTrain() {
143
- requestAnimationFrame(animateTrain);
144
- trainAngle += 0.01;
145
- trainBody.position.x = 20 * Math.cos(trainAngle);
146
- trainBody.position.z = 20 * Math.sin(trainAngle);
147
- trainBody.rotation.y = trainAngle + Math.PI / 2;
148
  }
149
- animateTrain();
 
 
150
 
151
- // CAR (box body, sphere wheels, controllable)
152
- let carBody = new THREE.Mesh(new THREE.BoxGeometry(3, 1.5, 1.8), new THREE.MeshLambertMaterial({ color: 'blue' }));
153
- let carWheelGeo = new THREE.SphereGeometry(0.4);
154
- let carWheelFL = new THREE.Mesh(carWheelGeo, new THREE.MeshLambertMaterial({ color: 'black' }));
155
- carWheelFL.position.set(-1.2, -0.5, 0.8);
156
- let carWheelFR = carWheelFL.clone();
157
- carWheelFR.position.x = 1.2;
158
- let carWheelBL = carWheelFL.clone();
159
- carWheelBL.position.z = -0.8;
160
- let carWheelBR = carWheelFR.clone();
161
- carWheelBR.position.z = -0.8;
162
- carBody.add(carWheelFL);
163
- carBody.add(carWheelFR);
164
- carBody.add(carWheelBL);
165
- carBody.add(carWheelBR);
166
- scene.add(carBody);
167
- carBody.position.set(0, 0.8, 0); // start pos
168
- let carSpeed = 0;
169
- let carAngle = 0;
170
- let keys = { ArrowUp: false, ArrowDown: false, ArrowLeft: false, ArrowRight: false,
171
- KeyW: false, KeyS: false, KeyA: false, KeyD: false };
172
- document.addEventListener('keydown', e => {
173
- if (e.code in keys) keys[e.code] = true;
174
- });
175
- document.addEventListener('keyup', e => {
176
- if (e.code in keys) keys[e.code] = false;
177
- });
178
- function updateCar() {
179
- if (keys.ArrowUp || keys.KeyW) carSpeed += 0.01;
180
- if (keys.ArrowDown || keys.KeyS) carSpeed -= 0.01;
181
- if (keys.ArrowLeft || keys.KeyA) carAngle -= 0.05;
182
- if (keys.ArrowRight || keys.KeyD) carAngle += 0.05;
183
- carSpeed *= 0.98; // friction
184
- carBody.position.x += Math.sin(carAngle) * carSpeed;
185
- carBody.position.z += Math.cos(carAngle) * carSpeed;
186
- carBody.rotation.y = -carAngle;
187
- // keep camera behind car
188
- camera.position.x = carBody.position.x - Math.sin(carAngle) * 5;
189
- camera.position.z = carBody.position.z - Math.cos(carAngle) * 5;
190
- camera.position.y = 3;
191
- camera.lookAt(carBody.position);
192
  }
 
 
 
193
 
194
- // MAIN LOOP
 
 
 
195
  function animate() {
196
  requestAnimationFrame(animate);
197
- updateCar();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
  renderer.render(scene, camera);
199
  }
200
  animate();
201
-
202
- // resize handling
203
- window.addEventListener('resize', () => {
204
- camera.aspect = window.innerWidth / window.innerHeight;
205
- camera.updateProjectionMatrix();
206
- renderer.setSize(window.innerWidth, window.innerHeight);
207
- });
208
  </script>
209
  </body>
210
  </html>
 
19
  renderer.setSize(window.innerWidth, window.innerHeight);
20
  document.body.appendChild(renderer.domElement);
21
 
22
+ // SKYBOX / BACKGROUND (just a simple gradient sky, no cube maps today)
23
+ let skyGeom = new THREE.SphereGeometry(500, 32, 32);
24
+ let skyMat = new THREE.MeshBasicMaterial({
25
+ map: new THREE.CanvasTexture((function(){
26
+ let c = document.createElement('canvas'), ctx = c.getContext('2d');
27
+ c.width = c.height = 256;
28
+ let grd = ctx.createLinearGradient(0, 0, 0, 256);
29
+ grd.addColorStop(0, '#87CEEB'); // light sky blue top
30
+ grd.addColorStop(1, '#4682B4'); // steel blue bottom
31
+ ctx.fillStyle = grd;
32
+ ctx.fillRect(0, 0, 256, 256);
33
+ return c;
34
+ })()),
35
+ side: THREE.BackSide
36
+ });
37
+ let sky = new THREE.Mesh(skyGeom, skyMat);
38
+ scene.add(sky);
39
 
40
+ // CLOUDS (just a few puffy billow-y things using transparent textures)
41
  function makeCloud(x, y, z) {
42
+ let cloudGeo = new THREE.SphereGeometry(10 + Math.random() * 5, 16, 16);
43
+ let cloudMat = new THREE.MeshBasicMaterial({
44
+ color: 0xffffff,
45
+ opacity: Math.random() * 0.3 + 0.2,
46
+ transparent: true,
47
+ map: new THREE.CanvasTexture((function(){
48
+ let c = document.createElement('canvas'), ctx = c.getContext('2d');
49
+ c.width = c.height = 64;
50
+ ctx.fillStyle = 'white';
51
+ ctx.beginPath(); ctx.arc(32, 32, 28, 0, Math.PI * 2); ctx.fill();
52
+ // make edges puffy/feathered
53
+ let gd = ctx.createRadialGradient(32, 32, 10, 32, 32, 28);
54
+ gd.addColorStop(0, 'rgba(255,255,255,1)');
55
+ gd.addColorStop(0.7, 'rgba(255,255,255,0.3)');
56
+ gd.addColorStop(1, 'rgba(255,255,255,0)');
57
+ ctx.fillStyle = gd;
58
+ ctx.fillRect(0, 0, 64, 64);
59
+ return c;
60
+ })())
61
  });
62
+ let cloud = new THREE.Mesh(cloudGeo, cloudMat);
63
  cloud.position.set(x, y, z);
 
64
  scene.add(cloud);
65
+ return cloud;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  }
67
+ let clouds = [];
68
+ for (let i = 0; i < 10; i++) clouds.push(makeCloud(Math.random() * 200 - 100, 30 + Math.random() * 10, Math.random() * 200 - 100));
 
69
 
70
+ // MOUNTAINS (simple low-poly with vertex colors)
71
+ let mountainGeom = new THREE.BufferGeometry();
72
+ let mVerts = new Float32Array([
73
+ 0, 0, 0,
74
+ 50, 0, 0,
75
+ 25, 40, 0,
76
+
77
+ 50, 0, 0,
78
+ 100, 0, 0,
79
+ 75, 40, 0,
80
+
81
+ 0, 0, 0,
82
+ 0, 0, 50,
83
+ 25, 40, 25,
84
+
85
+ 100, 0, 0,
86
+ 100, 0, 50,
87
+ 75, 40, 25,
88
  ]);
89
+ let mColors = new Float32Array([
90
+ 0.5, 0.4, 0.3, // brown base
91
+ 0.5, 0.4, 0.3,
92
+ 0.7, 0.6, 0.5, // beige peak
93
+
94
+ 0.5, 0.4, 0.3,
95
+ 0.5, 0.4, 0.3,
96
+ 0.7, 0.6, 0.5,
97
+
98
+ 0.5, 0.4, 0.3,
99
+ 0.5, 0.4, 0.3,
100
+ 0.7, 0.6, 0.5,
101
+
102
+ 0.5, 0.4, 0.3,
103
+ 0.5, 0.4, 0.3,
104
+ 0.7, 0.6, 0.5,
105
+ ]);
106
+ mountainGeom.setAttribute('position', new THREE.BufferAttribute(mVerts, 3));
107
+ mountainGeom.setAttribute('color', new THREE.BufferAttribute(mColors, 3));
108
+ let mountainMat = new THREE.MeshBasicMaterial({ vertexColors: true });
109
+ let mountains = new THREE.Mesh(mountainGeom, mountainMat);
110
+ mountains.scale.set(4, 4, 4); // bigger
111
+ mountains.position.z = -100;
112
+ scene.add(mountains);
113
 
114
+ // ROAD (just a long thin plane)
115
+ let roadGeom = new THREE.PlaneGeometry(200, 10);
116
+ let roadMat = new THREE.MeshBasicMaterial({ color: 0x444444 });
117
+ let road = new THREE.Mesh(roadGeom, roadMat);
118
+ road.rotation.x = -Math.PI / 2; // flat on ground
119
+ road.position.y = -0.1; // under car wheels
120
  scene.add(road);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
 
122
+ // TREES (simple green cones)
123
  function makeTree(x, z) {
124
+ let treeGeo = new THREE.ConeGeometry(4, 10);
125
+ let treeMat = new THREE.MeshBasicMaterial({ color: 0x228B22 }); // forestgreen
126
+ let tree = new THREE.Mesh(treeGeo, treeMat);
127
+ tree.position.set(x, 5, z); // half-height up so it sits on ground
128
+ scene.add(tree);
129
+ // quick 'n' dirty trunk
130
+ let trunkGeo = new THREE.CylinderGeometry(1, 1, 2);
131
+ let trunkMat = new THREE.MeshBasicMaterial({ color: 0x964B00 }); // brown
132
+ let trunk = new THREE.Mesh(trunkGeo, trunkMat);
133
+ trunk.position.set(x, 1, z);
134
  scene.add(trunk);
 
135
  }
136
+ for (let i = -5; i <= 5; i++) {
137
+ makeTree(i * 15, -50); // left side trees
138
+ makeTree(i * 15, 50); // right side trees
 
139
  }
140
 
141
+ // CAR (just a box with wheels)
142
+ let carBodyGeom = new THREE.BoxGeometry(10, 4, 6);
143
+ let carBodyMat = new THREE.MeshBasicMaterial({ color: 0xff0000 }); // red
144
+ let car = new THREE.Mesh(carBodyGeom, carBodyMat);
145
+ car.position.y = 2; // up off ground
146
+
147
+ let wheelGeo = new THREE.CylinderGeometry(1.5, 1.5, 1);
148
+ let wheelMat = new THREE.MeshBasicMaterial({ color: 0x333333 });
149
+ function makeWheel(x, z) {
150
+ let wheel = new THREE.Mesh(wheelGeo, wheelMat);
151
+ wheel.rotation.x = Math.PI / 2; // roll it
152
+ wheel.position.set(x, 0.5, z);
153
+ car.add(wheel);
 
 
 
 
 
 
 
154
  }
155
+ makeWheel(-4, -2); makeWheel( 4, -2); // front wheels
156
+ makeWheel(-4, 2); makeWheel( 4, 2); // rear wheels
157
+ scene.add(car);
158
 
159
+ // TRAIN (just a long box with wheels, moving in circle)
160
+ let trainBodyGeom = new THREE.BoxGeometry(30, 4, 6);
161
+ let trainBodyMat = new THREE.MeshBasicMaterial({ color: 0x0000ff }); // blue
162
+ let train = new THREE.Mesh(trainBodyGeom, trainBodyMat);
163
+ train.position.y = 2;
164
+ train.position.x = 80; // start off to side
165
+ let trainWheelGeo = new THREE.CylinderGeometry(2, 2, 1.5);
166
+ let trainWheelMat = new THREE.MeshBasicMaterial({ color: 0x333333 });
167
+ function makeTrainWheel(x, z) {
168
+ let wheel = new THREE.Mesh(trainWheelGeo, trainWheelMat);
169
+ wheel.rotation.x = Math.PI / 2;
170
+ wheel.position.set(x, 0.5, z);
171
+ train.add(wheel);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  }
173
+ makeTrainWheel(-12, -2.5); makeTrainWheel( 12, -2.5);
174
+ makeTrainWheel(-12, 2.5); makeTrainWheel( 12, 2.5);
175
+ scene.add(train);
176
 
177
+ // ANIMATION / PHYSICS
178
+ let carSpeed = 0.5;
179
+ let trainAngle = 0;
180
+ let clock = new THREE.Clock();
181
  function animate() {
182
  requestAnimationFrame(animate);
183
+
184
+ // move car forward
185
+ car.position.z += carSpeed;
186
+ if (car.position.z > 100) car.position.z = -100; // loop road
187
+
188
+ // move train in circle (easy parametric equation)
189
+ trainAngle += 0.01;
190
+ train.position.x = Math.cos(trainAngle) * 80;
191
+ train.position.z = Math.sin(trainAngle) * 80;
192
+ train.rotation.y = trainAngle + Math.PI / 2; // face direction of travel
193
+
194
+ // bob clouds gently up/down
195
+ clouds.forEach(cloud => {
196
+ cloud.position.y = 30 + Math.sin(clock.getElapsedTime() + cloud.position.x * 0.01) * 2;
197
+ });
198
+
199
+ // keep camera just behind car
200
+ camera.position.x = car.position.x;
201
+ camera.position.z = car.position.z - 15;
202
+ camera.position.y = 8; // nice view height
203
+ camera.lookAt(car.position.x, 2, car.position.z); // look at car
204
+
205
  renderer.render(scene, camera);
206
  }
207
  animate();
 
 
 
 
 
 
 
208
  </script>
209
  </body>
210
  </html>