150 lines
4.7 KiB
JavaScript
150 lines
4.7 KiB
JavaScript
/* global THREE */
|
|
const { Viewer, MapControls } = require('prismarine-viewer/viewer')
|
|
// const { Vec3 } = require('vec3')
|
|
const { ClientProvider } = require('./ClientProvider')
|
|
// const { ProxyProvider } = require('./ProxyProvider')
|
|
global.THREE = require('three')
|
|
|
|
const MCVER = '1.16.1'
|
|
|
|
class BotViewer {
|
|
start () {
|
|
this.bot = new ClientProvider()
|
|
// this.bot = new ProxyProvider()
|
|
// Create three.js context, add to page
|
|
this.renderer = new THREE.WebGLRenderer()
|
|
this.renderer.setPixelRatio(window.devicePixelRatio || 1)
|
|
this.renderer.setSize(window.innerWidth, window.innerHeight)
|
|
document.body.appendChild(this.renderer.domElement)
|
|
|
|
// Create viewer
|
|
this.viewer = new Viewer(this.renderer)
|
|
this.viewer.setVersion(MCVER)
|
|
// Attach controls to viewer
|
|
this.controls = new MapControls(this.viewer.camera, this.renderer.domElement)
|
|
// Enable damping (inertia) on movement
|
|
this.controls.enableDamping = true
|
|
this.controls.dampingFactor = 0.09
|
|
console.info('Registered handlers')
|
|
// Link WorldView and Viewer
|
|
this.viewer.listen(this.bot)
|
|
|
|
this.bot.on('spawn', ({ position, firstPerson }) => {
|
|
// Initialize viewer, load chunks
|
|
this.bot.init(position)
|
|
// Start listening for keys
|
|
this.registerBrowserEvents()
|
|
|
|
if (firstPerson && this.bot.movements) {
|
|
this.viewer.camera.position.set(position.x, position.y, position.z)
|
|
this.firstPerson = true
|
|
this.controls.enabled = false
|
|
} else {
|
|
this.viewer.camera.position.set(position.x, position.y, position.z)
|
|
}
|
|
})
|
|
|
|
this.bot.on('playerMove', (id, pos) => {
|
|
if (this.firstPerson && id < 10) {
|
|
this.setFirstPersonCamera(pos)
|
|
return
|
|
}
|
|
|
|
window.viewer.viewer.entities.update({
|
|
name: 'player',
|
|
id,
|
|
pos: pos.position,
|
|
width: 0.6,
|
|
height: 1.8,
|
|
yaw: pos.yaw,
|
|
pitch: pos.pitch
|
|
})
|
|
})
|
|
|
|
const oldFov = this.viewer.camera.fov
|
|
const sprintFov = this.viewer.camera.fov + 20
|
|
const sneakFov = this.viewer.camera.fov - 10
|
|
|
|
const onSprint = () => {
|
|
this.viewer.camera.fov = sprintFov
|
|
this.viewer.camera.updateProjectionMatrix()
|
|
}
|
|
|
|
const onSneak = () => {
|
|
this.viewer.camera.fov = sneakFov
|
|
this.viewer.camera.updateProjectionMatrix()
|
|
}
|
|
|
|
const onRelease = () => {
|
|
this.viewer.camera.fov = oldFov
|
|
this.viewer.camera.updateProjectionMatrix()
|
|
}
|
|
|
|
this.bot.on('startSprint', onSprint)
|
|
this.bot.on('startSneak', onSneak)
|
|
this.bot.on('stopSprint', onRelease)
|
|
this.bot.on('stopSneak', onRelease)
|
|
|
|
this.controls.update()
|
|
|
|
// Browser animation loop
|
|
const animate = () => {
|
|
window.requestAnimationFrame(animate)
|
|
if (this.controls && !this.firstPerson) this.controls.update()
|
|
this.viewer.update()
|
|
this.renderer.render(this.viewer.scene, this.viewer.camera)
|
|
}
|
|
animate()
|
|
|
|
window.addEventListener('resize', () => {
|
|
this.viewer.camera.aspect = window.innerWidth / window.innerHeight
|
|
this.viewer.camera.updateProjectionMatrix()
|
|
this.renderer.setSize(window.innerWidth, window.innerHeight)
|
|
})
|
|
}
|
|
|
|
onMouseMove = (e) => {
|
|
if (this.firstPerson) {
|
|
this.bot.entity.pitch -= e.movementY * 0.005
|
|
this.bot.entity.yaw -= e.movementX * 0.004
|
|
}
|
|
}
|
|
|
|
onPointerLockChange = () => {
|
|
const e = this.renderer.domElement
|
|
if (document.pointerLockElement === e) {
|
|
e.parentElement.addEventListener('mousemove', this.onMouseMove, { passive: true })
|
|
} else {
|
|
e.parentElement.removeEventListener('mousemove', this.onMouseMove, false)
|
|
}
|
|
}
|
|
|
|
onMouseDown = () => {
|
|
if (this.firstPerson && !document.pointerLockElement) {
|
|
this.renderer.domElement.requestPointerLock()
|
|
}
|
|
}
|
|
|
|
registerBrowserEvents () {
|
|
const e = this.renderer.domElement
|
|
e.parentElement.addEventListener('keydown', this.bot.onKeyDown)
|
|
e.parentElement.addEventListener('keyup', this.bot.onKeyUp)
|
|
e.parentElement.addEventListener('mousedown', this.onMouseDown)
|
|
document.addEventListener('pointerlockchange', this.onPointerLockChange, false)
|
|
}
|
|
|
|
unregisterBrowserEvents () {
|
|
const e = this.renderer.domElement
|
|
e.parentElement.removeEventListener('keydown', this.bot.onKeyDown)
|
|
e.parentElement.removeEventListener('keyup', this.bot.onKeyUp)
|
|
e.parentElement.removeEventListener('mousemove', this.onMouseMove)
|
|
e.parentElement.removeEventListener('mousedown', this.onMouseDown)
|
|
document.removeEventListener('pointerlockchange', this.onPointerLockChange, false)
|
|
}
|
|
|
|
setFirstPersonCamera (entity) {
|
|
this.viewer.setFirstPersonCamera(entity.position, entity.yaw, entity.pitch * 2)
|
|
}
|
|
}
|
|
|
|
module.exports = { BotViewer }
|