idk what imd oing
This commit is contained in:
parent
1be31684d6
commit
6c0f6350d6
@ -129,6 +129,14 @@ export class Game {
|
||||
});
|
||||
|
||||
this.socket.on('chat', (event) => {
|
||||
const player = this.players.find(
|
||||
(item) => item.user.id === event.sender.id,
|
||||
);
|
||||
|
||||
if (player && player.user.id !== this.me.id) {
|
||||
// (player as PlayerEntity).addChat(event.message);
|
||||
}
|
||||
|
||||
this.chat.addMessage(event.sender.display_name, event.message);
|
||||
});
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import { CanvasTexture, LinearFilter, ClampToEdgeWrapping } from 'three';
|
||||
|
||||
export class CanvasUtils {
|
||||
public createTextCanvas(
|
||||
text: string,
|
||||
text: string | string[],
|
||||
bold = true,
|
||||
fontSize = 16,
|
||||
padding = 4,
|
||||
@ -10,12 +10,23 @@ export class CanvasUtils {
|
||||
const ctx = document.createElement('canvas').getContext('2d');
|
||||
const font = `${fontSize}px${bold ? ' bold' : ''} sans`;
|
||||
|
||||
const lines = Array.isArray(text) ? text : [text];
|
||||
const lineWidths = [];
|
||||
let longestLine = 0;
|
||||
|
||||
// Measure the text bounds
|
||||
ctx.font = font;
|
||||
const measure = ctx.measureText(text);
|
||||
lines.forEach((line) => {
|
||||
const lineWidth = ctx.measureText(line).width;
|
||||
if (longestLine < lineWidth) {
|
||||
longestLine = lineWidth;
|
||||
}
|
||||
lineWidths.push(lineWidth);
|
||||
});
|
||||
|
||||
const width = measure.width + padding * 2;
|
||||
const height = fontSize + padding * 2;
|
||||
const width = longestLine + padding * 2;
|
||||
const textHeight = fontSize * lines.length;
|
||||
const height = textHeight + padding * 2;
|
||||
|
||||
// Resize canvas
|
||||
ctx.canvas.width = width;
|
||||
@ -23,7 +34,6 @@ export class CanvasUtils {
|
||||
|
||||
// Set text parameters
|
||||
ctx.font = font;
|
||||
ctx.textBaseline = 'middle';
|
||||
ctx.textAlign = 'center';
|
||||
|
||||
// Draw background
|
||||
@ -31,11 +41,13 @@ export class CanvasUtils {
|
||||
ctx.fillRect(0, 0, width, height);
|
||||
|
||||
// Scale the text to fit within the canvas
|
||||
const scaleFactor = Math.min(1, width / measure.width);
|
||||
ctx.translate(width / 2 - padding, height / 2 - padding);
|
||||
const scaleFactor = Math.min(1, width / longestLine);
|
||||
ctx.translate(width / 2 - padding, padding + fontSize / 2);
|
||||
ctx.scale(scaleFactor, 1);
|
||||
ctx.fillStyle = '#000';
|
||||
ctx.fillText(text, padding, padding);
|
||||
lines.forEach((line, i) => {
|
||||
ctx.fillText(line, padding, i * fontSize + padding);
|
||||
});
|
||||
|
||||
// Create texture with appropriate flags
|
||||
const texture = new CanvasTexture(ctx.canvas);
|
||||
@ -43,6 +55,6 @@ export class CanvasUtils {
|
||||
texture.wrapS = ClampToEdgeWrapping;
|
||||
texture.wrapT = ClampToEdgeWrapping;
|
||||
|
||||
return { texture, width: width, height: height };
|
||||
return { texture, width, height };
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import { CanvasUtils } from './canvas-utils';
|
||||
export class NameTag {
|
||||
public tag!: Sprite;
|
||||
public width!: number;
|
||||
public height!: number;
|
||||
private texture!: CanvasTexture;
|
||||
private material!: SpriteMaterial;
|
||||
|
||||
@ -16,6 +17,7 @@ export class NameTag {
|
||||
|
||||
this.texture = texture;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
this.material = new SpriteMaterial({
|
||||
map: texture,
|
||||
|
@ -2,9 +2,15 @@ import { IcyNetUser } from '../../common/types/user';
|
||||
import * as THREE from 'three';
|
||||
import { PonyEntity } from './pony';
|
||||
import { Packet } from '../../common/types/packet';
|
||||
import { CanvasUtils } from './canvas-utils';
|
||||
import { ChatBubble } from './chat-bubble';
|
||||
|
||||
const chatBuilder = new CanvasUtils();
|
||||
|
||||
export class PlayerEntity extends PonyEntity {
|
||||
private uncommittedPacket: Packet = {};
|
||||
private _chats: ChatBubble[] = [];
|
||||
|
||||
constructor(public user: IcyNetUser) {
|
||||
super();
|
||||
}
|
||||
@ -29,6 +35,47 @@ export class PlayerEntity extends PonyEntity {
|
||||
this.container.position.copy(pos);
|
||||
}
|
||||
|
||||
public addChat(message: string): void {
|
||||
const lines = [];
|
||||
let truncated = message;
|
||||
|
||||
while (truncated.length > 80) {
|
||||
lines.push(truncated.substring(0, 80));
|
||||
truncated = truncated.substring(80);
|
||||
}
|
||||
|
||||
if (truncated) {
|
||||
lines.push(truncated);
|
||||
}
|
||||
|
||||
const newChat = new ChatBubble(chatBuilder, lines);
|
||||
|
||||
this._chats.forEach((item) => {
|
||||
item.tag.position.add(new THREE.Vector3(0, item.height * 0.01, 0));
|
||||
});
|
||||
|
||||
this._chats.unshift(newChat);
|
||||
newChat.tag.position.set(0, 1.8, 0.5);
|
||||
this.container.add(newChat.tag);
|
||||
|
||||
if (this._chats.length > 3) {
|
||||
this._chats.splice(3, this._chats.length - 1).forEach((item) => {
|
||||
this.container.remove(item.tag);
|
||||
item.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
const i = this._chats.indexOf(newChat);
|
||||
|
||||
if (i !== -1) {
|
||||
this.container.remove(newChat.tag);
|
||||
this._chats.splice(i, 1);
|
||||
newChat.dispose();
|
||||
}
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
public setRotation(rot: THREE.Vector3 | THREE.Euler) {
|
||||
this.container.rotation.copy(
|
||||
rot instanceof THREE.Euler
|
||||
|
@ -86,7 +86,7 @@ export class Player extends PonyEntity {
|
||||
}
|
||||
|
||||
if (vector.x !== 0) {
|
||||
this.angularVelocity.set(0, Math.PI * dt * vector.x, 0);
|
||||
this.angularVelocity.set(0, Math.PI * vector.x, 0);
|
||||
this.changes.angular = this.angularVelocity.toArray();
|
||||
this._wasTurning = true;
|
||||
} else if (this._wasTurning && !wasExternalForce) {
|
||||
@ -97,9 +97,7 @@ export class Player extends PonyEntity {
|
||||
}
|
||||
|
||||
if (vector.y !== 0) {
|
||||
this.velocity.copy(
|
||||
this._lookVector.clone().multiplyScalar(vector.y * dt),
|
||||
);
|
||||
this.velocity.copy(this._lookVector.clone().multiplyScalar(vector.y));
|
||||
this.changes.velocity = this.velocity.toArray();
|
||||
this._wasMoving = true;
|
||||
} else if (this._wasMoving && !wasExternalForce) {
|
||||
|
@ -30,13 +30,13 @@ export class PonyEntity {
|
||||
}
|
||||
|
||||
update(dt: number) {
|
||||
this.container.position.add(this.velocity);
|
||||
this.container.position.add(this.velocity.clone().multiplyScalar(dt));
|
||||
this.container.rotation.setFromVector3(
|
||||
new THREE.Vector3(
|
||||
this.container.rotation.x,
|
||||
this.container.rotation.y,
|
||||
this.container.rotation.z,
|
||||
).add(this.angularVelocity),
|
||||
).add(this.angularVelocity.clone().multiplyScalar(dt)),
|
||||
);
|
||||
this.mixer.update(dt);
|
||||
|
||||
|
@ -152,7 +152,7 @@ body {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
button {
|
||||
button, input {
|
||||
pointer-events: all;
|
||||
}
|
||||
}
|
||||
|
@ -41,47 +41,54 @@ export class Game {
|
||||
const publicUserInfo = user ? this.mapPlayer(user) : null;
|
||||
|
||||
this._connections.push(socket);
|
||||
socket.data.user = user;
|
||||
socket.data.playerinfo = {
|
||||
velocity: [0, 0, 0],
|
||||
angular: [0, 0, 0],
|
||||
position: [0, 0, 0],
|
||||
rotation: [0, 0, 0],
|
||||
animState: 0,
|
||||
};
|
||||
|
||||
socket.emit('me', publicUserInfo);
|
||||
socket.emit(
|
||||
'players',
|
||||
this._connections
|
||||
.filter((player) => player.data.user)
|
||||
.map((conn) => ({
|
||||
...this.mapPlayer(conn.data.user),
|
||||
...conn.data.playerinfo,
|
||||
})),
|
||||
);
|
||||
|
||||
socket.broadcast.emit('playerjoin', publicUserInfo);
|
||||
if (user) {
|
||||
socket.broadcast.emit('playerjoin', publicUserInfo);
|
||||
|
||||
socket.data.user = user;
|
||||
socket.data.playerinfo = {
|
||||
velocity: [0, 0, 0],
|
||||
angular: [0, 0, 0],
|
||||
position: [0, 0, 0],
|
||||
rotation: [0, 0, 0],
|
||||
animState: 0,
|
||||
};
|
||||
|
||||
socket.emit(
|
||||
'players',
|
||||
this._connections
|
||||
.filter((player) => player.data.user)
|
||||
.map((conn) => ({
|
||||
...this.mapPlayer(conn.data.user),
|
||||
...conn.data.playerinfo,
|
||||
})),
|
||||
);
|
||||
|
||||
socket.on('move', (packet) => {
|
||||
socket.data.playerinfo = {
|
||||
...socket.data.playerinfo,
|
||||
...packet,
|
||||
};
|
||||
socket.broadcast.emit('playerupdate', {
|
||||
id: user.id,
|
||||
...packet,
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('chat-send', (raw) => {
|
||||
const message = raw.trim().substring(0, 260);
|
||||
this.io.emit('chat', { sender: publicUserInfo, message });
|
||||
});
|
||||
}
|
||||
|
||||
socket.on('disconnect', () => {
|
||||
this._connections.splice(this._connections.indexOf(socket), 1);
|
||||
this.io.emit('playerleave', publicUserInfo);
|
||||
});
|
||||
|
||||
socket.on('move', (packet) => {
|
||||
socket.data.playerinfo = {
|
||||
...socket.data.playerinfo,
|
||||
...packet,
|
||||
};
|
||||
socket.broadcast.emit('playerupdate', {
|
||||
id: user.id,
|
||||
...packet,
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('chat-send', (raw) => {
|
||||
const message = raw.trim().substring(0, 260);
|
||||
this.io.emit('chat', { sender: publicUserInfo, message });
|
||||
if (user) {
|
||||
this.io.emit('playerleave', publicUserInfo);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user