resize support
This commit is contained in:
parent
5215b29a0d
commit
6b9b5ef186
@ -1,5 +1,4 @@
|
|||||||
import { Socket } from 'socket.io-client';
|
import { Socket } from 'socket.io-client';
|
||||||
import { PerspectiveCamera, Scene } from 'three';
|
|
||||||
import { isMobileOrTablet } from '../common/helper';
|
import { isMobileOrTablet } from '../common/helper';
|
||||||
import { CompositePacket } from '../common/types/packet';
|
import { CompositePacket } from '../common/types/packet';
|
||||||
import { IcyNetUser } from '../common/types/user';
|
import { IcyNetUser } from '../common/types/user';
|
||||||
@ -9,6 +8,7 @@ import { Joystick } from './object/joystick';
|
|||||||
import { Player } from './object/player';
|
import { Player } from './object/player';
|
||||||
import { PlayerEntity } from './object/player-entity';
|
import { PlayerEntity } from './object/player-entity';
|
||||||
import modelLoaderInstance from './object/pony-loader';
|
import modelLoaderInstance from './object/pony-loader';
|
||||||
|
import { Renderer } from './renderer';
|
||||||
|
|
||||||
export class Game {
|
export class Game {
|
||||||
public players: (Player | PlayerEntity)[] = [];
|
public players: (Player | PlayerEntity)[] = [];
|
||||||
@ -18,27 +18,31 @@ export class Game {
|
|||||||
public joystick!: Joystick;
|
public joystick!: Joystick;
|
||||||
public chat!: Chat;
|
public chat!: Chat;
|
||||||
|
|
||||||
constructor(
|
public renderer = new Renderer();
|
||||||
public socket: Socket,
|
|
||||||
public camera: PerspectiveCamera,
|
constructor(public socket: Socket) {}
|
||||||
public scene: Scene,
|
|
||||||
public canvas: HTMLElement,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
async initialize(): Promise<void> {
|
async initialize(): Promise<void> {
|
||||||
await modelLoaderInstance.loadPonyModel();
|
await modelLoaderInstance.loadPonyModel();
|
||||||
|
|
||||||
|
this.renderer.initialize();
|
||||||
this.bindSocket();
|
this.bindSocket();
|
||||||
this.chat = new Chat();
|
this.chat = new Chat();
|
||||||
this.chat.initialize();
|
this.chat.initialize();
|
||||||
this.socket.connect();
|
this.socket.connect();
|
||||||
|
|
||||||
this.chat.registerSendFunction((message) => {
|
this.chat.registerSendFunction((message) => {
|
||||||
this.socket.emit('chat-send', message);
|
this.socket.emit('chat-send', message);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.renderer.registerRenderFunction((dt: number) => {
|
||||||
|
this.update(dt);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public dispose() {
|
public dispose() {
|
||||||
this.players.forEach((player) => {
|
this.players.forEach((player) => {
|
||||||
this.scene.remove(player.container);
|
this.renderer.scene.remove(player.container);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.thirdPersonCamera?.dispose();
|
this.thirdPersonCamera?.dispose();
|
||||||
@ -70,13 +74,13 @@ export class Game {
|
|||||||
|
|
||||||
this.me = user;
|
this.me = user;
|
||||||
|
|
||||||
const player = Player.fromUser(user, this.scene);
|
const player = Player.fromUser(user, this.renderer.scene);
|
||||||
this.players.push(player);
|
this.players.push(player);
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.thirdPersonCamera = new ThirdPersonCamera(
|
this.thirdPersonCamera = new ThirdPersonCamera(
|
||||||
this.camera,
|
this.renderer.camera,
|
||||||
this.player.container,
|
this.player.container,
|
||||||
this.canvas,
|
this.renderer.canvas,
|
||||||
);
|
);
|
||||||
this.thirdPersonCamera.initialize();
|
this.thirdPersonCamera.initialize();
|
||||||
|
|
||||||
@ -93,14 +97,14 @@ export class Game {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newplayer = PlayerEntity.fromUser(user, this.scene);
|
const newplayer = PlayerEntity.fromUser(user, this.renderer.scene);
|
||||||
this.players.push(newplayer);
|
this.players.push(newplayer);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.socket.on('playerleave', (user) => {
|
this.socket.on('playerleave', (user) => {
|
||||||
const findPlayer = this.players.find((item) => item.user.id === user.id);
|
const findPlayer = this.players.find((item) => item.user.id === user.id);
|
||||||
if (findPlayer) {
|
if (findPlayer) {
|
||||||
this.scene.remove(findPlayer.container);
|
this.renderer.scene.remove(findPlayer.container);
|
||||||
this.players.splice(this.players.indexOf(findPlayer), 1);
|
this.players.splice(this.players.indexOf(findPlayer), 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -111,7 +115,7 @@ export class Game {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newplayer = PlayerEntity.fromUser(player, this.scene);
|
const newplayer = PlayerEntity.fromUser(player, this.renderer.scene);
|
||||||
newplayer.addUncommittedChanges(player);
|
newplayer.addUncommittedChanges(player);
|
||||||
this.players.push(newplayer);
|
this.players.push(newplayer);
|
||||||
});
|
});
|
||||||
|
@ -1,53 +1,7 @@
|
|||||||
import SocketIO, { Socket } from 'socket.io-client';
|
import SocketIO from 'socket.io-client';
|
||||||
import * as THREE from 'three';
|
|
||||||
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
|
|
||||||
import { Game } from './game';
|
import { Game } from './game';
|
||||||
import { ThirdPersonCamera } from './object/camera';
|
|
||||||
|
|
||||||
const socket = SocketIO({ autoConnect: false });
|
const socket = SocketIO({ autoConnect: false });
|
||||||
|
const game = new Game(socket);
|
||||||
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();
|
|
||||||
|
|
||||||
game.initialize().catch((e) => console.error(e));
|
game.initialize().catch((e) => console.error(e));
|
||||||
|
@ -27,9 +27,9 @@ export function roundRect(
|
|||||||
y: number,
|
y: number,
|
||||||
width: number,
|
width: number,
|
||||||
height: number,
|
height: number,
|
||||||
radius: number | { tl: number; tr: number; br: number; bl: number },
|
radius?: number | { tl: number; tr: number; br: number; bl: number },
|
||||||
fill: boolean,
|
fill?: boolean,
|
||||||
stroke: boolean,
|
stroke?: boolean,
|
||||||
) {
|
) {
|
||||||
if (typeof stroke === 'undefined') {
|
if (typeof stroke === 'undefined') {
|
||||||
stroke = true;
|
stroke = true;
|
||||||
|
@ -88,27 +88,30 @@ export class Player extends PonyEntity {
|
|||||||
if (vector.x !== 0) {
|
if (vector.x !== 0) {
|
||||||
this.angularVelocity.set(0, Math.PI * vector.x, 0);
|
this.angularVelocity.set(0, Math.PI * vector.x, 0);
|
||||||
this.changes.angular = this.angularVelocity.toArray();
|
this.changes.angular = this.angularVelocity.toArray();
|
||||||
|
|
||||||
this._wasTurning = true;
|
this._wasTurning = true;
|
||||||
} else if (this._wasTurning && !wasExternalForce) {
|
} else if (this._wasTurning && !wasExternalForce) {
|
||||||
this._wasTurning = false;
|
this._wasTurning = false;
|
||||||
this.angularVelocity.set(0, 0, 0);
|
this.angularVelocity.set(0, 0, 0);
|
||||||
this.changes.angular = this.angularVelocity.toArray();
|
this.changes.angular = this.angularVelocity.toArray();
|
||||||
|
this.changes.rotation = this.container.rotation.toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.changes.rotation = this.container.rotation.toArray();
|
|
||||||
|
|
||||||
if (vector.y !== 0) {
|
if (vector.y !== 0) {
|
||||||
this.velocity.copy(this._lookVector.clone().multiplyScalar(vector.y));
|
this.velocity.copy(this._lookVector.clone().multiplyScalar(vector.y));
|
||||||
this.changes.velocity = this.velocity.toArray();
|
this.changes.velocity = this.velocity.toArray();
|
||||||
|
|
||||||
this._wasMoving = true;
|
this._wasMoving = true;
|
||||||
this.setWalkAnimationState(1);
|
this.setWalkAnimationState(1);
|
||||||
} else if (this._wasMoving && !wasExternalForce) {
|
} else if (this._wasMoving && !wasExternalForce) {
|
||||||
this._wasMoving = false;
|
this._wasMoving = false;
|
||||||
this.velocity.set(0, 0, 0);
|
this.velocity.set(0, 0, 0);
|
||||||
this.changes.velocity = this.velocity.toArray();
|
this.changes.velocity = this.velocity.toArray();
|
||||||
|
this.changes.position = this.container.position.toArray();
|
||||||
this.setWalkAnimationState(0);
|
this.setWalkAnimationState(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.changes.rotation = this.container.rotation.toArray();
|
||||||
this.changes.position = this.container.position.toArray();
|
this.changes.position = this.container.position.toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
77
src/client/renderer.ts
Normal file
77
src/client/renderer.ts
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user