import { Socket } from 'socket.io-client'; import { PerspectiveCamera, Scene } from 'three'; 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 { Player } from './object/player'; import { PlayerEntity } from './object/player-entity'; import modelLoaderInstance from './object/pony-loader'; export class Game { public players: (Player | PlayerEntity)[] = []; public player!: Player; public me!: IcyNetUser; public thirdPersonCamera!: ThirdPersonCamera; public joystick!: Joystick; public chat!: Chat; constructor( public socket: Socket, public camera: PerspectiveCamera, public scene: Scene, public canvas: HTMLElement, ) {} async initialize(): Promise { await modelLoaderInstance.loadPonyModel(); this.bindSocket(); this.chat = new Chat(); this.chat.initialize(); this.socket.connect(); this.chat.registerSendFunction((message) => { this.socket.emit('chat-send', message); }); } public dispose() { this.players.forEach((player) => { this.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.scene); this.players.push(player); this.player = player; this.thirdPersonCamera = new ThirdPersonCamera( this.camera, this.player.container, this.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.scene); this.players.push(newplayer); }); this.socket.on('playerleave', (user) => { const findPlayer = this.players.find((item) => item.user.id === user.id); if (findPlayer) { this.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.scene); newplayer.addUncommittedChanges(player); this.players.push(newplayer); }); }); this.socket.on('playerupdate', (data) => { const player = this.players.find((player) => player.user.id === data.id); if ( player && player instanceof PlayerEntity && player.user.id !== this.me.id ) { player.addUncommittedChanges(data); } }); this.socket.on('chat', (event) => { this.chat.addMessage(event.sender.display_name, event.message); }); } }