icy3dw/src/client/object/player.ts

142 lines
3.6 KiB
TypeScript
Raw Normal View History

2022-04-09 11:29:54 +00:00
import { IcyNetUser } from '../../common/types/user';
import { Socket } from 'socket.io-client';
import { PonyEntity } from './pony';
2022-04-10 08:33:52 +00:00
import { Scene, Vector2, Vector3 } from 'three';
2022-04-09 11:29:54 +00:00
export class Player extends PonyEntity {
public keydownMap: { [x: string]: boolean } = {};
private _prevKeydownMap: { [x: string]: boolean } = {};
/**
* Normal vector of the currently faced direction
*/
2022-04-10 08:33:52 +00:00
private _lookVector = new Vector3();
2022-04-09 11:29:54 +00:00
/**
* Direction of the current movement.
* X axis controls angular velocity, Y axis controls linear velocity direction by world coordinates.
*/
2022-04-10 08:33:52 +00:00
private _direction = new Vector2();
2022-04-09 11:29:54 +00:00
/**
* Joystick or other external movement usage.
*/
2022-04-10 08:33:52 +00:00
private _externalDirection = new Vector2();
2022-04-09 11:29:54 +00:00
/**
* Was external movement used this tick
*/
private _externalForce = false;
/**
* Was moving last tick
*/
private _wasMoving = false;
/**
* Was turning last tick
*/
private _wasTurning = false;
constructor(public user: IcyNetUser) {
super();
}
2022-04-10 08:33:52 +00:00
public static fromUser(user: IcyNetUser, scene: Scene): Player {
2022-04-09 11:29:54 +00:00
const entity = new Player(user);
entity.initialize();
scene.add(entity.container);
return entity;
}
initialize(): void {
super.initialize();
window.addEventListener('keydown', (e) => {
2022-04-09 15:09:11 +00:00
this.keydownMap[e.key.toLowerCase()] = true;
2022-04-09 11:29:54 +00:00
});
window.addEventListener('keyup', (e) => {
2022-04-09 15:09:11 +00:00
this.keydownMap[e.key.toLowerCase()] = false;
2022-04-09 11:29:54 +00:00
});
}
public createPacket(socket: Socket): void {
if (Object.keys(this.changes).length) {
socket.emit('move', this.changes);
this.changes = {};
}
}
public applyForce(vec: Vector2) {
this._externalDirection.copy(vec);
this._externalForce = true;
}
public moveCharacter(dt: number) {
2022-04-10 08:33:52 +00:00
const vector = new Vector2();
2022-04-09 11:29:54 +00:00
const wasExternalForce = this._externalForce;
this._externalForce = false;
if (wasExternalForce) {
vector.copy(this._externalDirection);
} else {
vector.copy(this._direction);
}
if (vector.x !== 0) {
2022-04-09 12:57:20 +00:00
this.angularVelocity.set(0, Math.PI * vector.x, 0);
2022-04-09 11:29:54 +00:00
this.changes.angular = this.angularVelocity.toArray();
2022-04-09 18:03:49 +00:00
2022-04-09 11:29:54 +00:00
this._wasTurning = true;
} else if (this._wasTurning && !wasExternalForce) {
this._wasTurning = false;
this.angularVelocity.set(0, 0, 0);
this.changes.angular = this.angularVelocity.toArray();
2022-04-09 18:03:49 +00:00
this.changes.rotation = this.container.rotation.toArray();
2022-04-09 11:29:54 +00:00
}
if (vector.y !== 0) {
2022-04-09 12:57:20 +00:00
this.velocity.copy(this._lookVector.clone().multiplyScalar(vector.y));
2022-04-09 11:29:54 +00:00
this.changes.velocity = this.velocity.toArray();
2022-04-09 18:03:49 +00:00
2022-04-09 11:29:54 +00:00
this._wasMoving = true;
2022-04-09 14:49:30 +00:00
this.setWalkAnimationState(1);
2022-04-09 11:29:54 +00:00
} else if (this._wasMoving && !wasExternalForce) {
this._wasMoving = false;
this.velocity.set(0, 0, 0);
this.changes.velocity = this.velocity.toArray();
2022-04-09 18:03:49 +00:00
this.changes.position = this.container.position.toArray();
2022-04-09 14:49:30 +00:00
this.setWalkAnimationState(0);
2022-04-09 11:29:54 +00:00
}
2022-04-09 14:49:30 +00:00
2022-04-09 18:03:49 +00:00
this.changes.rotation = this.container.rotation.toArray();
2022-04-09 14:49:30 +00:00
this.changes.position = this.container.position.toArray();
2022-04-09 11:29:54 +00:00
}
update(dt: number): void {
this.container.getWorldDirection(this._lookVector);
if (this.keydownMap['w']) {
this._direction.y = 1;
} else if (this.keydownMap['s']) {
this._direction.y = -1;
} else {
this._direction.y = 0;
}
if (this.keydownMap['a']) {
this._direction.x = 1;
} else if (this.keydownMap['d']) {
this._direction.x = -1;
} else {
this._direction.x = 0;
}
this.moveCharacter(dt);
super.update(dt);
this._prevKeydownMap = { ...this.keydownMap };
}
}