58 lines
1.9 KiB
JavaScript
58 lines
1.9 KiB
JavaScript
// Arcade car physics. Heading h faces world direction (cos h, 0, -sin h), matching Three's rotation.y.
|
|
// maxSpeed 55.6 m/s is 200 km/h.
|
|
export const CAR = {
|
|
maxSpeed: 55.6,
|
|
maxReverse: 6,
|
|
accel: 9.5,
|
|
brake: 14,
|
|
drag: 1.6,
|
|
maxSteer: 0.55,
|
|
wheelBase: 2.7,
|
|
radius: 1.6,
|
|
};
|
|
/**
|
|
* Creates car resources for the game.
|
|
* @param {*} x - x.
|
|
* @param {*} z - z.
|
|
* @param {*} heading - heading.
|
|
* @returns {*} Operation result, when applicable.
|
|
*/
|
|
export function createCar(x, z, heading = 0) {
|
|
return {
|
|
x,
|
|
z,
|
|
heading,
|
|
speed: 0,
|
|
steer: 0,
|
|
};
|
|
}
|
|
/**
|
|
* Runs the step car operation for this subsystem.
|
|
* @param {*} car - car.
|
|
* @param {*} options1 - Operation options.
|
|
* @param {*} dt - dt.
|
|
* @returns {*} Operation result, when applicable.
|
|
*/
|
|
export function stepCar(car, { throttle = 0, steer = 0, handbrake = false }, dt) {
|
|
car.steer += (steer * CAR.maxSteer - car.steer) * Math.min(1, dt * 6);
|
|
if (throttle > 0) car.speed += (car.speed < 0 ? CAR.brake : CAR.accel) * throttle * dt;
|
|
else if (throttle < 0)
|
|
car.speed += (car.speed > 0 ? -CAR.brake : -CAR.accel * 0.6) * -throttle * dt;
|
|
else car.speed -= Math.sign(car.speed) * Math.min(Math.abs(car.speed), CAR.drag * dt);
|
|
if (handbrake)
|
|
car.speed -= Math.sign(car.speed) * Math.min(Math.abs(car.speed), CAR.brake * 1.4 * dt);
|
|
car.speed = Math.max(-CAR.maxReverse, Math.min(CAR.maxSpeed, car.speed));
|
|
// High speed narrows the usable steering angle so the car stays controllable.
|
|
const steerAngle = car.steer / (1 + Math.abs(car.speed) * 0.045);
|
|
car.heading -= ((car.speed * Math.tan(steerAngle)) / CAR.wheelBase) * dt;
|
|
car.x += Math.cos(car.heading) * car.speed * dt;
|
|
car.z -= Math.sin(car.heading) * car.speed * dt;
|
|
return car;
|
|
}
|
|
/**
|
|
* Runs the kmh operation for this subsystem.
|
|
* @param {*} car - car.
|
|
* @returns {*} Operation result, when applicable.
|
|
*/
|
|
export const kmh = (car) => Math.round(Math.abs(car.speed) * 3.6);
|