icy3dw/src/client/game.ts

185 lines
4.8 KiB
TypeScript

import e from 'express';
import { Socket } from 'socket.io-client';
import { isMobileOrTablet } from '../common/helper';
import { CompositePacket } from '../common/types/packet';
import { IcyNetUser } from '../common/types/user';
import { ThirdPersonCamera } from './object/camera';
import { Chat } from './object/chat';
import { Joystick } from './object/joystick';
import { VideoPlayer } from './object/other/video-player';
import { Player } from './object/player';
import { PlayerEntity } from './object/player-entity';
import modelLoaderInstance from './object/pony-loader';
import { Renderer } from './renderer';
export class Game {
public players: (Player | PlayerEntity)[] = [];
public player!: Player;
public me!: IcyNetUser;
public thirdPersonCamera!: ThirdPersonCamera;
public joystick!: Joystick;
public chat!: Chat;
public renderer = new Renderer();
private videoTest = new VideoPlayer();
constructor(public socket: Socket) {}
async initialize(): Promise<void> {
await modelLoaderInstance.loadPonyModel();
this.renderer.initialize();
this.bindSocket();
this.chat = new Chat();
this.chat.initialize();
this.socket.connect();
// experimental
this.videoTest.initialize();
this.videoTest.mesh.position.set(0, 6, -20);
this.renderer.scene.add(this.videoTest.mesh);
// end of
this.chat.registerSendFunction((message) => {
// experimental
if (message.startsWith('!play')) {
const [cmd, src] = message.split(' ');
if (src) {
this.videoTest.setSource(src, true);
} else {
this.videoTest.play();
}
return;
}
if (message.startsWith('!stop') || message.startsWith('!pause')) {
this.videoTest.stop();
return;
}
if (message.startsWith('!volume')) {
const [cmd, vol] = message.split(' ');
this.videoTest.setVolume(parseInt(vol.replace('%', ''), 10));
return;
}
// end of
this.socket.emit('chat-send', message);
});
this.renderer.registerRenderFunction((dt: number) => {
this.update(dt);
});
}
public dispose() {
this.players.forEach((player) => {
this.renderer.scene.remove(player.container);
});
this.thirdPersonCamera?.dispose();
this.joystick?.dispose();
this.players.length = 0;
}
public update(dt: number) {
this.players.forEach((player) => player.update(dt));
this.player?.createPacket(this.socket);
this.thirdPersonCamera?.update(dt);
this.joystick?.update(dt);
}
bindSocket() {
this.socket.on('connect', () => {
this.dispose();
console.log('connected');
});
this.socket.on('me', (user) => {
console.log(user);
if (!user) {
window.location.href = '/login';
return;
}
this.me = user;
const player = Player.fromUser(user, this.renderer.scene);
this.players.push(player);
this.player = player;
this.thirdPersonCamera = new ThirdPersonCamera(
this.renderer.camera,
this.player.container,
this.renderer.canvas,
);
this.thirdPersonCamera.initialize();
this.joystick = new Joystick(player);
this.joystick.initialize();
if (isMobileOrTablet()) {
this.joystick.show();
}
});
this.socket.on('playerjoin', (user) => {
if (user.id === this.me.id) {
return;
}
const newplayer = PlayerEntity.fromUser(user, this.renderer.scene);
this.players.push(newplayer);
});
this.socket.on('playerleave', (user) => {
const findPlayer = this.players.find((item) => item.user.id === user.id);
if (findPlayer) {
this.renderer.scene.remove(findPlayer.container);
this.players.splice(this.players.indexOf(findPlayer), 1);
}
});
this.socket.on('players', (list: CompositePacket[]) => {
list.forEach((player) => {
if (player.id === this.me.id) {
return;
}
const newplayer = PlayerEntity.fromUser(player, this.renderer.scene);
newplayer.addUncommittedChanges(player);
this.players.push(newplayer);
});
});
this.socket.on('playerupdate', (data) => {
data.forEach((item) => {
const player = this.players.find(
(player) => player.user.id === item.id,
);
if (
player &&
player instanceof PlayerEntity &&
player.user.id !== this.me.id
) {
player.addUncommittedChanges(item);
}
});
});
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);
});
}
}