idk what imd oing

This commit is contained in:
Evert Prants 2022-04-09 15:57:20 +03:00
parent 1be31684d6
commit 6c0f6350d6
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
8 changed files with 124 additions and 50 deletions

View File

@ -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);
});
}

View File

@ -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 };
}
}

View File

@ -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,

View File

@ -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

View File

@ -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) {

View File

@ -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);

View File

@ -152,7 +152,7 @@ body {
pointer-events: none;
}
button {
button, input {
pointer-events: all;
}
}

View File

@ -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);
}
});
});
}