const info = wx.getSystemInfoSync(); const dpi = info.pixelRatio; const width = info.windowWidth * dpi; const height = info.windowHeight * dpi; import CONFIG from './config.js'; const ROOT_DURATIONS = [ 3000, 4500, 6000, Infinity ]; const ROOT_DELAYS = [ 2000, 1500, 1000, 0 ]; const ROOT_AMBIENTS = [ 0.05, 0.15, 0.4, 1 ]; const ROOT_BLURS = [ 32, 32, 16, 0 ]; const REAL_BLURS = [ 0, 32, 48, 96 ]; function showFinalChoose(content, callback) { wx.showModal({ title: '做出选择', content, showCancel: true, confirmText: '正视现实', cancelText: '我不要!', success: (res) => { if (res.cancel) { showFinalChoose('不能逃避!', callback); } else { callback(); setTimeout(() => { wx.showToast({ title: '勇敢一些\n不要怯懦', duration: 5000, icon: 'none' }) }, 500); } } }); } Component({ scene: null, properties: { nextAction: { type: String, value: '', observer(fromWhat, old) { if (fromWhat === 'item') { this.remainItems -= 1; if (this.remainItems === 0) { this.disable3DTouch = false; this.setData({subStep: true}); return; } this.switchSide(false); this.triggerEvent('requireLight', {state: 'idle'}); return; } if (fromWhat === 'char') { const {texts} = this.config.steps[this.data.step]; this.requireDialog({texts, from: 'step'}); return; } if (fromWhat === 'step' || fromWhat === 'intro') { const step = this.data.step + 1; if (step === 4) { wx.showModal({ title: '最后的信', content: this.config.letter.texts.join('\n'), showCancel: false, confirmText: '做出选择', complete: () => { showFinalChoose('', () => this.switchSide(false, 0)); } }); return; } if (step === 3) { this.bgm.stop(); this.bgm2.play(); } this.remainItems = this.config.steps[step].itemCount; this.setData({step, subStep: false, ambient: ROOT_AMBIENTS[step]}); this.switchSide(false); this.triggerEvent('requireLight', {state: 'idle'}); return; } if (fromWhat === 'light') { this.switchSide(true); this.disable3DTouch = false; this.lightDuration = ROOT_DURATIONS[this.data.step]; this.lightDelay = ROOT_DELAYS[this.data.step]; } } } }, data: { step: -1, subStep: false, ambient: 0, width: width, height: height, loaded: false, arReady: false }, lifetimes: { detached() { this.bgm.stop(); this.bgm2.stop(); wx.setKeepScreenOn({keepScreenOn: false}); } }, methods: { handleReady({detail}) { this.scene = detail.value; this.scene.event.add('tick', this.handleTick.bind(this)); this.inited = false; this.disable3DTouch = false; this.remainItems = 0; this.lightDuration = 0; this.lightDelay = 0; this.bgm = wx.createInnerAudioContext({}); this.bgm.src = 'https://mmbizwxaminiprogram-1258344707.cos.ap-guangzhou.myqcloud.com/xr-frame/demo/beside-edge/bgm1.mp3'; this.bgm.loop = true; this.bgm2 = wx.createInnerAudioContext({}); this.bgm2.src = 'https://mmbizwxaminiprogram-1258344707.cos.ap-guangzhou.myqcloud.com/xr-frame/demo/beside-edge/bgm2.mp3'; this.bgm2.loop = true; }, handleARReady() { wx.setKeepScreenOn({keepScreenOn: true}); this.setData({arReady: true}); }, handleAssetsLoaded: function ({detail}) { console.log('assets loaded', detail.value); this.config = CONFIG; this.setData({loaded: true}); }, handleTick(dt) { const mainCamera = this.scene.getNodeById('main-camera'); const light = this.scene.getNodeById('light'); if (mainCamera && light) { light.position.set(mainCamera.position); light.rotation.set(mainCamera.rotation); light.rotation.x = Math.PI - light.rotation.x; light.rotation.y += Math.PI; } if (this.inited) { const nextDuration = Math.max(this.lightDuration - dt, 0); if (this.lightDuration > 0 && nextDuration === 0) { this.disable3DTouch = true; this.switchSide(false); this.triggerEvent('requireLight', {state: 'cd', wait: 1}); } else if (this.lightDuration === 0) { const nextDelay = Math.max(this.lightDelay - dt, 0); if (this.lightDelay > 0 && nextDelay === 0) { this.triggerEvent('requireLight', {state: 'idle'}); } else if (this.lightDelay > 0) { this.triggerEvent('requireLight', {state: 'cd', wait: nextDelay / ROOT_DELAYS[this.data.step]}); } this.lightDelay = nextDelay; } this.lightDuration = nextDuration; return; } if (!this.data.arReady || !this.data.loaded) { return; } const setItem = this.scene.getNodeById('setitem'); setItem.position.set(mainCamera.position); setItem.position.y = 1; this.inited = true; setTimeout(() => { this.switchSide(true, ROOT_BLURS[0]); const {texts} = this.config.intro; this.requireDialog({texts, from: 'intro'}); this.bgm.play(); }, 1000); }, switchSide(virtual, blur) { const setItem = this.scene.getNodeById('setitem'); setItem.visible = virtual; const blurAsset = this.scene.assets.getAsset('post-process', 'blur'); if (virtual) { blurAsset.data.radius = blur === undefined ? ROOT_BLURS[this.data.step] : blur; this.triggerEvent('requireLight', {state: 'hide'}); } else { blurAsset.data.radius = blur === undefined ? REAL_BLURS[this.data.step] : blur; } }, handleResume() { if (this.inited) { this.data.step === 3 ? this.bgm2.play() : this.bgm2.play(); } }, handleTouchObj({detail}) { if (!this.inDistance(detail)) { return; } const id = detail.value.target.id; const {texts} = this.config.items[id]; this.requireDialog({texts, from: 'item'}); }, handleTouchChar({detail}) { if (!this.inDistance(detail)) { return; } const id = this.data.step === 3 ? 'final' : detail.value.target.id; const {name, texts} = this.config.chars[id]; this.requireDialog({name, texts, from: 'char'}); }, requireDialog(info) { this.disable3DTouch = true; this.lightDuration = Infinity; this.triggerEvent('requireLight', {state: 'hide'}); info.name = info.name || '某个声音'; this.triggerEvent('requireDialog', info); }, inDistance(detail) { if (detail.value.camera.el.id !== 'main-camera') { return false; } if (this.disable3DTouch) { return false; } const xrSystem = wx.getXrFrameSystem(); const {camera, target} = detail.value; const camTrs = camera.el.getComponent(xrSystem.Transform); const targetTrs = target.getComponent(xrSystem.Transform); const diff = camTrs.worldPosition.sub(targetTrs.worldPosition); return Math.sqrt(diff.x * diff.x + diff.z * diff.z) < 3; } } })