bedrock-protocol/examples/viewer/client/BotViewer.js
2021-04-08 01:32:20 -04:00

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 }