Spaces:
Running
Running
Update index.html
Browse files- index.html +48 -11
index.html
CHANGED
|
@@ -371,7 +371,7 @@
|
|
| 371 |
|
| 372 |
// Use the updated getRoadPropertiesAtZ function for consistent elevation
|
| 373 |
const { roadY: elevation_val } = getRoadPropertiesAtZ(worldZ);
|
| 374 |
-
vertices.setY(i, elevation_val);
|
| 375 |
}
|
| 376 |
roadGeometry.attributes.position.needsUpdate = true;
|
| 377 |
roadGeometry.computeVertexNormals();
|
|
@@ -382,6 +382,24 @@
|
|
| 382 |
road.receiveShadow = true;
|
| 383 |
scene.add(road);
|
| 384 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 385 |
const centerLineGeometry = new THREE.PlaneGeometry(0.1, roadLength, 1, 200);
|
| 386 |
centerLineGeometry.rotateX(-Math.PI / 2);
|
| 387 |
|
|
@@ -392,7 +410,7 @@
|
|
| 392 |
const curve_val = Math.sin(localZ * 0.005) * 15;
|
| 393 |
lineVertices.setX(i, lineVertices.getX(i) + curve_val);
|
| 394 |
const { roadY: elevation_val } = getRoadPropertiesAtZ(worldZ);
|
| 395 |
-
lineVertices.setY(i, elevation_val + 0.
|
| 396 |
}
|
| 397 |
centerLineGeometry.attributes.position.needsUpdate = true;
|
| 398 |
centerLineGeometry.computeVertexNormals();
|
|
@@ -550,8 +568,10 @@
|
|
| 550 |
const car = new THREE.Mesh(new THREE.BoxGeometry(1.8,1,3.8), new THREE.MeshStandardMaterial({color:carColors[Math.floor(Math.random()*carColors.length)]}));
|
| 551 |
car.castShadow = true;
|
| 552 |
const {roadY,roadCurve} = getRoadPropertiesAtZ(worldZPosition);
|
|
|
|
|
|
|
| 553 |
const laneXOffset = isOncoming ? (roadWidth/4 + 0.25) : (-roadWidth/4 - 0.25);
|
| 554 |
-
car.position.set(roadCurve+laneXOffset, 1+roadY, worldZPosition);
|
| 555 |
car.rotation.y = isOncoming ? Math.PI : 0;
|
| 556 |
scene.add(car);
|
| 557 |
const headlightMat = new THREE.MeshBasicMaterial({color:0xFFFFFF});
|
|
@@ -855,8 +875,12 @@
|
|
| 855 |
else { if(isGrounded)speed*=0.98; else speed*=0.995; if(Math.abs(speed)<0.05)speed=0; }
|
| 856 |
|
| 857 |
if((keys[' ']||keys.j)&&isGrounded&&Math.abs(speed)>10){
|
| 858 |
-
|
| 859 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 860 |
}
|
| 861 |
|
| 862 |
speed=Math.max(-maxSpeed/2,Math.min(maxSpeed,speed));
|
|
@@ -898,7 +922,8 @@
|
|
| 898 |
if (distToRampZ < ramp.length / 2 && distToRampX < ramp.width / 2 && playerCar.position.y < ramp.mesh.position.y + ramp.height + carEffectiveRadius) {
|
| 899 |
onRamp = true;
|
| 900 |
if (!ramp.used && isGrounded) { // Only trigger jump once and if grounded
|
| 901 |
-
|
|
|
|
| 902 |
isGrounded = false;
|
| 903 |
ramp.used = true; // Mark ramp as used for this jump
|
| 904 |
showMessage("Ramp Jump!", 2);
|
|
@@ -909,7 +934,6 @@
|
|
| 909 |
}
|
| 910 |
});
|
| 911 |
|
| 912 |
-
|
| 913 |
if (isGrounded && !onRamp) { // Don't apply ground physics if on ramp and about to jump
|
| 914 |
const elevationChange = groundHeightAtCar - lastRoadY;
|
| 915 |
suspensionCompression = -elevationChange * suspensionStrength;
|
|
@@ -925,11 +949,24 @@
|
|
| 925 |
playerCar.position.y = groundHeightAtCar + carEffectiveRadius;
|
| 926 |
isGrounded = true;
|
| 927 |
const impactForce = Math.abs(velocity.y);
|
| 928 |
-
velocity.y = 0;
|
| 929 |
-
|
| 930 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 931 |
suspensionCompression = Math.min(impactForce*0.2,0.4);
|
| 932 |
-
} else {
|
|
|
|
|
|
|
|
|
|
| 933 |
}
|
| 934 |
}
|
| 935 |
lastRoadY = groundHeightAtCar;
|
|
|
|
| 371 |
|
| 372 |
// Use the updated getRoadPropertiesAtZ function for consistent elevation
|
| 373 |
const { roadY: elevation_val } = getRoadPropertiesAtZ(worldZ);
|
| 374 |
+
vertices.setY(i, elevation_val + 0.1); // Lift road surface slightly above base terrain
|
| 375 |
}
|
| 376 |
roadGeometry.attributes.position.needsUpdate = true;
|
| 377 |
roadGeometry.computeVertexNormals();
|
|
|
|
| 382 |
road.receiveShadow = true;
|
| 383 |
scene.add(road);
|
| 384 |
|
| 385 |
+
// Create thicker road base to prevent water clipping
|
| 386 |
+
const roadBaseGeometry = new THREE.BoxGeometry(roadWidth, 0.5, roadLength);
|
| 387 |
+
const roadBaseMaterial = new THREE.MeshStandardMaterial({ color: 0x444444, roughness: 0.9 });
|
| 388 |
+
const roadBase = new THREE.Mesh(roadBaseGeometry, roadBaseMaterial);
|
| 389 |
+
|
| 390 |
+
// Position road base properly
|
| 391 |
+
const roadBaseVertices = roadBaseGeometry.attributes.position;
|
| 392 |
+
for (let i = 0; i < roadBaseVertices.count; i++) {
|
| 393 |
+
const localZ = roadBaseVertices.getZ(i);
|
| 394 |
+
const worldZ = localZ + roadLength / 2;
|
| 395 |
+
const { roadY } = getRoadPropertiesAtZ(worldZ);
|
| 396 |
+
roadBaseVertices.setY(i, roadBaseVertices.getY(i) + roadY - 0.2); // Position base below road surface
|
| 397 |
+
}
|
| 398 |
+
roadBaseGeometry.attributes.position.needsUpdate = true;
|
| 399 |
+
roadBase.position.z = roadLength / 2;
|
| 400 |
+
roadBase.receiveShadow = true;
|
| 401 |
+
scene.add(roadBase);
|
| 402 |
+
|
| 403 |
const centerLineGeometry = new THREE.PlaneGeometry(0.1, roadLength, 1, 200);
|
| 404 |
centerLineGeometry.rotateX(-Math.PI / 2);
|
| 405 |
|
|
|
|
| 410 |
const curve_val = Math.sin(localZ * 0.005) * 15;
|
| 411 |
lineVertices.setX(i, lineVertices.getX(i) + curve_val);
|
| 412 |
const { roadY: elevation_val } = getRoadPropertiesAtZ(worldZ);
|
| 413 |
+
lineVertices.setY(i, elevation_val + 0.12);
|
| 414 |
}
|
| 415 |
centerLineGeometry.attributes.position.needsUpdate = true;
|
| 416 |
centerLineGeometry.computeVertexNormals();
|
|
|
|
| 568 |
const car = new THREE.Mesh(new THREE.BoxGeometry(1.8,1,3.8), new THREE.MeshStandardMaterial({color:carColors[Math.floor(Math.random()*carColors.length)]}));
|
| 569 |
car.castShadow = true;
|
| 570 |
const {roadY,roadCurve} = getRoadPropertiesAtZ(worldZPosition);
|
| 571 |
+
|
| 572 |
+
// Fix lane positioning - oncoming cars should be on player's right side
|
| 573 |
const laneXOffset = isOncoming ? (roadWidth/4 + 0.25) : (-roadWidth/4 - 0.25);
|
| 574 |
+
car.position.set(roadCurve + laneXOffset, 1+roadY, worldZPosition);
|
| 575 |
car.rotation.y = isOncoming ? Math.PI : 0;
|
| 576 |
scene.add(car);
|
| 577 |
const headlightMat = new THREE.MeshBasicMaterial({color:0xFFFFFF});
|
|
|
|
| 875 |
else { if(isGrounded)speed*=0.98; else speed*=0.995; if(Math.abs(speed)<0.05)speed=0; }
|
| 876 |
|
| 877 |
if((keys[' ']||keys.j)&&isGrounded&&Math.abs(speed)>10){
|
| 878 |
+
// Speed-dependent jump height
|
| 879 |
+
jumpSpeed = Math.abs(speed); // Store speed when jumping
|
| 880 |
+
jumpForce = 0.8 + jumpSpeed * 0.04 + suspensionCompression * 6; // Reduced base jump
|
| 881 |
+
velocity.y = jumpForce;
|
| 882 |
+
isGrounded = false;
|
| 883 |
+
showMessage("Jumping!", 1);
|
| 884 |
}
|
| 885 |
|
| 886 |
speed=Math.max(-maxSpeed/2,Math.min(maxSpeed,speed));
|
|
|
|
| 922 |
if (distToRampZ < ramp.length / 2 && distToRampX < ramp.width / 2 && playerCar.position.y < ramp.mesh.position.y + ramp.height + carEffectiveRadius) {
|
| 923 |
onRamp = true;
|
| 924 |
if (!ramp.used && isGrounded) { // Only trigger jump once and if grounded
|
| 925 |
+
jumpSpeed = Math.abs(speed); // Store speed when hitting ramp
|
| 926 |
+
velocity.y = ramp.height * 1.2 + jumpSpeed * 0.08; // Speed-dependent ramp jump
|
| 927 |
isGrounded = false;
|
| 928 |
ramp.used = true; // Mark ramp as used for this jump
|
| 929 |
showMessage("Ramp Jump!", 2);
|
|
|
|
| 934 |
}
|
| 935 |
});
|
| 936 |
|
|
|
|
| 937 |
if (isGrounded && !onRamp) { // Don't apply ground physics if on ramp and about to jump
|
| 938 |
const elevationChange = groundHeightAtCar - lastRoadY;
|
| 939 |
suspensionCompression = -elevationChange * suspensionStrength;
|
|
|
|
| 949 |
playerCar.position.y = groundHeightAtCar + carEffectiveRadius;
|
| 950 |
isGrounded = true;
|
| 951 |
const impactForce = Math.abs(velocity.y);
|
| 952 |
+
velocity.y = 0;
|
| 953 |
+
|
| 954 |
+
// Check for successful landing bonuses
|
| 955 |
+
checkLandingBonus(impactForce);
|
| 956 |
+
|
| 957 |
+
airTime = 0;
|
| 958 |
+
// Speed-dependent landing damage
|
| 959 |
+
const speedFactor = Math.max(0.3, jumpSpeed / 45); // Reduce damage for slower jumps
|
| 960 |
+
const damageThreshold = 0.4 + (jumpSpeed / 45); // Higher threshold for faster jumps
|
| 961 |
+
|
| 962 |
+
if (impactForce > damageThreshold) {
|
| 963 |
+
const damage = Math.floor(impactForce * 5 * speedFactor); // Much reduced damage
|
| 964 |
+
decreaseHealth(damage, `Hard landing!`);
|
| 965 |
suspensionCompression = Math.min(impactForce*0.2,0.4);
|
| 966 |
+
} else {
|
| 967 |
+
suspensionCompression = Math.min(impactForce*0.1,0.1);
|
| 968 |
+
}
|
| 969 |
+
jumpSpeed = 0; // Reset jump speed after landing
|
| 970 |
}
|
| 971 |
}
|
| 972 |
lastRoadY = groundHeightAtCar;
|