Fork自 AresnLiang / Minecraft
{"version":3,"file":"index.3d64fa62.js","sources":["../../vite/modulepreload-polyfill","../../src/core/index.ts","../../src/player/index.ts","../../src/static/textures/block/stone.png","../../src/static/textures/block/coal_ore.png","../../src/static/textures/block/iron_ore.png","../../src/static/textures/block/grass_block_side.png","../../src/static/textures/block/grass_top_green.png","../../src/static/textures/block/dirt.png","../../src/static/textures/block/oak_log.png","../../src/static/textures/block/oak_log_top.png","../../src/static/textures/block/oak_leaves.png","../../src/static/textures/block/sand.png","../../src/static/textures/block/oak_planks.png","../../src/static/textures/block/diamond_block.png","../../src/static/textures/block/quartz_block_side.png","../../src/static/textures/block/glass.png","../../src/static/textures/block/bedrock.png","../../src/terrain/mesh/materials.ts","../../src/terrain/mesh/block.ts","../../src/terrain/highlight/index.ts","../../src/terrain/noise/index.ts","../../src/terrain/index.ts","../../src/utils/index.ts","../../src/control/index.ts","../../src/ui/fps/index.ts","../../src/static/block-icon/grass.png","../../src/static/block-icon/stone.png","../../src/static/block-icon/tree.png","../../src/static/block-icon/wood.png","../../src/static/block-icon/diamond.png","../../src/static/block-icon/quartz.png","../../src/static/block-icon/glass.png","../../src/ui/bag/index.ts","../../src/ui/joystick/joystick.html?raw","../../src/ui/joystick/index.ts","../../src/ui/index.ts","../../src/audio/musics/hal3.ogg","../../src/audio/blocks/grass1.ogg","../../src/audio/blocks/grass2.ogg","../../src/audio/blocks/grass3.ogg","../../src/audio/blocks/grass4.ogg","../../src/audio/blocks/sand1.ogg","../../src/audio/blocks/sand2.ogg","../../src/audio/blocks/sand3.ogg","../../src/audio/blocks/sand4.ogg","../../src/audio/blocks/stone1.ogg","../../src/audio/blocks/stone2.ogg","../../src/audio/blocks/stone3.ogg","../../src/audio/blocks/stone4.ogg","../../src/audio/blocks/dirt1.ogg","../../src/audio/blocks/dirt2.ogg","../../src/audio/blocks/dirt3.ogg","../../src/audio/blocks/dirt4.ogg","../../src/audio/blocks/tree1.ogg","../../src/audio/blocks/tree2.ogg","../../src/audio/blocks/tree3.ogg","../../src/audio/blocks/tree4.ogg","../../src/audio/blocks/leaf1.ogg","../../src/audio/blocks/leaf2.ogg","../../src/audio/blocks/leaf3.ogg","../../src/audio/blocks/leaf4.ogg","../../src/audio/index.ts","../../src/main.ts"],"sourcesContent":["const p = function polyfill() {\n const relList = document.createElement('link').relList;\n if (relList && relList.supports && relList.supports('modulepreload')) {\n return;\n }\n for (const link of document.querySelectorAll('link[rel=\"modulepreload\"]')) {\n processPreload(link);\n }\n new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n if (mutation.type !== 'childList') {\n continue;\n }\n for (const node of mutation.addedNodes) {\n if (node.tagName === 'LINK' && node.rel === 'modulepreload')\n processPreload(node);\n }\n }\n }).observe(document, { childList: true, subtree: true });\n function getFetchOpts(script) {\n const fetchOpts = {};\n if (script.integrity)\n fetchOpts.integrity = script.integrity;\n if (script.referrerpolicy)\n fetchOpts.referrerPolicy = script.referrerpolicy;\n if (script.crossorigin === 'use-credentials')\n fetchOpts.credentials = 'include';\n else if (script.crossorigin === 'anonymous')\n fetchOpts.credentials = 'omit';\n else\n fetchOpts.credentials = 'same-origin';\n return fetchOpts;\n }\n function processPreload(link) {\n if (link.ep)\n // ep marker = processed\n return;\n link.ep = true;\n // prepopulate the load record\n const fetchOpts = getFetchOpts(link);\n fetch(link.href, fetchOpts);\n }\n};__VITE_IS_MODERN__&&p();","import * as THREE from 'three'\n\nexport default class Core {\n constructor() {\n this.camera = new THREE.PerspectiveCamera()\n this.renderer = new THREE.WebGLRenderer()\n this.scene = new THREE.Scene()\n this.initScene()\n this.initRenderer()\n this.initCamera()\n }\n\n camera: THREE.PerspectiveCamera\n scene: THREE.Scene\n renderer: THREE.Renderer\n\n initCamera = () => {\n this.camera.fov = 50\n this.camera.aspect = window.innerWidth / window.innerHeight\n this.camera.near = 0.01\n this.camera.far = 500\n this.camera.updateProjectionMatrix()\n this.camera.position.set(8, 50, 8)\n\n this.camera.lookAt(100, 30, 100)\n\n window.addEventListener('resize', () => {\n this.camera.aspect = window.innerWidth / window.innerHeight\n this.camera.updateProjectionMatrix()\n })\n }\n\n initScene = () => {\n this.scene = new THREE.Scene()\n const backgroundColor = 0x87ceeb\n\n this.scene.fog = new THREE.Fog(backgroundColor, 1, 96)\n this.scene.background = new THREE.Color(backgroundColor)\n\n const sunLight = new THREE.PointLight(0xffffff, 0.5)\n sunLight.position.set(500, 500, 500)\n this.scene.add(sunLight)\n\n const sunLight2 = new THREE.PointLight(0xffffff, 0.2)\n sunLight2.position.set(-500, 500, -500)\n this.scene.add(sunLight2)\n\n const reflectionLight = new THREE.AmbientLight(0x404040)\n this.scene.add(reflectionLight)\n }\n\n initRenderer = () => {\n this.renderer.setSize(window.innerWidth, window.innerHeight)\n document.body.appendChild(this.renderer.domElement)\n\n window.addEventListener('resize', () => {\n this.renderer.setSize(window.innerWidth, window.innerHeight)\n })\n }\n}\n","export enum Mode {\n walking = 'walking',\n sprinting = 'sprinting',\n flying = 'flying',\n sprintFlying = 'sprintFlying',\n sneaking = 'sneaking'\n}\n\nexport enum Speed {\n // walking = 4.317,\n walking = 5.612,\n sprinting = 5.612,\n // flying = 10.89,\n flying = 21.78,\n sprintFlying = 21.78,\n sneaking = 1.95\n}\nexport default class Player {\n mode = Mode.walking\n speed = Speed[this.mode]\n\n setMode(Mode: Mode) {\n this.mode = Mode\n this.speed = Speed[this.mode]\n }\n falling = 38.4\n\n jump = 1.2522\n\n body = {\n height: 1.8,\n width: 0.5\n }\n}\n","export default \"__VITE_ASSET__fa5e82cb__\"","export default \"__VITE_ASSET__29c9a29e__\"","export default \"__VITE_ASSET__78230e9e__\"","export default \"__VITE_ASSET__1f5d4845__\"","export default \"__VITE_ASSET__be9cf310__\"","export default \"__VITE_ASSET__fb045025__\"","export default \"__VITE_ASSET__fc1a2462__\"","export default \"__VITE_ASSET__6a68c340__\"","export default \"__VITE_ASSET__776aee85__\"","export default \"__VITE_ASSET__f4bf1751__\"","export default \"__VITE_ASSET__be4a7f91__\"","export default \"__VITE_ASSET__fb45cc99__\"","export default \"__VITE_ASSET__0e4d401c__\"","export default \"__VITE_ASSET__17e849a2__\"","export default \"__VITE_ASSET__3e3a8330__\"","import * as THREE from 'three'\nimport stone from '../../static/textures/block/stone.png'\nimport coal_ore from '../../static/textures/block/coal_ore.png'\nimport iron_ore from '../../static/textures/block/iron_ore.png'\nimport grass_side from '../../static/textures/block/grass_block_side.png'\nimport grass_top_green from '../../static/textures/block/grass_top_green.png'\nimport dirt from '../../static/textures/block/dirt.png'\nimport oak_log from '../../static/textures/block/oak_log.png'\nimport oak_log_top from '../../static/textures/block/oak_log_top.png'\nimport oak_leaves from '../../static/textures/block/oak_leaves.png'\nimport sand from '../../static/textures/block/sand.png'\n// import water from '../../static/textures/block/water.png'\nimport oak_wood from '../../static/textures/block/oak_planks.png'\nimport diamond from '../../static/textures/block/diamond_block.png'\nimport quartz from '../../static/textures/block/quartz_block_side.png'\nimport glass from '../../static/textures/block/glass.png'\nimport bedrock from '../../static/textures/block/bedrock.png'\n\nexport enum MaterialType {\n grass = 'grass',\n dirt = 'dirt',\n tree = 'tree',\n leaf = 'leaf',\n sand = 'sand',\n // water = 'water',\n stone = 'stone',\n coal = 'coal',\n wood = 'wood',\n diamond = 'diamond',\n quartz = 'quartz',\n glass = 'glass',\n bedrock = 'bedrock'\n}\nlet loader = new THREE.TextureLoader()\n\n// load texture\nconst grassTopMaterial = loader.load(grass_top_green)\nconst grassMaterial = loader.load(grass_side)\nconst treeMaterial = loader.load(oak_log)\nconst treeTopMaterial = loader.load(oak_log_top)\nconst dirtMaterial = loader.load(dirt)\nconst stoneMaterial = loader.load(stone)\nconst coalMaterial = loader.load(coal_ore)\nconst ironMaterial = loader.load(iron_ore)\nconst leafMaterial = loader.load(oak_leaves)\nconst sandMaterial = loader.load(sand)\n// const waterMaterial = loader.load(water)\nconst woodMaterial = loader.load(oak_wood)\nconst diamondMaterial = loader.load(diamond)\nconst quartzMaterial = loader.load(quartz)\nconst glassMaterial = loader.load(glass)\nconst bedrockMaterial = loader.load(bedrock)\n\n// pixelate texture\ngrassTopMaterial.magFilter = THREE.NearestFilter\ngrassMaterial.magFilter = THREE.NearestFilter\ntreeMaterial.magFilter = THREE.NearestFilter\ntreeTopMaterial.magFilter = THREE.NearestFilter\ndirtMaterial.magFilter = THREE.NearestFilter\nstoneMaterial.magFilter = THREE.NearestFilter\ncoalMaterial.magFilter = THREE.NearestFilter\nironMaterial.magFilter = THREE.NearestFilter\nleafMaterial.magFilter = THREE.NearestFilter\nsandMaterial.magFilter = THREE.NearestFilter\n// waterMaterial.magFilter = THREE.NearestFilter\nwoodMaterial.magFilter = THREE.NearestFilter\ndiamondMaterial.magFilter = THREE.NearestFilter\nquartzMaterial.magFilter = THREE.NearestFilter\nglassMaterial.magFilter = THREE.NearestFilter\nbedrockMaterial.magFilter = THREE.NearestFilter\n\nexport default class Materials {\n materials = {\n grass: [\n new THREE.MeshStandardMaterial({ map: grassMaterial }),\n new THREE.MeshStandardMaterial({ map: grassMaterial }),\n new THREE.MeshStandardMaterial({\n map: grassTopMaterial\n }),\n new THREE.MeshStandardMaterial({ map: dirtMaterial }),\n new THREE.MeshStandardMaterial({ map: grassMaterial }),\n new THREE.MeshStandardMaterial({ map: grassMaterial })\n ],\n dirt: new THREE.MeshStandardMaterial({ map: dirtMaterial }),\n sand: new THREE.MeshStandardMaterial({ map: sandMaterial }),\n tree: [\n new THREE.MeshStandardMaterial({ map: treeMaterial }),\n new THREE.MeshStandardMaterial({ map: treeMaterial }),\n new THREE.MeshStandardMaterial({ map: treeTopMaterial }),\n new THREE.MeshStandardMaterial({ map: treeTopMaterial }),\n new THREE.MeshStandardMaterial({ map: treeMaterial }),\n new THREE.MeshStandardMaterial({ map: treeMaterial })\n ],\n leaf: new THREE.MeshStandardMaterial({\n map: leafMaterial,\n color: new THREE.Color(0, 1, 0),\n transparent: true\n }),\n // water: new THREE.MeshStandardMaterial({\n // map: waterMaterial,\n // transparent: true,\n // opacity: 0.7\n // }),\n stone: new THREE.MeshStandardMaterial({ map: stoneMaterial }),\n coal: new THREE.MeshStandardMaterial({ map: coalMaterial }),\n wood: new THREE.MeshStandardMaterial({ map: woodMaterial }),\n diamond: new THREE.MeshStandardMaterial({ map: diamondMaterial }),\n quartz: new THREE.MeshStandardMaterial({ map: quartzMaterial }),\n glass: new THREE.MeshStandardMaterial({\n map: glassMaterial,\n transparent: true\n }),\n bedrock: new THREE.MeshStandardMaterial({ map: bedrockMaterial })\n }\n\n get = (\n type: MaterialType\n ): THREE.MeshStandardMaterial | THREE.MeshStandardMaterial[] => {\n return this.materials[type]\n }\n}\n","import { BlockType } from '../index'\n\n/**\n * Custom block\n */\nexport default class Block {\n object: any\n constructor(\n x: number,\n y: number,\n z: number,\n type: BlockType,\n placed: boolean\n ) {\n this.x = x\n this.y = y\n this.z = z\n this.type = type\n this.placed = placed\n }\n x: number\n y: number\n z: number\n type: BlockType\n placed: boolean\n}\n","import * as THREE from 'three'\nimport Terrain from '..'\n\n/**\n * Highlight block on crosshair\n */\nexport default class BlockHighlight {\n constructor(\n scene: THREE.Scene,\n camera: THREE.PerspectiveCamera,\n terrain: Terrain\n ) {\n this.camera = camera\n this.scene = scene\n this.terrain = terrain\n this.raycaster = new THREE.Raycaster()\n this.raycaster.far = 8\n }\n\n scene: THREE.Scene\n camera: THREE.PerspectiveCamera\n terrain: Terrain\n raycaster: THREE.Raycaster\n block: THREE.Intersection | null = null\n\n // highlight block mesh\n geometry = new THREE.BoxGeometry(1.01, 1.01, 1.01)\n material = new THREE.MeshStandardMaterial({\n transparent: true,\n opacity: 0.25\n // depthWrite: false\n })\n mesh = new THREE.Mesh(new THREE.BoxGeometry(), this.material)\n\n // block simulation\n index = 0\n instanceMesh = new THREE.InstancedMesh(\n new THREE.BoxGeometry(),\n new THREE.MeshBasicMaterial(),\n 1000\n )\n\n update() {\n // remove last highlight and reset block simulation\n this.scene.remove(this.mesh)\n this.index = 0\n this.instanceMesh.instanceMatrix = new THREE.InstancedBufferAttribute(\n new Float32Array(1000 * 16),\n 16\n )\n\n const position = this.camera.position\n const matrix = new THREE.Matrix4()\n const idMap = new Map<string, number>()\n const noise = this.terrain.noise\n\n let xPos = Math.round(position.x)\n let zPos = Math.round(position.z)\n\n for (let i = -8; i < 8; i++) {\n for (let j = -8; j < 8; j++) {\n // check terrain\n let x = xPos + i\n let z = zPos + j\n let y =\n Math.floor(\n noise.get(x / noise.gap, z / noise.gap, noise.seed) * noise.amp\n ) + 30\n\n idMap.set(`${x}_${y}_${z}`, this.index)\n matrix.setPosition(x, y, z)\n this.instanceMesh.setMatrixAt(this.index++, matrix)\n\n let stoneOffset =\n noise.get(x / noise.stoneGap, z / noise.stoneGap, noise.stoneSeed) *\n noise.stoneAmp\n\n let treeOffset =\n noise.get(x / noise.treeGap, z / noise.treeGap, noise.treeSeed) *\n noise.treeAmp\n\n // check tree\n if (\n treeOffset > noise.treeThreshold &&\n y - 30 >= -3 &&\n stoneOffset < noise.stoneThreshold\n ) {\n for (let t = 1; t <= noise.treeHeight; t++) {\n idMap.set(`${x}_${y + t}_${z}`, this.index)\n matrix.setPosition(x, y + t, z)\n this.instanceMesh.setMatrixAt(this.index++, matrix)\n }\n\n // leaf\n // for (let i = -3; i < 3; i++) {\n // for (let j = -3; j < 3; j++) {\n // for (let k = -3; k < 3; k++) {\n // if (i === 0 && k === 0) {\n // continue\n // }\n // let leafOffset =\n // noise.get(\n // (x + i + j) / noise.leafGap,\n // (z + k) / noise.leafGap,\n // noise.leafSeed\n // ) * noise.leafAmp\n\n // if (leafOffset > noise.leafThreshold) {\n // idMap.set(\n // `${x + i}_${y + noise.treeHeight + j}_${z + k}`,\n // this.index\n // )\n // matrix.setPosition(x + i, y + noise.treeHeight + j, z + k)\n // this.instanceMesh.setMatrixAt(this.index++, matrix)\n // }\n // }\n // }\n // }\n }\n }\n }\n\n // check custom blocks\n for (const block of this.terrain.customBlocks) {\n if (block.placed) {\n matrix.setPosition(block.x, block.y, block.z)\n this.instanceMesh.setMatrixAt(this.index++, matrix)\n } else {\n if (idMap.has(`${block.x}_${block.y}_${block.z}`)) {\n let id = idMap.get(`${block.x}_${block.y}_${block.z}`)\n this.instanceMesh.setMatrixAt(\n id!,\n new THREE.Matrix4().set(\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0\n )\n )\n }\n }\n }\n\n // highlight new block\n this.raycaster.setFromCamera({ x: 0, y: 0 }, this.camera)\n this.block = this.raycaster.intersectObject(this.instanceMesh)[0]\n if (\n this.block &&\n this.block.object instanceof THREE.InstancedMesh &&\n typeof this.block.instanceId === 'number'\n ) {\n this.mesh = new THREE.Mesh(this.geometry, this.material)\n let matrix = new THREE.Matrix4()\n this.block.object.getMatrixAt(this.block.instanceId, matrix)\n const position = new THREE.Vector3().setFromMatrixPosition(matrix)\n\n this.mesh.position.set(position.x, position.y, position.z)\n this.scene.add(this.mesh)\n }\n }\n}\n","import { ImprovedNoise } from 'three/examples/jsm/math/ImprovedNoise'\n// import { SimplexNoise } from 'three/examples/jsm/math/SimplexNoise'\n\nexport default class Noise {\n noise = new ImprovedNoise()\n seed = Math.random()\n gap = 22\n amp = 8\n\n stoneSeed = this.seed * 0.4\n stoneGap = 12\n stoneAmp = 8\n stoneThreshold = 3.5\n\n coalSeed = this.seed * 0.5\n coalGap = 3\n coalAmp = 8\n coalThreshold = 3\n\n treeSeed = this.seed * 0.7\n treeGap = 2\n treeAmp = 6\n treeHeight = 10\n treeThreshold = 4\n\n leafSeed = this.seed * 0.8\n leafGap = 2\n leafAmp = 5\n leafThreshold = -0.03\n\n get = (x: number, y: number, z: number) => {\n return this.noise.noise(x, y, z)\n }\n}\n","import * as THREE from 'three'\nimport Materials, { MaterialType } from './mesh/materials'\nimport Block from './mesh/block'\nimport Highlight from './highlight'\nimport Noise from './noise'\n\nimport Generate from './worker/generate?worker'\n\nexport enum BlockType {\n grass = 0,\n sand = 1,\n tree = 2,\n leaf = 3,\n dirt = 4,\n stone = 5,\n coal = 6,\n wood = 7,\n diamond = 8,\n quartz = 9,\n glass = 10,\n bedrock = 11\n}\nexport default class Terrain {\n constructor(scene: THREE.Scene, camera: THREE.PerspectiveCamera) {\n this.scene = scene\n this.camera = camera\n this.maxCount =\n (this.distance * this.chunkSize * 2 + this.chunkSize) ** 2 + 500\n this.highlight = new Highlight(scene, camera, this)\n this.scene.add(this.cloud)\n\n // generate worker callback handler\n this.generateWorker.onmessage = (\n msg: MessageEvent<{\n idMap: Map<string, number>\n arrays: ArrayLike<number>[]\n blocksCount: number[]\n }>\n ) => {\n this.resetBlocks()\n this.idMap = msg.data.idMap\n this.blocksCount = msg.data.blocksCount\n\n for (let i = 0; i < msg.data.arrays.length; i++) {\n this.blocks[i].instanceMatrix = new THREE.InstancedBufferAttribute(\n (this.blocks[i].instanceMatrix.array = msg.data.arrays[i]),\n 16\n )\n }\n\n for (const block of this.blocks) {\n block.instanceMatrix.needsUpdate = true\n }\n }\n }\n // core properties\n scene: THREE.Scene\n camera: THREE.PerspectiveCamera\n distance = 3\n chunkSize = 24\n\n // terrain properties\n maxCount: number\n chunk = new THREE.Vector2(0, 0)\n previousChunk = new THREE.Vector2(0, 0)\n noise = new Noise()\n\n // materials\n materials = new Materials()\n materialType = [\n MaterialType.grass,\n MaterialType.sand,\n MaterialType.tree,\n MaterialType.leaf,\n MaterialType.dirt,\n MaterialType.stone,\n MaterialType.coal,\n MaterialType.wood,\n MaterialType.diamond,\n MaterialType.quartz,\n MaterialType.glass,\n MaterialType.bedrock\n ]\n\n // other properties\n blocks: THREE.InstancedMesh[] = []\n blocksCount: number[] = []\n blocksFactor = [1, 0.2, 0.1, 0.7, 0.1, 0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]\n\n customBlocks: Block[] = []\n highlight: Highlight\n\n idMap = new Map<string, number>()\n generateWorker = new Generate()\n\n // cloud\n cloud = new THREE.InstancedMesh(\n new THREE.BoxGeometry(20, 5, 14),\n new THREE.MeshStandardMaterial({\n transparent: true,\n color: 0xffffff,\n opacity: 0.4\n }),\n 1000\n )\n cloudCount = 0\n cloudGap = 5\n\n getCount = (type: BlockType) => {\n return this.blocksCount[type]\n }\n\n setCount = (type: BlockType) => {\n this.blocksCount[type] = this.blocksCount[type] + 1\n }\n\n initBlocks = () => {\n // reset\n for (const block of this.blocks) {\n this.scene.remove(block)\n }\n this.blocks = []\n\n // create instance meshes\n const geometry = new THREE.BoxGeometry()\n\n for (let i = 0; i < this.materialType.length; i++) {\n let block = new THREE.InstancedMesh(\n geometry,\n this.materials.get(this.materialType[i]),\n this.maxCount * this.blocksFactor[i]\n )\n block.name = BlockType[i]\n this.blocks.push(block)\n this.scene.add(block)\n }\n\n this.blocksCount = new Array(this.materialType.length).fill(0)\n }\n\n resetBlocks = () => {\n // reest count and instance matrix\n for (let i = 0; i < this.blocks.length; i++) {\n this.blocks[i].instanceMatrix = new THREE.InstancedBufferAttribute(\n new Float32Array(this.maxCount * this.blocksFactor[i] * 16),\n 16\n )\n }\n }\n\n generate = () => {\n this.blocksCount = new Array(this.blocks.length).fill(0)\n // post work to generate worker\n this.generateWorker.postMessage({\n distance: this.distance,\n chunk: this.chunk,\n noiseSeed: this.noise.seed,\n treeSeed: this.noise.treeSeed,\n stoneSeed: this.noise.stoneSeed,\n coalSeed: this.noise.coalSeed,\n idMap: new Map<string, number>(),\n blocksFactor: this.blocksFactor,\n blocksCount: this.blocksCount,\n customBlocks: this.customBlocks,\n chunkSize: this.chunkSize\n })\n\n // cloud\n\n if (this.cloudGap++ > 5) {\n this.cloudGap = 0\n this.cloud.instanceMatrix = new THREE.InstancedBufferAttribute(\n new Float32Array(1000 * 16),\n 16\n )\n this.cloudCount = 0\n for (\n let x =\n -this.chunkSize * this.distance * 3 + this.chunkSize * this.chunk.x;\n x <\n this.chunkSize * this.distance * 3 +\n this.chunkSize +\n this.chunkSize * this.chunk.x;\n x += 20\n ) {\n for (\n let z =\n -this.chunkSize * this.distance * 3 + this.chunkSize * this.chunk.y;\n z <\n this.chunkSize * this.distance * 3 +\n this.chunkSize +\n this.chunkSize * this.chunk.y;\n z += 20\n ) {\n const matrix = new THREE.Matrix4()\n matrix.setPosition(x, 80 + (Math.random() - 0.5) * 30, z)\n\n if (Math.random() > 0.8) {\n this.cloud.setMatrixAt(this.cloudCount++, matrix)\n }\n }\n }\n this.cloud.instanceMatrix.needsUpdate = true\n }\n }\n\n // generate adjacent blocks after removing a block (vertical infinity world)\n generateAdjacentBlocks = (position: THREE.Vector3) => {\n const { x, y, z } = position\n const noise = this.noise\n const yOffset = Math.floor(\n noise.get(x / noise.gap, z / noise.gap, noise.seed) * noise.amp\n )\n\n if (y > 30 + yOffset) {\n return\n }\n\n const stoneOffset =\n noise.get(x / noise.stoneGap, z / noise.stoneGap, noise.stoneSeed) *\n noise.stoneAmp\n\n let type: BlockType\n\n if (stoneOffset > noise.stoneThreshold || y < 23) {\n type = BlockType.stone\n } else {\n if (yOffset < -3) {\n type = BlockType.sand\n } else {\n type = BlockType.dirt\n }\n }\n\n this.buildBlock(new THREE.Vector3(x, y - 1, z), type)\n this.buildBlock(new THREE.Vector3(x, y + 1, z), type)\n this.buildBlock(new THREE.Vector3(x - 1, y, z), type)\n this.buildBlock(new THREE.Vector3(x + 1, y, z), type)\n this.buildBlock(new THREE.Vector3(x, y, z - 1), type)\n this.buildBlock(new THREE.Vector3(x, y, z + 1), type)\n\n this.blocks[type].instanceMatrix.needsUpdate = true\n }\n\n buildBlock = (position: THREE.Vector3, type: BlockType) => {\n const noise = this.noise\n // check if it's natural terrain\n const yOffset = Math.floor(\n noise.get(position.x / noise.gap, position.z / noise.gap, noise.seed) *\n noise.amp\n )\n if (position.y >= 30 + yOffset || position.y < 0) {\n return\n }\n\n position.y === 0 && (type = BlockType.bedrock)\n\n // check custom blocks\n for (const block of this.customBlocks) {\n if (\n block.x === position.x &&\n block.y === position.y &&\n block.z === position.z\n ) {\n return\n }\n }\n\n // build block\n this.customBlocks.push(\n new Block(position.x, position.y, position.z, type, true)\n )\n\n const matrix = new THREE.Matrix4()\n matrix.setPosition(position)\n this.blocks[type].setMatrixAt(this.getCount(type), matrix)\n this.blocks[type].instanceMatrix.needsUpdate = true\n this.setCount(type)\n }\n\n update = () => {\n this.chunk.set(\n Math.floor(this.camera.position.x / this.chunkSize),\n Math.floor(this.camera.position.z / this.chunkSize)\n )\n\n //generate terrain when getting into new chunk\n if (\n this.chunk.x !== this.previousChunk.x ||\n this.chunk.y !== this.previousChunk.y\n ) {\n this.generate()\n }\n\n this.previousChunk.copy(this.chunk)\n\n this.highlight.update()\n }\n}\n","export const htmlToDom = (html: string) => {\n const templateDom = document.createElement('template')\n templateDom.innerHTML = html\n window.document.body.appendChild(templateDom.content)\n}\n\nexport const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(\n navigator.userAgent\n)\n","import * as THREE from 'three'\nimport { PointerLockControls } from 'three/examples/jsm/controls/PointerLockControls'\nimport Player, { Mode } from '../player'\nimport Terrain, { BlockType } from '../terrain'\n\nimport Block from '../terrain/mesh/block'\nimport Noise from '../terrain/noise'\nimport Audio from '../audio'\nimport { isMobile } from '../utils'\nenum Side {\n front,\n back,\n left,\n right,\n down,\n up\n}\n\nexport default class Control {\n constructor(\n scene: THREE.Scene,\n camera: THREE.PerspectiveCamera,\n player: Player,\n terrain: Terrain,\n audio: Audio\n ) {\n this.scene = scene\n this.camera = camera\n this.player = player\n this.terrain = terrain\n this.control = new PointerLockControls(camera, document.body)\n this.audio = audio\n\n this.raycaster = new THREE.Raycaster()\n this.raycaster.far = 8\n this.far = this.player.body.height\n\n this.initRayCaster()\n this.initEventListeners()\n }\n\n // core properties\n scene: THREE.Scene\n camera: THREE.PerspectiveCamera\n player: Player\n terrain: Terrain\n control: PointerLockControls\n audio: Audio\n velocity = new THREE.Vector3(0, 0, 0)\n\n // collide and jump properties\n frontCollide = false\n backCollide = false\n leftCollide = false\n rightCollide = false\n downCollide = true\n upCollide = false\n isJumping = false\n\n raycasterDown = new THREE.Raycaster()\n raycasterUp = new THREE.Raycaster()\n raycasterFront = new THREE.Raycaster()\n raycasterBack = new THREE.Raycaster()\n raycasterRight = new THREE.Raycaster()\n raycasterLeft = new THREE.Raycaster()\n\n tempMesh = new THREE.InstancedMesh(\n new THREE.BoxGeometry(1, 1, 1),\n new THREE.MeshBasicMaterial(),\n 100\n )\n tempMeshMatrix = new THREE.InstancedBufferAttribute(\n new Float32Array(100 * 16),\n 16\n )\n\n // other properties\n p1 = performance.now()\n p2 = performance.now()\n raycaster: THREE.Raycaster\n far: number\n\n holdingBlock = BlockType.grass\n holdingBlocks = [\n BlockType.grass,\n BlockType.stone,\n BlockType.tree,\n BlockType.wood,\n BlockType.diamond,\n BlockType.quartz,\n BlockType.glass,\n BlockType.grass,\n BlockType.grass,\n BlockType.grass\n ]\n holdingIndex = 0\n wheelGap = false\n clickInterval?: ReturnType<typeof setInterval>\n jumpInterval?: ReturnType<typeof setInterval>\n mouseHolding = false\n spaceHolding = false\n\n initRayCaster = () => {\n this.raycasterUp.ray.direction = new THREE.Vector3(0, 1, 0)\n this.raycasterDown.ray.direction = new THREE.Vector3(0, -1, 0)\n this.raycasterFront.ray.direction = new THREE.Vector3(1, 0, 0)\n this.raycasterBack.ray.direction = new THREE.Vector3(-1, 0, 0)\n this.raycasterLeft.ray.direction = new THREE.Vector3(0, 0, -1)\n this.raycasterRight.ray.direction = new THREE.Vector3(0, 0, 1)\n\n this.raycasterUp.far = 1.2\n this.raycasterDown.far = this.player.body.height\n this.raycasterFront.far = this.player.body.width\n this.raycasterBack.far = this.player.body.width\n this.raycasterLeft.far = this.player.body.width\n this.raycasterRight.far = this.player.body.width\n }\n\n setMovementHandler = (e: KeyboardEvent) => {\n if (e.repeat) {\n return\n }\n\n switch (e.key) {\n case 'q':\n if (this.player.mode === Mode.walking) {\n this.player.setMode(Mode.flying)\n } else {\n this.player.setMode(Mode.walking)\n }\n this.velocity.y = 0\n this.velocity.x = 0\n this.velocity.z = 0\n break\n case 'w':\n case 'W':\n this.velocity.x += this.player.speed\n break\n case 's':\n case 'S':\n this.velocity.x -= this.player.speed\n break\n case 'a':\n case 'A':\n this.velocity.z -= this.player.speed\n break\n case 'd':\n case 'D':\n this.velocity.z += this.player.speed\n break\n case ' ':\n if (this.player.mode === Mode.walking) {\n // jump\n if (!this.isJumping) {\n this.velocity.y = 8\n this.isJumping = true\n this.downCollide = false\n this.far = 0\n setTimeout(() => {\n this.far = this.player.body.height\n }, 300)\n }\n } else {\n this.velocity.y += this.player.speed\n }\n if (this.player.mode === Mode.walking && !this.spaceHolding) {\n this.spaceHolding = true\n this.jumpInterval = setInterval(() => {\n this.setMovementHandler(e)\n }, 10)\n }\n break\n case 'Shift':\n if (this.player.mode === Mode.walking) {\n } else {\n this.velocity.y -= this.player.speed\n }\n break\n default:\n break\n }\n }\n\n resetMovementHandler = (e: KeyboardEvent) => {\n if (e.repeat) {\n return\n }\n\n switch (e.key) {\n case 'w':\n case 'W':\n this.velocity.x = 0\n break\n case 's':\n case 'S':\n this.velocity.x = 0\n break\n case 'a':\n case 'A':\n this.velocity.z = 0\n break\n case 'd':\n case 'D':\n this.velocity.z = 0\n break\n case ' ':\n this.jumpInterval && clearInterval(this.jumpInterval)\n this.spaceHolding = false\n if (this.player.mode === Mode.walking) {\n return\n }\n this.velocity.y = 0\n break\n case 'Shift':\n if (this.player.mode === Mode.walking) {\n return\n }\n this.velocity.y = 0\n break\n default:\n break\n }\n }\n\n mousedownHandler = (e: MouseEvent) => {\n e.preventDefault()\n // let p1 = performance.now()\n this.raycaster.setFromCamera({ x: 0, y: 0 }, this.camera)\n const block = this.raycaster.intersectObjects(this.terrain.blocks)[0]\n const matrix = new THREE.Matrix4()\n\n switch (e.button) {\n // left click to remove block\n case 0:\n {\n if (block && block.object instanceof THREE.InstancedMesh) {\n // calculate position\n block.object.getMatrixAt(block.instanceId!, matrix)\n const position = new THREE.Vector3().setFromMatrixPosition(matrix)\n\n // don't remove bedrock\n if (\n (BlockType[block.object.name as any] as unknown as BlockType) ===\n BlockType.bedrock\n ) {\n this.terrain.generateAdjacentBlocks(position)\n return\n }\n\n // remove the block\n block.object.setMatrixAt(\n block.instanceId!,\n new THREE.Matrix4().set(\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0\n )\n )\n\n // block and sound effect\n this.audio.playSound(\n BlockType[block.object.name as any] as unknown as BlockType\n )\n\n const mesh = new THREE.Mesh(\n new THREE.BoxGeometry(1, 1, 1),\n this.terrain.materials.get(\n this.terrain.materialType[\n parseInt(BlockType[block.object.name as any])\n ]\n )\n )\n mesh.position.set(position.x, position.y, position.z)\n this.scene.add(mesh)\n const time = performance.now()\n let raf = 0\n const animate = () => {\n if (performance.now() - time > 250) {\n this.scene.remove(mesh)\n cancelAnimationFrame(raf)\n return\n }\n raf = requestAnimationFrame(animate)\n mesh.geometry.scale(0.85, 0.85, 0.85)\n }\n animate()\n\n // update\n block.object.instanceMatrix.needsUpdate = true\n\n // check existence\n let existed = false\n for (const customBlock of this.terrain.customBlocks) {\n if (\n customBlock.x === position.x &&\n customBlock.y === position.y &&\n customBlock.z === position.z\n ) {\n existed = true\n customBlock.placed = false\n }\n }\n\n // add to custom blocks when it's not existed\n if (!existed) {\n this.terrain.customBlocks.push(\n new Block(\n position.x,\n position.y,\n position.z,\n BlockType[block.object.name as any] as unknown as BlockType,\n false\n )\n )\n }\n\n // generate adjacent blocks\n this.terrain.generateAdjacentBlocks(position)\n }\n }\n break\n\n // right click to put block\n case 2:\n {\n if (block && block.object instanceof THREE.InstancedMesh) {\n // calculate normal and position\n const normal = block.face!.normal\n block.object.getMatrixAt(block.instanceId!, matrix)\n const position = new THREE.Vector3().setFromMatrixPosition(matrix)\n\n // return when block overlaps with player\n if (\n position.x + normal.x === Math.round(this.camera.position.x) &&\n position.z + normal.z === Math.round(this.camera.position.z) &&\n (position.y + normal.y === Math.round(this.camera.position.y) ||\n position.y + normal.y ===\n Math.round(this.camera.position.y - 1))\n ) {\n return\n }\n\n // put the block\n matrix.setPosition(\n normal.x + position.x,\n normal.y + position.y,\n normal.z + position.z\n )\n this.terrain.blocks[this.holdingBlock].setMatrixAt(\n this.terrain.getCount(this.holdingBlock),\n matrix\n )\n this.terrain.setCount(this.holdingBlock)\n\n //sound effect\n this.audio.playSound(this.holdingBlock)\n\n // update\n this.terrain.blocks[this.holdingBlock].instanceMatrix.needsUpdate =\n true\n\n // add to custom blocks\n this.terrain.customBlocks.push(\n new Block(\n normal.x + position.x,\n normal.y + position.y,\n normal.z + position.z,\n this.holdingBlock,\n true\n )\n )\n }\n }\n break\n default:\n break\n }\n\n if (!isMobile && !this.mouseHolding) {\n this.mouseHolding = true\n this.clickInterval = setInterval(() => {\n this.mousedownHandler(e)\n }, 333)\n }\n\n // console.log(performance.now() - p1)\n }\n mouseupHandler = () => {\n this.clickInterval && clearInterval(this.clickInterval)\n this.mouseHolding = false\n }\n\n changeHoldingBlockHandler = (e: KeyboardEvent) => {\n if (isNaN(parseInt(e.key)) || e.key === '0') {\n return\n }\n this.holdingIndex = parseInt(e.key) - 1\n\n this.holdingBlock = this.holdingBlocks[this.holdingIndex] ?? BlockType.grass\n }\n\n wheelHandler = (e: WheelEvent) => {\n if (!this.wheelGap) {\n this.wheelGap = true\n setTimeout(() => {\n this.wheelGap = false\n }, 100)\n if (e.deltaY > 0) {\n this.holdingIndex++\n this.holdingIndex > 9 && (this.holdingIndex = 0)\n } else if (e.deltaY < 0) {\n this.holdingIndex--\n this.holdingIndex < 0 && (this.holdingIndex = 9)\n }\n this.holdingBlock =\n this.holdingBlocks[this.holdingIndex] ?? BlockType.grass\n }\n }\n\n initEventListeners = () => {\n // add / remove handler when pointer lock / unlock\n document.addEventListener('pointerlockchange', () => {\n if (document.pointerLockElement) {\n document.body.addEventListener(\n 'keydown',\n this.changeHoldingBlockHandler\n )\n document.body.addEventListener('wheel', this.wheelHandler)\n document.body.addEventListener('keydown', this.setMovementHandler)\n document.body.addEventListener('keyup', this.resetMovementHandler)\n document.body.addEventListener('mousedown', this.mousedownHandler)\n document.body.addEventListener('mouseup', this.mouseupHandler)\n } else {\n document.body.removeEventListener(\n 'keydown',\n this.changeHoldingBlockHandler\n )\n document.body.removeEventListener('wheel', this.wheelHandler)\n document.body.removeEventListener('keydown', this.setMovementHandler)\n document.body.removeEventListener('keyup', this.resetMovementHandler)\n document.body.removeEventListener('mousedown', this.mousedownHandler)\n document.body.removeEventListener('mouseup', this.mouseupHandler)\n this.velocity = new THREE.Vector3(0, 0, 0)\n }\n })\n }\n\n // move along X with direction factor\n moveX(distance: number, delta: number) {\n this.camera.position.x +=\n distance * (this.player.speed / Math.PI) * 2 * delta\n }\n\n // move along Z with direction factor\n moveZ = (distance: number, delta: number) => {\n this.camera.position.z +=\n distance * (this.player.speed / Math.PI) * 2 * delta\n }\n\n // collide checking\n collideCheckAll = (\n position: THREE.Vector3,\n noise: Noise,\n customBlocks: Block[],\n far: number\n ) => {\n this.collideCheck(Side.down, position, noise, customBlocks, far)\n this.collideCheck(Side.front, position, noise, customBlocks)\n this.collideCheck(Side.back, position, noise, customBlocks)\n this.collideCheck(Side.left, position, noise, customBlocks)\n this.collideCheck(Side.right, position, noise, customBlocks)\n this.collideCheck(Side.up, position, noise, customBlocks)\n }\n\n collideCheck = (\n side: Side,\n position: THREE.Vector3,\n noise: Noise,\n customBlocks: Block[],\n far: number = this.player.body.width\n ) => {\n const matrix = new THREE.Matrix4()\n\n //reset simulation blocks\n let index = 0\n this.tempMesh.instanceMatrix = new THREE.InstancedBufferAttribute(\n new Float32Array(100 * 16),\n 16\n )\n\n // block to remove\n let removed = false\n let treeRemoved = new Array<boolean>(\n this.terrain.noise.treeHeight + 1\n ).fill(false)\n\n // get block position\n let x = Math.round(position.x)\n let z = Math.round(position.z)\n\n switch (side) {\n case Side.front:\n x++\n this.raycasterFront.ray.origin = position\n break\n case Side.back:\n x--\n this.raycasterBack.ray.origin = position\n break\n case Side.left:\n z--\n this.raycasterLeft.ray.origin = position\n break\n case Side.right:\n z++\n this.raycasterRight.ray.origin = position\n break\n case Side.down:\n this.raycasterDown.ray.origin = position\n this.raycasterDown.far = far\n break\n case Side.up:\n this.raycasterUp.ray.origin = new THREE.Vector3().copy(position)\n this.raycasterUp.ray.origin.y--\n break\n }\n\n let y =\n Math.floor(\n noise.get(x / noise.gap, z / noise.gap, noise.seed) * noise.amp\n ) + 30\n\n // check custom blocks\n for (const block of customBlocks) {\n if (block.x === x && block.z === z) {\n if (block.placed) {\n // placed blocks\n matrix.setPosition(block.x, block.y, block.z)\n this.tempMesh.setMatrixAt(index++, matrix)\n } else if (block.y === y) {\n // removed blocks\n removed = true\n } else {\n for (let i = 1; i <= this.terrain.noise.treeHeight; i++) {\n if (block.y === y + i) {\n treeRemoved[i] = true\n }\n }\n }\n }\n }\n\n // update simulation blocks (ignore removed blocks)\n if (!removed) {\n matrix.setPosition(x, y, z)\n this.tempMesh.setMatrixAt(index++, matrix)\n }\n for (let i = 1; i <= this.terrain.noise.treeHeight; i++) {\n if (!treeRemoved[i]) {\n let treeOffset =\n noise.get(x / noise.treeGap, z / noise.treeGap, noise.treeSeed) *\n noise.treeAmp\n\n let stoneOffset =\n noise.get(x / noise.stoneGap, z / noise.stoneGap, noise.stoneSeed) *\n noise.stoneAmp\n\n if (\n treeOffset > noise.treeThreshold &&\n y >= 27 &&\n stoneOffset < noise.stoneThreshold\n ) {\n matrix.setPosition(x, y + i, z)\n this.tempMesh.setMatrixAt(index++, matrix)\n }\n }\n }\n\n this.tempMesh.instanceMatrix.needsUpdate = true\n\n // update collide\n const origin = new THREE.Vector3(position.x, position.y - 1, position.z)\n switch (side) {\n case Side.front: {\n const c1 = this.raycasterFront.intersectObject(this.tempMesh).length\n this.raycasterFront.ray.origin = origin\n const c2 = this.raycasterFront.intersectObject(this.tempMesh).length\n c1 || c2 ? (this.frontCollide = true) : (this.frontCollide = false)\n\n break\n }\n case Side.back: {\n const c1 = this.raycasterBack.intersectObject(this.tempMesh).length\n this.raycasterBack.ray.origin = origin\n const c2 = this.raycasterBack.intersectObject(this.tempMesh).length\n c1 || c2 ? (this.backCollide = true) : (this.backCollide = false)\n break\n }\n case Side.left: {\n const c1 = this.raycasterLeft.intersectObject(this.tempMesh).length\n this.raycasterLeft.ray.origin = origin\n const c2 = this.raycasterLeft.intersectObject(this.tempMesh).length\n c1 || c2 ? (this.leftCollide = true) : (this.leftCollide = false)\n break\n }\n case Side.right: {\n const c1 = this.raycasterRight.intersectObject(this.tempMesh).length\n this.raycasterRight.ray.origin = origin\n const c2 = this.raycasterRight.intersectObject(this.tempMesh).length\n c1 || c2 ? (this.rightCollide = true) : (this.rightCollide = false)\n break\n }\n case Side.down: {\n const c1 = this.raycasterDown.intersectObject(this.tempMesh).length\n c1 ? (this.downCollide = true) : (this.downCollide = false)\n break\n }\n case Side.up: {\n const c1 = this.raycasterUp.intersectObject(this.tempMesh).length\n c1 ? (this.upCollide = true) : (this.upCollide = false)\n break\n }\n }\n }\n\n update = () => {\n this.p1 = performance.now()\n const delta = (this.p1 - this.p2) / 1000\n if (\n // dev mode\n this.player.mode === Mode.flying\n ) {\n this.control.moveForward(this.velocity.x * delta)\n this.control.moveRight(this.velocity.z * delta)\n this.camera.position.y += this.velocity.y * delta\n } else {\n // normal mode\n this.collideCheckAll(\n this.camera.position,\n this.terrain.noise,\n this.terrain.customBlocks,\n this.far - this.velocity.y * delta\n )\n\n // gravity\n if (Math.abs(this.velocity.y) < this.player.falling) {\n this.velocity.y -= 25 * delta\n }\n\n // up collide handler\n if (this.upCollide) {\n this.velocity.y = -225 * delta\n this.far = this.player.body.height\n }\n\n // down collide and jump handler\n if (this.downCollide && !this.isJumping) {\n this.velocity.y = 0\n } else if (this.downCollide && this.isJumping) {\n this.isJumping = false\n }\n\n // side collide handler\n let vector = new THREE.Vector3(0, 0, -1).applyQuaternion(\n this.camera.quaternion\n )\n let direction = Math.atan2(vector.x, vector.z)\n if (\n this.frontCollide ||\n this.backCollide ||\n this.leftCollide ||\n this.rightCollide\n ) {\n // collide front (positive x)\n if (this.frontCollide) {\n // camera front\n if (direction < Math.PI && direction > 0 && this.velocity.x > 0) {\n if (\n (!this.leftCollide && direction > Math.PI / 2) ||\n (!this.rightCollide && direction < Math.PI / 2)\n ) {\n this.moveZ(Math.PI / 2 - direction, delta)\n }\n } else if (\n !this.leftCollide &&\n !this.rightCollide &&\n this.velocity.x > 0\n ) {\n this.control.moveForward(this.velocity.x * delta)\n }\n\n // camera back\n if (direction < 0 && direction > -Math.PI && this.velocity.x < 0) {\n if (\n (!this.leftCollide && direction > -Math.PI / 2) ||\n (!this.rightCollide && direction < -Math.PI / 2)\n ) {\n this.moveZ(-Math.PI / 2 - direction, delta)\n }\n } else if (\n !this.leftCollide &&\n !this.rightCollide &&\n this.velocity.x < 0\n ) {\n this.control.moveForward(this.velocity.x * delta)\n }\n\n // camera left\n if (\n direction < Math.PI / 2 &&\n direction > -Math.PI / 2 &&\n this.velocity.z < 0\n ) {\n if (\n (!this.rightCollide && direction < 0) ||\n (!this.leftCollide && direction > 0)\n ) {\n this.moveZ(-direction, delta)\n }\n } else if (\n !this.leftCollide &&\n !this.rightCollide &&\n this.velocity.z < 0\n ) {\n this.control.moveRight(this.velocity.z * delta)\n }\n\n // camera right\n if (\n (direction < -Math.PI / 2 || direction > Math.PI / 2) &&\n this.velocity.z > 0\n ) {\n if (!this.rightCollide && direction > 0) {\n this.moveZ(Math.PI - direction, delta)\n }\n if (!this.leftCollide && direction < 0) {\n this.moveZ(-Math.PI - direction, delta)\n }\n } else if (\n !this.leftCollide &&\n !this.rightCollide &&\n this.velocity.z > 0\n ) {\n this.control.moveRight(this.velocity.z * delta)\n }\n }\n\n // collide back (negative x)\n if (this.backCollide) {\n // camera front\n if (direction < 0 && direction > -Math.PI && this.velocity.x > 0) {\n if (\n (!this.leftCollide && direction < -Math.PI / 2) ||\n (!this.rightCollide && direction > -Math.PI / 2)\n ) {\n this.moveZ(Math.PI / 2 + direction, delta)\n }\n } else if (\n !this.leftCollide &&\n !this.rightCollide &&\n this.velocity.x > 0\n ) {\n this.control.moveForward(this.velocity.x * delta)\n }\n\n // camera back\n if (direction < Math.PI && direction > 0 && this.velocity.x < 0) {\n if (\n (!this.leftCollide && direction < Math.PI / 2) ||\n (!this.rightCollide && direction > Math.PI / 2)\n ) {\n this.moveZ(direction - Math.PI / 2, delta)\n }\n } else if (\n !this.leftCollide &&\n !this.rightCollide &&\n this.velocity.x < 0\n ) {\n this.control.moveForward(this.velocity.x * delta)\n }\n\n // camera left\n if (\n (direction < -Math.PI / 2 || direction > Math.PI / 2) &&\n this.velocity.z < 0\n ) {\n if (!this.leftCollide && direction > 0) {\n this.moveZ(-Math.PI + direction, delta)\n }\n if (!this.rightCollide && direction < 0) {\n this.moveZ(Math.PI + direction, delta)\n }\n } else if (\n !this.leftCollide &&\n !this.rightCollide &&\n this.velocity.z < 0\n ) {\n this.control.moveRight(this.velocity.z * delta)\n }\n\n // camera right\n if (\n direction < Math.PI / 2 &&\n direction > -Math.PI / 2 &&\n this.velocity.z > 0\n ) {\n if (\n (!this.leftCollide && direction < 0) ||\n (!this.rightCollide && direction > 0)\n ) {\n this.moveZ(direction, delta)\n }\n } else if (\n !this.leftCollide &&\n !this.rightCollide &&\n this.velocity.z > 0\n ) {\n this.control.moveRight(this.velocity.z * delta)\n }\n }\n\n // collide left (negative z)\n if (this.leftCollide) {\n // camera front\n if (\n (direction < -Math.PI / 2 || direction > Math.PI / 2) &&\n this.velocity.x > 0\n ) {\n if (!this.frontCollide && direction > 0) {\n this.moveX(Math.PI - direction, delta)\n }\n if (!this.backCollide && direction < 0) {\n this.moveX(-Math.PI - direction, delta)\n }\n } else if (\n !this.frontCollide &&\n !this.backCollide &&\n this.velocity.x > 0\n ) {\n this.control.moveForward(this.velocity.x * delta)\n } else if (\n this.frontCollide &&\n direction < 0 &&\n direction > -Math.PI / 2 &&\n this.velocity.x > 0\n ) {\n this.control.moveForward(this.velocity.x * delta)\n } else if (\n this.backCollide &&\n direction < Math.PI / 2 &&\n direction > 0 &&\n this.velocity.x > 0\n ) {\n this.control.moveForward(this.velocity.x * delta)\n }\n\n // camera back\n if (\n direction < Math.PI / 2 &&\n direction > -Math.PI / 2 &&\n this.velocity.x < 0\n ) {\n if (\n (!this.frontCollide && direction < 0) ||\n (!this.backCollide && direction > 0)\n ) {\n this.moveX(-direction, delta)\n }\n } else if (\n !this.frontCollide &&\n !this.backCollide &&\n this.velocity.x < 0\n ) {\n this.control.moveForward(this.velocity.x * delta)\n } else if (\n this.frontCollide &&\n direction < Math.PI &&\n direction > Math.PI / 2 &&\n this.velocity.x < 0\n ) {\n this.control.moveForward(this.velocity.x * delta)\n } else if (\n this.backCollide &&\n direction > -Math.PI &&\n direction < -Math.PI / 2 &&\n this.velocity.x < 0\n ) {\n this.control.moveForward(this.velocity.x * delta)\n }\n\n // camera left\n if (direction > 0 && direction < Math.PI && this.velocity.z < 0) {\n if (\n (!this.backCollide && direction > Math.PI / 2) ||\n (!this.frontCollide && direction < Math.PI / 2)\n ) {\n this.moveX(Math.PI / 2 - direction, delta)\n }\n } else if (\n !this.frontCollide &&\n !this.backCollide &&\n this.velocity.z < 0\n ) {\n this.control.moveRight(this.velocity.z * delta)\n } else if (\n this.frontCollide &&\n direction > -Math.PI &&\n direction < -Math.PI / 2 &&\n this.velocity.z < 0\n ) {\n this.control.moveRight(this.velocity.z * delta)\n } else if (\n this.backCollide &&\n direction > -Math.PI / 2 &&\n direction < 0 &&\n this.velocity.z < 0\n ) {\n this.control.moveRight(this.velocity.z * delta)\n }\n\n // camera right\n if (direction < 0 && direction > -Math.PI && this.velocity.z > 0) {\n if (\n (!this.backCollide && direction > -Math.PI / 2) ||\n (!this.frontCollide && direction < -Math.PI / 2)\n ) {\n this.moveX(-Math.PI / 2 - direction, delta)\n }\n } else if (\n !this.frontCollide &&\n !this.backCollide &&\n this.velocity.z > 0\n ) {\n this.control.moveRight(this.velocity.z * delta)\n } else if (\n this.frontCollide &&\n direction < Math.PI / 2 &&\n direction > 0 &&\n this.velocity.z > 0\n ) {\n this.control.moveRight(this.velocity.z * delta)\n } else if (\n this.backCollide &&\n direction < Math.PI &&\n direction > Math.PI / 2 &&\n this.velocity.z > 0\n ) {\n this.control.moveRight(this.velocity.z * delta)\n }\n }\n\n // collide right (positive z)\n if (this.rightCollide) {\n // camera front\n if (\n direction < Math.PI / 2 &&\n direction > -Math.PI / 2 &&\n this.velocity.x > 0\n ) {\n if (\n (!this.backCollide && direction < 0) ||\n (!this.frontCollide && direction > 0)\n ) {\n this.moveX(direction, delta)\n }\n } else if (\n !this.frontCollide &&\n !this.backCollide &&\n this.velocity.x > 0\n ) {\n this.control.moveForward(this.velocity.x * delta)\n } else if (\n this.frontCollide &&\n direction < -Math.PI / 2 &&\n direction > -Math.PI &&\n this.velocity.x > 0\n ) {\n this.control.moveForward(this.velocity.x * delta)\n } else if (\n this.backCollide &&\n direction < Math.PI &&\n direction > Math.PI / 2 &&\n this.velocity.x > 0\n ) {\n this.control.moveForward(this.velocity.x * delta)\n }\n\n // camera back\n if (\n (direction < -Math.PI / 2 || direction > Math.PI / 2) &&\n this.velocity.x < 0\n ) {\n if (!this.backCollide && direction > 0) {\n this.moveX(-Math.PI + direction, delta)\n }\n if (!this.frontCollide && direction < 0) {\n this.moveX(Math.PI + direction, delta)\n }\n } else if (\n !this.frontCollide &&\n !this.backCollide &&\n this.velocity.x < 0\n ) {\n this.control.moveForward(this.velocity.x * delta)\n } else if (\n this.frontCollide &&\n direction < Math.PI / 2 &&\n direction > 0 &&\n this.velocity.x < 0\n ) {\n this.control.moveForward(this.velocity.x * delta)\n } else if (\n this.backCollide &&\n direction < 0 &&\n direction > -Math.PI / 2 &&\n this.velocity.x < 0\n ) {\n this.control.moveForward(this.velocity.x * delta)\n }\n\n // camera left\n if (direction < 0 && direction > -Math.PI && this.velocity.z < 0) {\n if (\n (!this.frontCollide && direction > -Math.PI / 2) ||\n (!this.backCollide && direction < -Math.PI / 2)\n ) {\n this.moveX(Math.PI / 2 + direction, delta)\n }\n } else if (\n !this.frontCollide &&\n !this.backCollide &&\n this.velocity.z < 0\n ) {\n this.control.moveRight(this.velocity.z * delta)\n } else if (\n this.frontCollide &&\n direction > Math.PI / 2 &&\n direction < Math.PI &&\n this.velocity.z < 0\n ) {\n this.control.moveRight(this.velocity.z * delta)\n } else if (\n this.backCollide &&\n direction > 0 &&\n direction < Math.PI / 2 &&\n this.velocity.z < 0\n ) {\n this.control.moveRight(this.velocity.z * delta)\n }\n\n // camera right\n if (direction > 0 && direction < Math.PI && this.velocity.z > 0) {\n if (\n (!this.frontCollide && direction > Math.PI / 2) ||\n (!this.backCollide && direction < Math.PI / 2)\n ) {\n this.moveX(direction - Math.PI / 2, delta)\n }\n } else if (\n !this.frontCollide &&\n !this.backCollide &&\n this.velocity.z > 0\n ) {\n this.control.moveRight(this.velocity.z * delta)\n } else if (\n this.frontCollide &&\n direction > -Math.PI / 2 &&\n direction < 0 &&\n this.velocity.z > 0\n ) {\n this.control.moveRight(this.velocity.z * delta)\n } else if (\n this.backCollide &&\n direction > -Math.PI &&\n direction < -Math.PI / 2 &&\n this.velocity.z > 0\n ) {\n this.control.moveRight(this.velocity.z * delta)\n }\n }\n } else {\n // no collide\n this.control.moveForward(this.velocity.x * delta)\n this.control.moveRight(this.velocity.z * delta)\n }\n\n this.camera.position.y += this.velocity.y * delta\n\n // catching net\n if (this.camera.position.y < -100) {\n this.camera.position.y = 60\n }\n }\n this.p2 = this.p1\n }\n}\n","/**\n * Display current FPS\n */\nexport default class FPS {\n constructor() {\n this.fps.className = 'fps'\n this.fps.innerHTML = `FPS: 60`\n\n document.body.appendChild(this.fps)\n }\n\n p1 = performance.now()\n p2 = performance.now()\n gap = performance.now()\n fps = document.createElement('div')\n count = 0\n\n update = () => {\n this.p1 = performance.now()\n this.count++\n\n if (performance.now() - this.gap > 1000) {\n this.fps.innerHTML = `FPS: ${this.count}`\n this.gap = performance.now()\n this.count = 0\n }\n\n this.p2 = this.p1\n }\n}\n","export default \"__VITE_ASSET__020eb145__\"","export default \"__VITE_ASSET__53e38748__\"","export default \"__VITE_ASSET__98a9b0d4__\"","export default \"__VITE_ASSET__9768871f__\"","export default \"__VITE_ASSET__b6171099__\"","export default \"__VITE_ASSET__9ffd1d51__\"","export default \"__VITE_ASSET__3e48b289__\"","import grass from '../../static/block-icon/grass.png'\nimport stone from '../../static/block-icon/stone.png'\nimport tree from '../../static/block-icon/tree.png'\nimport wood from '../../static/block-icon/wood.png'\nimport diamond from '../../static/block-icon/diamond.png'\nimport quartz from '../../static/block-icon/quartz.png'\nimport glass from '../../static/block-icon/glass.png'\nimport { isMobile } from '../../utils'\n\nexport default class Bag {\n constructor() {\n if (isMobile) return\n\n this.bag.className = 'bag'\n this.items[0].classList.add('selected')\n\n for (let i = 0; i < this.items.length; i++) {\n this.bag.appendChild(this.items[i])\n }\n document.body.appendChild(this.bag)\n\n document.body.addEventListener('keydown', (e: KeyboardEvent) => {\n if (isNaN(parseInt(e.key)) || e.key === '0') {\n return\n }\n\n for (let i = 0; i < this.items.length; i++) {\n this.items[i].classList.remove('selected')\n }\n\n this.current = parseInt(e.key) - 1\n this.items[this.current].classList.add('selected')\n })\n\n document.body.addEventListener('wheel', (e: WheelEvent) => {\n if (!this.wheelGap) {\n this.wheelGap = true\n setTimeout(() => {\n this.wheelGap = false\n }, 100)\n if (e.deltaY > 0) {\n this.current++\n this.current > 9 && (this.current = 0)\n } else if (e.deltaY < 0) {\n this.current--\n this.current < 0 && (this.current = 9)\n }\n for (let i = 0; i < this.items.length; i++) {\n this.items[i].classList.remove('selected')\n }\n this.items[this.current].classList.add('selected')\n }\n })\n }\n wheelGap = false\n current = 0\n icon = [grass, stone, tree, wood, diamond, quartz, glass]\n iconIndex = 0\n y = 0\n\n bag = document.createElement('div')\n\n items = new Array(10).fill(null).map(() => {\n let item = document.createElement('div')\n item.className = 'item'\n\n let img = document.createElement('img')\n if (this.icon[this.iconIndex]) {\n img.className = 'icon'\n img.alt = 'block'\n img.src = this.icon[this.iconIndex++]\n item.appendChild(img)\n }\n\n return item\n })\n}\n","export default \"<div class=\\\"joystick\\\">\\n <button id=\\\"action-front\\\" class=\\\"joystick-button front\\\" role=\\\"div\\\">🔼</button>\\n <button id=\\\"action-left\\\" class=\\\"joystick-button left\\\" role=\\\"div\\\">◀️</button>\\n <button id=\\\"action-right\\\" class=\\\"joystick-button right\\\" role=\\\"div\\\">▶️</button>\\n <button id=\\\"action-back\\\" class=\\\"joystick-button back\\\" role=\\\"div\\\">🔽</button>\\n <button id=\\\"action-mode\\\" class=\\\"joystick-button mode\\\" role=\\\"div\\\">⏹️</button>\\n <button id=\\\"action-up\\\" class=\\\"joystick-button up\\\" role=\\\"div\\\">🔼</button>\\n <button id=\\\"action-down\\\" class=\\\"joystick-button down hidden\\\" role=\\\"div\\\">\\n 🔽\\n </button>\\n</div>\\n\\n<style>\\n .joystick {\\n position: fixed;\\n bottom: 0;\\n display: grid;\\n width: 100%;\\n grid-template-columns: repeat(auto-fill, 50px);\\n grid-template-rows: repeat(3, 1fr);\\n gap: 10px;\\n padding: 10px;\\n }\\n .joystick-button {\\n width: 52px;\\n height: 50px;\\n font-size: 50px;\\n line-height: 50px;\\n padding: 0px;\\n border: none;\\n background-color: transparent;\\n }\\n .front {\\n grid-column: 2 / 3;\\n grid-row: 1;\\n }\\n .left {\\n grid-column: 1 / 2;\\n grid-row: 2;\\n }\\n .right {\\n grid-column: 3 / 4;\\n grid-row: 2;\\n }\\n .back {\\n grid-column: 2 / 3;\\n grid-row: 3;\\n }\\n .mode {\\n grid-column: 2 / 3;\\n grid-row: 2;\\n }\\n .up {\\n grid-column: -3 / -2;\\n grid-row: 2;\\n }\\n .down {\\n grid-column: -3 / -2;\\n grid-row: 3;\\n }\\n</style>\\n\"","import * as THREE from 'three'\nimport Control from '../../control'\nimport { Mode } from '../../player'\nimport { htmlToDom } from '../../utils'\nimport UI from './joystick.html?raw'\n\nenum ActionKey {\n FRONT = 'front',\n LEFT = 'left',\n RIGHT = 'right',\n BACK = 'back',\n MODE = 'mode',\n JUMP = 'jump',\n UP = 'up',\n DOWN = 'down'\n}\n\nexport default class Joystick {\n constructor(control: Control) {\n this.control = control\n this.euler = new THREE.Euler(0, 0, 0, 'YXZ')\n }\n\n control: Control\n pageX = 0\n pageY = 0\n clickX = 0\n clickY = 0\n euler: THREE.Euler\n clickTimeout?: ReturnType<typeof setTimeout>\n clickInterval?: ReturnType<typeof setInterval>\n hold = false\n\n // emit keyboard event\n private emitKeyboardEvent = (key: string) => {\n return {\n key\n } as KeyboardEvent\n }\n\n // emit click event\n private emitClickEvent = (button: number) => {\n return {\n button,\n preventDefault: () => { }\n } as MouseEvent\n }\n\n // init joystick button\n private initButton = ({\n actionKey,\n key\n }: {\n actionKey: ActionKey\n key: string\n }) => {\n const button = document.querySelector(\n `#action-${actionKey}`\n ) as HTMLButtonElement\n button.addEventListener('pointermove', e => {\n e.stopPropagation()\n })\n button.addEventListener('pointerdown', e => {\n this.control.setMovementHandler(this.emitKeyboardEvent(key))\n e.stopPropagation()\n })\n button.addEventListener('pointerup', e => {\n this.control.resetMovementHandler(this.emitKeyboardEvent(key))\n e.stopPropagation()\n })\n // extra config for mode switch button\n if (actionKey === ActionKey.MODE && key === 'q') {\n this.initButton({ actionKey: ActionKey.MODE, key: ' ' })\n button.addEventListener('pointerdown', () => {\n if (this.control.player.mode === Mode.flying) {\n document.querySelector('#action-down')?.classList.remove('hidden')\n } else {\n document.querySelector('#action-down')?.classList.add('hidden')\n }\n })\n }\n }\n\n init = () => {\n htmlToDom(UI)\n\n this.initButton({ actionKey: ActionKey.FRONT, key: 'w' })\n this.initButton({ actionKey: ActionKey.LEFT, key: 'a' })\n this.initButton({ actionKey: ActionKey.RIGHT, key: 'd' })\n this.initButton({ actionKey: ActionKey.BACK, key: 's' })\n this.initButton({ actionKey: ActionKey.MODE, key: 'q' })\n this.initButton({ actionKey: ActionKey.UP, key: ' ' })\n this.initButton({ actionKey: ActionKey.DOWN, key: 'Shift' })\n\n // camera control\n document.addEventListener('pointermove', e => {\n if (this.pageX !== 0 || this.pageY !== 0) {\n this.euler.setFromQuaternion(this.control.camera.quaternion)\n this.euler.y -= 0.01 * (e.pageX - this.pageX)\n this.euler.x -= 0.01 * (e.pageY - this.pageY)\n this.euler.x = Math.max(\n -Math.PI / 2,\n Math.min(Math.PI / 2, this.euler.x)\n )\n this.control.camera.quaternion.setFromEuler(this.euler)\n }\n this.pageX = e.pageX\n this.pageY = e.pageY\n this.clickTimeout && clearTimeout(this.clickTimeout)\n })\n\n // click control\n document.addEventListener('pointerdown', e => {\n this.clickX = e.pageX\n this.clickY = e.pageY\n\n this.clickTimeout = setTimeout(() => {\n if (e.pageX === this.clickX && e.pageY === this.clickY) {\n this.control.mousedownHandler(this.emitClickEvent(0))\n this.clickInterval = setInterval(() => {\n this.control.mousedownHandler(this.emitClickEvent(0))\n }, 333)\n this.hold = true\n }\n }, 500)\n })\n\n document.addEventListener('pointerup', e => {\n this.clickTimeout && clearTimeout(this.clickTimeout)\n this.clickInterval && clearInterval(this.clickInterval)\n\n if (!this.hold && e.pageX === this.clickX && e.pageY === this.clickY) {\n this.control.mousedownHandler(this.emitClickEvent(2))\n }\n this.hold = false\n this.pageX = 0\n this.pageY = 0\n })\n }\n}\n","import FPS from './fps'\nimport Bag from './bag'\nimport Terrain from '../terrain'\nimport Block from '../terrain/mesh/block'\nimport Control from '../control'\nimport { Mode } from '../player'\nimport Joystick from './joystick'\nimport { isMobile } from '../utils'\nimport * as THREE from 'three'\n\nexport default class UI {\n constructor(terrain: Terrain, control: Control) {\n this.fps = new FPS()\n this.bag = new Bag()\n this.joystick = new Joystick(control)\n\n this.crossHair.className = 'cross-hair'\n this.crossHair.innerHTML = '+'\n document.body.appendChild(this.crossHair)\n\n // play\n this.play?.addEventListener('click', () => {\n if (this.play?.innerHTML === 'Play') {\n this.onPlay()\n\n // reset game\n terrain.noise.seed = Math.random()\n terrain.noise.stoneSeed = Math.random()\n terrain.noise.treeSeed = Math.random()\n terrain.noise.coalSeed = Math.random()\n terrain.noise.leafSeed = Math.random()\n terrain.customBlocks = []\n terrain.initBlocks()\n terrain.generate()\n terrain.camera.position.y = 40\n control.player.setMode(Mode.walking)\n }\n !isMobile && control.control.lock()\n })\n\n // save load\n this.save?.addEventListener('click', () => {\n if (this.save?.innerHTML === 'Save and Exit') {\n // save game\n window.localStorage.setItem(\n 'block',\n JSON.stringify(terrain.customBlocks)\n )\n window.localStorage.setItem('seed', JSON.stringify(terrain.noise.seed))\n\n window.localStorage.setItem(\n 'position',\n JSON.stringify({\n x: terrain.camera.position.x,\n y: terrain.camera.position.y,\n z: terrain.camera.position.z\n })\n )\n\n // ui update\n this.onExit()\n this.onSave()\n } else {\n // load game\n terrain.noise.seed =\n Number(window.localStorage.getItem('seed')) ?? Math.random()\n\n const customBlocks =\n (JSON.parse(\n window.localStorage.getItem('block') || 'null'\n ) as Block[]) ?? []\n\n terrain.customBlocks = customBlocks\n terrain.initBlocks()\n terrain.generate()\n\n const position =\n (JSON.parse(window.localStorage.getItem('position') || 'null') as {\n x: number\n y: number\n z: number\n }) ?? null\n\n position && (terrain.camera.position.x = position.x)\n position && (terrain.camera.position.y = position.y)\n position && (terrain.camera.position.z = position.z)\n\n // ui update\n this.onPlay()\n this.onLoad()\n !isMobile && control.control.lock()\n }\n })\n\n // guide\n this.feature?.addEventListener('click', () => {\n this.features?.classList.remove('hidden')\n })\n this.back?.addEventListener('click', () => {\n this.features?.classList.add('hidden')\n })\n\n // setting\n this.setting?.addEventListener('click', () => {\n this.settings?.classList.remove('hidden')\n })\n this.settingBack?.addEventListener('click', () => {\n this.settings?.classList.add('hidden')\n })\n\n // render distance\n this.distanceInput?.addEventListener('input', (e: Event) => {\n if (this.distance && e.target instanceof HTMLInputElement) {\n this.distance.innerHTML = `Render Distance: ${e.target.value}`\n }\n })\n\n // fov\n this.fovInput?.addEventListener('input', (e: Event) => {\n if (this.fov && e.target instanceof HTMLInputElement) {\n this.fov.innerHTML = `Field of View: ${e.target.value}`\n control.camera.fov = parseInt(e.target.value)\n control.camera.updateProjectionMatrix()\n }\n })\n\n // music\n this.musicInput?.addEventListener('input', (e: Event) => {\n if (this.fov && e.target instanceof HTMLInputElement) {\n const disabled = e.target.value === '0'\n control.audio.disabled = disabled\n this.music!.innerHTML = `Music: ${disabled ? 'Off' : 'On'}`\n }\n })\n\n // apply settings\n this.settingBack?.addEventListener('click', () => {\n if (this.distanceInput instanceof HTMLInputElement) {\n terrain.distance = parseInt(this.distanceInput.value)\n terrain.maxCount =\n (terrain.distance * terrain.chunkSize * 2 + terrain.chunkSize) ** 2 +\n 500\n\n terrain.initBlocks()\n terrain.generate()\n terrain.scene.fog = new THREE.Fog(\n 0x87ceeb,\n 1,\n terrain.distance * 24 + 24\n )\n }\n })\n\n // menu and fullscreen\n document.body.addEventListener('keydown', (e: KeyboardEvent) => {\n // menu\n if (e.key === 'e' && document.pointerLockElement) {\n !isMobile && control.control.unlock()\n }\n\n // fullscreen\n if (e.key === 'f') {\n if (document.fullscreenElement) {\n document.exitFullscreen()\n } else {\n document.body.requestFullscreen()\n }\n }\n })\n\n // exit\n this.exit?.addEventListener('click', () => {\n this.onExit()\n })\n\n // play / pause handler\n document.addEventListener('pointerlockchange', () => {\n if (document.pointerLockElement) {\n this.onPlay()\n } else {\n this.onPause()\n }\n })\n\n // disable context menu\n document.addEventListener('contextmenu', e => {\n e.preventDefault()\n })\n\n // fallback lock handler\n document.querySelector('canvas')?.addEventListener('click', (e: Event) => {\n e.preventDefault()\n !isMobile && control.control.lock()\n })\n }\n\n fps: FPS\n bag: Bag\n joystick: Joystick\n\n menu = document.querySelector('.menu')\n crossHair = document.createElement('div')\n\n // buttons\n play = document.querySelector('#play')\n control = document.querySelector('#control')\n setting = document.querySelector('#setting')\n feature = document.querySelector('#feature')\n back = document.querySelector('#back')\n exit = document.querySelector('#exit')\n save = document.querySelector('#save')\n\n // modals\n saveModal = document.querySelector('.save-modal')\n loadModal = document.querySelector('.load-modal')\n settings = document.querySelector('.settings')\n features = document.querySelector('.features')\n github = document.querySelector('.github')\n\n // settings\n distance = document.querySelector('#distance')\n distanceInput = document.querySelector('#distance-input')\n\n fov = document.querySelector('#fov')\n fovInput = document.querySelector('#fov-input')\n\n music = document.querySelector('#music')\n musicInput = document.querySelector('#music-input')\n\n settingBack = document.querySelector('#setting-back')\n\n onPlay = () => {\n isMobile && this.joystick.init()\n this.menu?.classList.add('hidden')\n this.menu?.classList.remove('start')\n this.play && (this.play.innerHTML = 'Resume')\n this.crossHair.classList.remove('hidden')\n this.github && this.github.classList.add('hidden')\n this.feature?.classList.add('hidden')\n }\n\n onPause = () => {\n this.menu?.classList.remove('hidden')\n this.crossHair.classList.add('hidden')\n this.save && (this.save.innerHTML = 'Save and Exit')\n this.github && this.github.classList.remove('hidden')\n }\n\n onExit = () => {\n this.menu?.classList.add('start')\n this.play && (this.play.innerHTML = 'Play')\n this.save && (this.save.innerHTML = 'Load Game')\n this.feature?.classList.remove('hidden')\n }\n\n onSave = () => {\n this.saveModal?.classList.remove('hidden')\n setTimeout(() => {\n this.saveModal?.classList.add('show')\n })\n setTimeout(() => {\n this.saveModal?.classList.remove('show')\n }, 1000)\n\n setTimeout(() => {\n this.saveModal?.classList.add('hidden')\n }, 1350)\n }\n\n onLoad = () => {\n this.loadModal?.classList.remove('hidden')\n setTimeout(() => {\n this.loadModal?.classList.add('show')\n })\n setTimeout(() => {\n this.loadModal?.classList.remove('show')\n }, 1000)\n\n setTimeout(() => {\n this.loadModal?.classList.add('hidden')\n }, 1350)\n }\n\n update = () => {\n this.fps.update()\n }\n}\n","export default \"__VITE_ASSET__2642662e__\"","export default \"__VITE_ASSET__3619fdb8__\"","export default \"__VITE_ASSET__b0763cf2__\"","export default \"__VITE_ASSET__9ac02803__\"","export default \"__VITE_ASSET__dd733357__\"","export default \"__VITE_ASSET__1260ef32__\"","export default \"__VITE_ASSET__74ef2fa1__\"","export default \"__VITE_ASSET__0441e996__\"","export default \"__VITE_ASSET__42ac9116__\"","export default \"__VITE_ASSET__97f2a8a7__\"","export default \"__VITE_ASSET__98a5c319__\"","export default \"__VITE_ASSET__19273f0e__\"","export default \"__VITE_ASSET__b164e732__\"","export default \"__VITE_ASSET__55a610c8__\"","export default \"__VITE_ASSET__60ebf0ed__\"","export default \"__VITE_ASSET__ab5e4b40__\"","export default \"__VITE_ASSET__fd4aa755__\"","export default \"__VITE_ASSET__cb6071c8__\"","export default \"__VITE_ASSET__59edca84__\"","export default \"__VITE_ASSET__cf6be231__\"","export default \"__VITE_ASSET__de868b31__\"","export default \"__VITE_ASSET__74400cfe__\"","export default \"__VITE_ASSET__b7636085__\"","export default \"__VITE_ASSET__6228533c__\"","export default \"__VITE_ASSET__72db3634__\"","import * as THREE from 'three'\nimport hal3 from './musics/hal3.ogg'\nimport { BlockType } from '../terrain'\n\nimport grass1 from './blocks/grass1.ogg'\nimport grass2 from './blocks/grass2.ogg'\nimport grass3 from './blocks/grass3.ogg'\nimport grass4 from './blocks/grass4.ogg'\n\nimport sand1 from './blocks/sand1.ogg'\nimport sand2 from './blocks/sand2.ogg'\nimport sand3 from './blocks/sand3.ogg'\nimport sand4 from './blocks/sand4.ogg'\n\nimport stone1 from './blocks/stone1.ogg'\nimport stone2 from './blocks/stone2.ogg'\nimport stone3 from './blocks/stone3.ogg'\nimport stone4 from './blocks/stone4.ogg'\n\nimport dirt1 from './blocks/dirt1.ogg'\nimport dirt2 from './blocks/dirt2.ogg'\nimport dirt3 from './blocks/dirt3.ogg'\nimport dirt4 from './blocks/dirt4.ogg'\n\nimport tree1 from './blocks/tree1.ogg'\nimport tree2 from './blocks/tree2.ogg'\nimport tree3 from './blocks/tree3.ogg'\nimport tree4 from './blocks/tree4.ogg'\n\nimport leaf1 from './blocks/leaf1.ogg'\nimport leaf2 from './blocks/leaf2.ogg'\nimport leaf3 from './blocks/leaf3.ogg'\nimport leaf4 from './blocks/leaf4.ogg'\nimport { isMobile } from '../utils'\n\nexport default class Audio {\n constructor(camera: THREE.PerspectiveCamera) {\n if (isMobile) return\n\n const listener = new THREE.AudioListener()\n const audioLoader = new THREE.AudioLoader()\n camera.add(listener)\n\n // load bgm\n const bgm = new THREE.Audio(listener)\n bgm.autoplay = false\n audioLoader.load(hal3, buffer => {\n bgm.setBuffer(buffer)\n bgm.setVolume(0.1)\n bgm.setLoop(true)\n if (bgm.isPlaying) {\n bgm.pause()\n bgm.play()\n }\n })\n\n // play / pause bgm\n document.addEventListener('pointerlockchange', () => {\n if (document.pointerLockElement && !bgm.isPlaying && !this.disabled) {\n bgm.play()\n } else {\n bgm.pause()\n }\n })\n\n // load sound effect\n for (const types of this.sourceSet) {\n const audios: THREE.Audio[] = []\n for (const type of types) {\n audioLoader.load(type, buffer => {\n const audio = new THREE.Audio(listener!)\n audio.setBuffer(buffer)\n audio.setVolume(0.15)\n audios.push(audio)\n })\n }\n this.soundSet.push(audios)\n }\n }\n\n disabled = false\n\n sourceSet = [\n [grass1, grass2, grass3, grass4],\n [sand1, sand2, sand3, sand4],\n [tree1, tree2, tree3, tree4],\n [leaf1, leaf2, leaf3, leaf4],\n [dirt1, dirt2, dirt3, dirt4],\n [stone1, stone2, stone3, stone4],\n [stone1, stone2, stone3, stone4],\n [tree1, tree2, tree3, tree4],\n [stone1, stone2, stone3, stone4],\n [stone1, stone2, stone3, stone4],\n [stone1, stone2, stone3, stone4]\n ]\n\n soundSet: THREE.Audio[][] = []\n\n index = 0\n\n playSound(type: BlockType) {\n if (!this.disabled && !isMobile) {\n this.index++ === 3 && (this.index = 0)\n this.soundSet[type]?.[this.index]?.play()\n }\n }\n}\n","import Core from './core'\nimport Control from './control'\nimport Player from './player'\nimport Terrain from './terrain'\nimport UI from './ui'\nimport Audio from './audio'\n\nimport './style.css'\n\nconst core = new Core()\nconst camera = core.camera\nconst scene = core.scene\nconst renderer = core.renderer\n\nconst player = new Player()\nconst audio = new Audio(camera)\n\nconst terrain = new Terrain(scene, camera)\nconst control = new Control(scene, camera, player, terrain, audio)\n\nconst ui = new UI(terrain, control)\n\n// animation\n;(function animate() {\n // let p1 = performance.now()\n requestAnimationFrame(animate)\n\n control.update()\n terrain.update()\n ui.update()\n\n renderer.render(scene, camera)\n // console.log(performance.now()-p1)\n})()\n"],"names":["THREE.Scene","THREE.Fog","THREE.Color","THREE.PointLight","THREE.AmbientLight","THREE.PerspectiveCamera","THREE.WebGLRenderer","THREE.TextureLoader","stone","diamond","quartz","glass","THREE.NearestFilter","THREE.MeshStandardMaterial","THREE.BoxGeometry","THREE.Mesh","THREE.InstancedMesh","THREE.MeshBasicMaterial","THREE.Raycaster","THREE.InstancedBufferAttribute","THREE.Matrix4","THREE.Vector3","THREE.Vector2","Generate","Highlight","UI","THREE.Euler","THREE.AudioListener","THREE.AudioLoader","THREE.Audio"],"mappings":"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"}