From 6b9b5ef18683e8dbde4d2ca6f82a85c1f6b116c4 Mon Sep 17 00:00:00 2001 From: Evert Prants Date: Sat, 9 Apr 2022 21:03:49 +0300 Subject: [PATCH] resize support --- src/client/game.ts | 32 +++++++------ src/client/index.ts | 50 +------------------- src/client/object/canvas-utils.ts | 6 +-- src/client/object/player.ts | 7 ++- src/client/renderer.ts | 77 +++++++++++++++++++++++++++++++ 5 files changed, 105 insertions(+), 67 deletions(-) create mode 100644 src/client/renderer.ts diff --git a/src/client/game.ts b/src/client/game.ts index 61c8e21..2340477 100644 --- a/src/client/game.ts +++ b/src/client/game.ts @@ -1,5 +1,4 @@ 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'; @@ -9,6 +8,7 @@ import { Joystick } from './object/joystick'; 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)[] = []; @@ -18,27 +18,31 @@ export class Game { public joystick!: Joystick; public chat!: Chat; - constructor( - public socket: Socket, - public camera: PerspectiveCamera, - public scene: Scene, - public canvas: HTMLElement, - ) {} + public renderer = new Renderer(); + + constructor(public socket: Socket) {} async initialize(): Promise { await modelLoaderInstance.loadPonyModel(); + + this.renderer.initialize(); this.bindSocket(); this.chat = new Chat(); this.chat.initialize(); this.socket.connect(); + this.chat.registerSendFunction((message) => { this.socket.emit('chat-send', message); }); + + this.renderer.registerRenderFunction((dt: number) => { + this.update(dt); + }); } public dispose() { this.players.forEach((player) => { - this.scene.remove(player.container); + this.renderer.scene.remove(player.container); }); this.thirdPersonCamera?.dispose(); @@ -70,13 +74,13 @@ export class Game { this.me = user; - const player = Player.fromUser(user, this.scene); + const player = Player.fromUser(user, this.renderer.scene); this.players.push(player); this.player = player; this.thirdPersonCamera = new ThirdPersonCamera( - this.camera, + this.renderer.camera, this.player.container, - this.canvas, + this.renderer.canvas, ); this.thirdPersonCamera.initialize(); @@ -93,14 +97,14 @@ export class Game { return; } - const newplayer = PlayerEntity.fromUser(user, this.scene); + 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.scene.remove(findPlayer.container); + this.renderer.scene.remove(findPlayer.container); this.players.splice(this.players.indexOf(findPlayer), 1); } }); @@ -111,7 +115,7 @@ export class Game { return; } - const newplayer = PlayerEntity.fromUser(player, this.scene); + const newplayer = PlayerEntity.fromUser(player, this.renderer.scene); newplayer.addUncommittedChanges(player); this.players.push(newplayer); }); diff --git a/src/client/index.ts b/src/client/index.ts index a4a0340..5078483 100644 --- a/src/client/index.ts +++ b/src/client/index.ts @@ -1,53 +1,7 @@ -import SocketIO, { Socket } from 'socket.io-client'; -import * as THREE from 'three'; -import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; +import SocketIO from 'socket.io-client'; import { Game } from './game'; -import { ThirdPersonCamera } from './object/camera'; const socket = SocketIO({ autoConnect: false }); - -const scene = new THREE.Scene(); -const camera = new THREE.PerspectiveCamera( - 75, - window.innerWidth / window.innerHeight, - 0.1, - 1000, -); - -const renderer = new THREE.WebGLRenderer(); -renderer.setSize(window.innerWidth, window.innerHeight); -document.body.appendChild(renderer.domElement); - -renderer.setClearColor(0x00ddff); - -const sun = new THREE.DirectionalLight(0xffffff); -sun.position.set(10, 10, 0); -scene.add(sun); - -const ambient = new THREE.AmbientLight(0xe8e8e8, 0.2); -scene.add(ambient); - -const cube = new THREE.Mesh( - new THREE.BoxGeometry(100, 1, 100, 10, 1, 10), - new THREE.MeshToonMaterial({ color: 0x32a852 }), -); -cube.position.set(0, -0.5, 0); -scene.add(cube); - -camera.position.set(0, 4, 4); - -const game = new Game(socket, camera, scene, renderer.domElement); - -const clock = new THREE.Clock(); -let delta: number; -function animate() { - requestAnimationFrame(animate); - - delta = clock.getDelta(); - game.update(delta); - - renderer.render(scene, camera); -} -animate(); +const game = new Game(socket); game.initialize().catch((e) => console.error(e)); diff --git a/src/client/object/canvas-utils.ts b/src/client/object/canvas-utils.ts index 5c0184f..4fe64f2 100644 --- a/src/client/object/canvas-utils.ts +++ b/src/client/object/canvas-utils.ts @@ -27,9 +27,9 @@ export function roundRect( y: number, width: number, height: number, - radius: number | { tl: number; tr: number; br: number; bl: number }, - fill: boolean, - stroke: boolean, + radius?: number | { tl: number; tr: number; br: number; bl: number }, + fill?: boolean, + stroke?: boolean, ) { if (typeof stroke === 'undefined') { stroke = true; diff --git a/src/client/object/player.ts b/src/client/object/player.ts index 7614168..b376ade 100644 --- a/src/client/object/player.ts +++ b/src/client/object/player.ts @@ -88,27 +88,30 @@ export class Player extends PonyEntity { if (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) { this._wasTurning = false; this.angularVelocity.set(0, 0, 0); this.changes.angular = this.angularVelocity.toArray(); + this.changes.rotation = this.container.rotation.toArray(); } - this.changes.rotation = this.container.rotation.toArray(); - if (vector.y !== 0) { this.velocity.copy(this._lookVector.clone().multiplyScalar(vector.y)); this.changes.velocity = this.velocity.toArray(); + this._wasMoving = true; this.setWalkAnimationState(1); } else if (this._wasMoving && !wasExternalForce) { this._wasMoving = false; this.velocity.set(0, 0, 0); this.changes.velocity = this.velocity.toArray(); + this.changes.position = this.container.position.toArray(); this.setWalkAnimationState(0); } + this.changes.rotation = this.container.rotation.toArray(); this.changes.position = this.container.position.toArray(); } diff --git a/src/client/renderer.ts b/src/client/renderer.ts new file mode 100644 index 0000000..d0dd4fd --- /dev/null +++ b/src/client/renderer.ts @@ -0,0 +1,77 @@ +import * as THREE from 'three'; + +export class Renderer { + public scene!: THREE.Scene; + public camera!: THREE.PerspectiveCamera; + public renderer!: THREE.WebGLRenderer; + + public sun!: THREE.DirectionalLight; + public ambient!: THREE.AmbientLight; + + public ground!: THREE.Mesh; + + private clock = new THREE.Clock(); + private _renderFn?: (dt: number) => void; + + constructor() {} + + get canvas() { + return this.renderer.domElement; + } + + initialize() { + this.scene = new THREE.Scene(); + this.camera = new THREE.PerspectiveCamera( + 75, + window.innerWidth / window.innerHeight, + 0.1, + 1000, + ); + + this.renderer = new THREE.WebGLRenderer(); + this.renderer.setSize(window.innerWidth, window.innerHeight); + document.body.appendChild(this.renderer.domElement); + + this.renderer.setClearColor(0x00ddff); + + this.sun = new THREE.DirectionalLight(0xffffff); + this.sun.position.set(10, 10, 0); + this.scene.add(this.sun); + + this.ambient = new THREE.AmbientLight(0xe8e8e8, 0.2); + this.scene.add(this.ambient); + + this.ground = new THREE.Mesh( + new THREE.BoxGeometry(100, 1, 100, 10, 1, 10), + new THREE.MeshToonMaterial({ color: 0x32a852 }), + ); + + this.ground.position.set(0, -0.5, 0); + this.scene.add(this.ground); + + this.camera.position.set(0, 4, 4); + + window.addEventListener('resize', () => { + this.renderer.setSize(window.innerWidth, window.innerHeight); + this.camera.aspect = window.innerWidth / window.innerHeight; + this.camera.updateProjectionMatrix(); + }); + + this.render(); + } + + render() { + requestAnimationFrame(() => this.render()); + + const delta = this.clock.getDelta(); + if (this._renderFn) { + this._renderFn(delta); + } + + this.renderer.render(this.scene, this.camera); + } + + public registerRenderFunction(fn: (dt: number) => void) { + this._renderFn = fn; + } +}