index.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import XrTeamCameraAnimation from '../../xr-custom/animations/XrTeamCameraAnimation';
  2. Component({
  3. behaviors: [require('../common/share-behavior').default],
  4. properties: {
  5. loaded: false,
  6. run: {
  7. type: Boolean,
  8. value: false,
  9. observer: function(newVal, oldVal) {
  10. if (newVal && newVal !== oldVal) {
  11. this.requireRun = true;
  12. }
  13. }
  14. }
  15. },
  16. lifetimes: {
  17. detached: function() {
  18. this.voice.stop();
  19. this.bgm.stop();
  20. },
  21. },
  22. methods: {
  23. handleReady({detail}) {
  24. const xrScene = this.scene = detail.value;
  25. console.log('xr-scene', xrScene);
  26. this.bgm = wx.createInnerAudioContext({});
  27. this.bgm.src = 'https://mmbizwxaminiprogram-1258344707.cos.ap-guangzhou.myqcloud.com/xr-frame/demo/kaqituolitai.mp3';
  28. this.bgm.volume = 0.5;
  29. this.voice = wx.createInnerAudioContext({useWebAudioImplement: true});
  30. this.voice.src = 'https://mmbizwxaminiprogram-1258344707.cos.ap-guangzhou.myqcloud.com/xr-frame/demo/homo.m4a';
  31. this.voiceFrag = {
  32. xinyi: [4, 2],
  33. roam: [6.8, 2],
  34. hikari: [53.9, 2],
  35. jump: [8.9, 1.5]
  36. };
  37. this.tmpV3 = new (wx.getXrFrameSystem().Vector3)();
  38. },
  39. handleAssetsLoaded: function({detail}) {
  40. this.triggerEvent('assetsLoaded', detail.value);
  41. },
  42. handleRaf: function({detail}) {
  43. if (!this.init()) {
  44. return;
  45. }
  46. if (this.requireRun) {
  47. this.requireRun = false;
  48. this.run();
  49. }
  50. this.triggerEvent('syncPositions', [
  51. this.getScreenPosition(this.hikari, '瞬光'),
  52. this.getScreenPosition(this.roam, 'roam'),
  53. this.getScreenPosition(this.xinyi, 'xinyi')
  54. ]);
  55. },
  56. getScreenPosition: function(char, name) {
  57. this.tmpV3.set(char.worldPosition);
  58. this.tmpV3.x += -0.1;
  59. this.tmpV3.y += 1.2;
  60. const clipPos = this.camera.convertWorldPositionToClip(this.tmpV3);
  61. const {frameWidth, frameHeight} = this.scene;
  62. return [((clipPos.x + 1) / 2) * frameWidth, (1 - (clipPos.y + 1) / 2) * frameHeight, name];
  63. },
  64. init: function() {
  65. if (!this.camera) {
  66. const camEl = this.scene.getElementById('camera');
  67. this.camera = camEl.getComponent(wx.getXrFrameSystem().Camera);
  68. this.cameraCtrl = camEl.getComponent('camera-orbit-control');
  69. }
  70. const inited = this.camera && this.hikari && this.roam && this.xinyi;
  71. if (inited && !this.cameraAnim) {
  72. this.cameraAnim = this.camera.el.addComponent(wx.getXrFrameSystem().Animator);
  73. this.cameraAnim.createAnimation(XrTeamCameraAnimation, {
  74. targets: {
  75. hikari: this.hikari.position,
  76. roam: this.roam.position,
  77. xinyi: this.xinyi.position,
  78. final: this.hikari.position
  79. },
  80. startY: 1.2,
  81. finalY: 0.8
  82. });
  83. }
  84. return inited;
  85. },
  86. handleModelLoaded: function({detail}) {
  87. const {target} = detail.value;
  88. this[target.id] = target.getComponent(wx.getXrFrameSystem().Transform);
  89. },
  90. run: async function() {
  91. this.cameraCtrl.disable();
  92. await this.prepareRun('xinyi');
  93. await this.prepareRun('roam');
  94. await this.prepareRun('hikari');
  95. await this.prepareCamera();
  96. this.runOne(this.hikari);
  97. this.runOne(this.roam);
  98. this.runOne(this.xinyi);
  99. this.cameraCtrl.enable();
  100. },
  101. prepareRun: async function(char) {
  102. const voiceFrag = this.voiceFrag[char];
  103. return new Promise(resolve => {
  104. const animator = this[char].el.getComponent(wx.getXrFrameSystem().Animator);
  105. this.cameraAnim.play(char);
  106. this.cameraAnim.el.event.addOnce('anim-stop', () => {
  107. this.voice.seek(voiceFrag[0]);
  108. this.voice.play();
  109. setTimeout(() => {
  110. this.voice.stop();
  111. animator.stop();
  112. animator.pauseToFrame('Run', 0);
  113. setTimeout(() => resolve(), 200);
  114. }, voiceFrag[1] * 1000);
  115. });
  116. });
  117. },
  118. prepareCamera: async function() {
  119. this.bgm.play();
  120. this.bgm.seek(46);
  121. return new Promise(resolve => {
  122. this.cameraAnim.play('final');
  123. this.cameraAnim.el.event.addOnce('anim-stop', () => {
  124. setTimeout(() => {
  125. resolve();
  126. }, 1000);
  127. });
  128. });
  129. },
  130. runOne: function(char) {
  131. const animator = char.el.getComponent(wx.getXrFrameSystem().Animator);
  132. animator.resume();
  133. const jump = () => {
  134. this.voice.seek(this.voiceFrag.jump[0]);
  135. this.voice.play();
  136. animator.stop();
  137. animator.play('Jump', {loop: 0});
  138. animator.el.event.addOnce('anim-stop', () => {
  139. animator.play('Run');
  140. this.voice.stop();
  141. });
  142. char.el.event.addOnce('touch-shape', jump);
  143. }
  144. char.el.event.addOnce('touch-shape', jump);
  145. }
  146. }
  147. })