three-game-engine
Version:
Simple light-weight game engine using three.js, three-mesh-ui and rapier
69 lines (68 loc) • 3.37 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
const THREE = require("three");
const rapier3d_compat_1 = require("@dimforge/rapier3d-compat");
const CharacterController_1 = require("./CharacterController");
const RigidBodyComponent_1 = require("../components/RigidBodyComponent");
const defaultCapsuleOptions = {
halfHeight: 0.45,
radius: 0.4,
density: 500
};
class DynamicCharacterController extends CharacterController_1.default {
constructor(parent, options, controllerOptions) {
super(parent, {
rigidBody: {
type: 'dynamic',
colliders: [
{ type: 'capsule', ...Object.assign({}, defaultCapsuleOptions, ((controllerOptions || {}).capsule || {})) }
],
enabledRotations: { x: false, y: true, z: false }
},
...options // merge with any passed in GameObjectOptions
}, controllerOptions);
this.jumpImpulse = 1300;
}
afterLoaded() {
}
beforeRender({ deltaTimeInSec, time }) {
const inputManager = this.getScene().game.inputManager;
const keyboard = inputManager.keyboardHandler;
const rigidBodyComponent = this.getComponent(RigidBodyComponent_1.default);
const rapierRigidBody = rigidBodyComponent.getRapierRigidBody();
const yawAngle = this.getDesiredYaw();
const pitchAngle = this.getDesiredPitch();
const desiredRotation = new THREE.Quaternion();
desiredRotation.setFromEuler(new THREE.Euler(pitchAngle, yawAngle, 0, 'YXZ'));
rapierRigidBody.setRotation(desiredRotation, true);
const desiredMovementVector = this.getDesiredTranslation(deltaTimeInSec);
// Make it so "forward" is in the same direction as where the character faces
desiredMovementVector.applyQuaternion(desiredRotation);
desiredMovementVector.multiplyScalar(400);
rapierRigidBody.applyImpulse(desiredMovementVector, true);
// Jump mechanics
if (keyboard.isKeyDown(' ')) {
const timeSinceLastJump = time - this.lastJumpTime;
if (timeSinceLastJump > this.controllerOptions.jumpCooldown) {
const rapierWorld = this.getScene().getRapierWorld();
const currentPosition = rapierRigidBody.translation();
// Point just below the capsulate collider
const rayOrigin = {
x: currentPosition.x,
y: currentPosition.y - this.controllerOptions.capsule.halfHeight - this.controllerOptions.capsule.radius - 0.05,
z: currentPosition.z
};
const rayDirection = { x: 0, y: -0.1, z: 0 }; // downwards
const ray = new rapier3d_compat_1.default.Ray(rayOrigin, rayDirection);
const groundHit = rapierWorld.castRay(ray, 0.01, true);
const isFalling = rapierRigidBody.linvel().y < -0.1;
if (groundHit && !isFalling) {
// There is ground below the character, so the player can indeed initate a jump
rapierRigidBody.applyImpulse(new THREE.Vector3(0, this.jumpImpulse, 0), true);
this.lastJumpTime = time;
}
}
}
}
}
exports.default = DynamicCharacterController;
;