Files
bworld/client/entity/remote_player.ts
T
2026-09-25 16:05:25 -03:00

66 lines
1.7 KiB
TypeScript

import type { PlayerInfo } from "$/common/protocol.ts";
import type { ClientLevel } from "../level/client_level.ts";
import { Player } from "./player.ts";
const SMOOTHING = 12;
// another player on the server, it moves where the server says instead of simulating anything
export class RemotePlayer extends Player {
color: [number, number, number];
// where the server last said it is, the drawn position eases towards it so movement isn't choppy
target_x: number;
target_y: number;
target_z: number;
constructor(level: ClientLevel, info: PlayerInfo) {
super(level, info.id, info.name);
this.set_position(info.x, info.y, info.z);
this.target_x = info.x;
this.target_y = info.y;
this.target_z = info.z;
this.yaw = info.yaw;
this.pitch = info.pitch;
this.color = color_from_name(info.name);
}
lerp_to(x: number, y: number, z: number, yaw: number, pitch: number) {
this.target_x = x;
this.target_y = y;
this.target_z = z;
this.yaw = yaw;
this.pitch = pitch;
}
tick(delta: number) {
const t = Math.min(1, delta * SMOOTHING);
this.x += (this.target_x - this.x) * t;
this.y += (this.target_y - this.y) * t;
this.z += (this.target_z - this.z) * t;
}
}
function color_from_name(name: string): [number, number, number] {
let hash = 0;
for (const ch of name) {
hash = (hash * 31 + ch.charCodeAt(0)) | 0;
}
const hue = ((hash % 360) + 360) % 360;
// hsl with s=0.6 l=0.6 to rgb
const c = 0.48;
const x = c * (1 - Math.abs(((hue / 60) % 2) - 1));
const m = 0.36;
const [r, g, b] = hue < 60
? [c, x, 0]
: hue < 120
? [x, c, 0]
: hue < 180
? [0, c, x]
: hue < 240
? [0, x, c]
: hue < 300
? [x, 0, c]
: [c, 0, x];
return [r + m, g + m, b + m];
}