Refactor Player Movement Logic
All checks were successful
Build and Publish Docker Image / Build and Validate (pull_request) Successful in 8s
Build and Publish Docker Image / Publish to Registry (pull_request) Has been skipped

- 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:
Juan Sebastián Montoya 2025-11-26 09:33:56 -05:00
parent dfe87d63cc
commit 257cd017af

View file

@ -153,7 +153,10 @@
class Player extends GameObject { class Player extends GameObject {
constructor(scene, groundSize) { constructor(scene, groundSize) {
super(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() { createMesh() {
@ -170,31 +173,69 @@
} }
initialize() { initialize() {
// Initialize velocity (needed because initialize is called from parent constructor)
if (!this.velocity) {
this.velocity = new THREE.Vector3(0, 0, 0);
}
this.reset(); this.reset();
} }
reset() { reset() {
this.setPosition(0, 0.5, 0); this.setPosition(0, 0.5, 0);
this.mesh.rotation.y = 0; this.mesh.rotation.y = 0;
if (this.velocity) {
this.velocity.set(0, 0, 0);
}
} }
update(keys) { 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['w'] || keys['arrowup']) targetVelocity.z -= this.maxSpeed;
if (keys['s'] || keys['arrowdown']) moveVector.z += this.speed; if (keys['s'] || keys['arrowdown']) targetVelocity.z += this.maxSpeed;
if (keys['a'] || keys['arrowleft']) moveVector.x -= this.speed; if (keys['a'] || keys['arrowleft']) targetVelocity.x -= this.maxSpeed;
if (keys['d'] || keys['arrowright']) moveVector.x += this.speed; 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 // Boundary checks
const boundary = this.groundSize / 2 - 0.5; const boundary = this.groundSize / 2 - 0.5;
this.mesh.position.x = Math.max(-boundary, Math.min(boundary, this.mesh.position.x)); 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)); 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 // Rotate player based on movement
if (moveVector.length() > 0) { if (this.velocity.length() > 0.01) {
this.mesh.rotation.y += 0.1; this.mesh.rotation.y += 0.1;
} }
} }