Refactor Player Movement Logic
- Updated Player class to use maxSpeed, acceleration, and deceleration for smoother movement. - Introduced velocity vector for more responsive control and smoother diagonal movement. - Enhanced update method to calculate target velocity based on input and apply easing for acceleration and deceleration. - Implemented boundary checks to stop movement when hitting the edges of the play area. This change improves the overall player control experience, making movement more fluid and intuitive.
This commit is contained in:
parent
dfe87d63cc
commit
257cd017af
1 changed files with 49 additions and 8 deletions
57
index.html
57
index.html
|
|
@ -153,7 +153,10 @@
|
|||
class Player extends GameObject {
|
||||
constructor(scene, groundSize) {
|
||||
super(scene, groundSize);
|
||||
this.speed = 0.15;
|
||||
this.maxSpeed = 0.15;
|
||||
this.acceleration = 0.08;
|
||||
this.deceleration = 0.12;
|
||||
this.velocity = new THREE.Vector3(0, 0, 0);
|
||||
}
|
||||
|
||||
createMesh() {
|
||||
|
|
@ -170,31 +173,69 @@
|
|||
}
|
||||
|
||||
initialize() {
|
||||
// Initialize velocity (needed because initialize is called from parent constructor)
|
||||
if (!this.velocity) {
|
||||
this.velocity = new THREE.Vector3(0, 0, 0);
|
||||
}
|
||||
this.reset();
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.setPosition(0, 0.5, 0);
|
||||
this.mesh.rotation.y = 0;
|
||||
if (this.velocity) {
|
||||
this.velocity.set(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
update(keys) {
|
||||
const moveVector = new THREE.Vector3();
|
||||
// Calculate target velocity based on input
|
||||
const targetVelocity = new THREE.Vector3(0, 0, 0);
|
||||
|
||||
if (keys['w'] || keys['arrowup']) moveVector.z -= this.speed;
|
||||
if (keys['s'] || keys['arrowdown']) moveVector.z += this.speed;
|
||||
if (keys['a'] || keys['arrowleft']) moveVector.x -= this.speed;
|
||||
if (keys['d'] || keys['arrowright']) moveVector.x += this.speed;
|
||||
if (keys['w'] || keys['arrowup']) targetVelocity.z -= this.maxSpeed;
|
||||
if (keys['s'] || keys['arrowdown']) targetVelocity.z += this.maxSpeed;
|
||||
if (keys['a'] || keys['arrowleft']) targetVelocity.x -= this.maxSpeed;
|
||||
if (keys['d'] || keys['arrowright']) targetVelocity.x += this.maxSpeed;
|
||||
|
||||
this.mesh.position.add(moveVector);
|
||||
// Smoothly interpolate velocity towards target
|
||||
const isMoving = targetVelocity.length() > 0;
|
||||
const accelRate = isMoving ? this.acceleration : this.deceleration;
|
||||
|
||||
// Calculate velocity difference for each axis
|
||||
const velDiffX = targetVelocity.x - this.velocity.x;
|
||||
const velDiffZ = targetVelocity.z - this.velocity.z;
|
||||
|
||||
// Apply easing to each axis independently for smoother diagonal movement
|
||||
if (Math.abs(velDiffX) > 0.001) {
|
||||
this.velocity.x += velDiffX * accelRate;
|
||||
} else {
|
||||
this.velocity.x = targetVelocity.x;
|
||||
}
|
||||
|
||||
if (Math.abs(velDiffZ) > 0.001) {
|
||||
this.velocity.z += velDiffZ * accelRate;
|
||||
} else {
|
||||
this.velocity.z = targetVelocity.z;
|
||||
}
|
||||
|
||||
// Apply velocity to position
|
||||
this.mesh.position.add(this.velocity);
|
||||
|
||||
// Boundary checks
|
||||
const boundary = this.groundSize / 2 - 0.5;
|
||||
this.mesh.position.x = Math.max(-boundary, Math.min(boundary, this.mesh.position.x));
|
||||
this.mesh.position.z = Math.max(-boundary, Math.min(boundary, this.mesh.position.z));
|
||||
|
||||
// Stop velocity if hitting boundary
|
||||
if (Math.abs(this.mesh.position.x) >= boundary) {
|
||||
this.velocity.x = 0;
|
||||
}
|
||||
if (Math.abs(this.mesh.position.z) >= boundary) {
|
||||
this.velocity.z = 0;
|
||||
}
|
||||
|
||||
// Rotate player based on movement
|
||||
if (moveVector.length() > 0) {
|
||||
if (this.velocity.length() > 0.01) {
|
||||
this.mesh.rotation.y += 0.1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue