import { Cube } from "./Cube.js"; import { Rotation } from "./utils.js"; import { jumpDemo } from "./Game.js"; export class Player extends Cube { constructor(color) { super(color, "assets/images/player.jpg"); this.data.position.x = -2; this.data.rotation.x = this.gameRotation; this.movementData = new Rotation(this.data.position); } /** * Play the player animation * @param {*} listEnnemies * @param {boolean} demo * @returns boolean if the player is alive or not */ animation = (listEnnemies, demo) => { if (demo) { listEnnemies.forEach((ennemy) => { const pos = ennemy.position.x - this.data.position.x; if (pos > 0 && pos < Math.random() * 1.5 + 0.5) { dispatchEvent(jumpDemo); } }); } // If we jump if (this.movementData.state) { // Rotation this.data.rotation.y -= this.movementData.rotationVelocity / 1.6; // If we're falling (2nd part of the jump) if (this.movementData.falling()) { // Gravity! this.data.position.y -= this.movementData.jumpVelocity; } else { // If we're jumping (1st part of the jump) : jumping this.data.position.y += this.movementData.jumpVelocity; // Check if the jump stop and we need to goes down if (this.data.position.y >= this.movementData.jump) { this.movementData.changeJump(this.movementData.default.y); } } // End of the rotation if (this.data.rotation.y <= this.movementData.rotation) { // Force the final rotation this.data.rotation.y = this.movementData.rotation; // Force the end of the jump this.data.position.y = this.movementData.default.y; // End this.movementData.changeState(); } } return !this.checkCollision(listEnnemies); }; /** * Handle player's input * @param {string} key key pressed */ controlUser = (key) => { if (key.code == "Space" && !this.movementData.state) { this.movementData.changeRotation( this.data.rotation.y - Math.PI / 2 ); this.movementData.changeJump( 3 * this.data.position.y + Math.PI / 2 ); this.movementData.changeState(); } }; /** * Check collisions with ennemies * @param {*} listEnnemies * @returns boolean */ checkCollision = (listEnnemies) => { for ( let vertexIndex = 0; vertexIndex < this.data.geometry.attributes.position.array.length; vertexIndex++ ) { // Retrieve the vertex from the player geometry const localVertex = new THREE.Vector3() .fromBufferAttribute( this.data.geometry.attributes.position, vertexIndex ) .clone(); // Apply the player matrix for the vector const globalVertex = localVertex.applyMatrix4(this.data.matrix); // Substract the position to obtain the position const directionVector = globalVertex.sub(this.data.position); // Create the raycaster for this vector from the player position const rc = new THREE.Raycaster( this.data.position, directionVector.clone().normalize() ); // Check if the raycaster hit ennemies const collisionResults = rc.intersectObjects(listEnnemies, false); if ( collisionResults.length > 0 && directionVector.length() < 1.5 && collisionResults[0].distance < directionVector.length() ) { // Yes some ennemies are in the way return true; } } // No ennemies found return false; }; }