diff --git a/src/components/InteractiveObjects/InteractiveObject.js b/src/components/InteractiveObjects/InteractiveObject.js index 23f2df1..994b3d7 100644 --- a/src/components/InteractiveObjects/InteractiveObject.js +++ b/src/components/InteractiveObjects/InteractiveObject.js @@ -19,10 +19,11 @@ import { SingleQuestion } from "./SingleQuestion/SingleQuestion"; import { MazeQuizGame } from "./MazeQuizGame/MazeQuizGame"; import { Particles } from "./Particles/Particles"; import { SceneSwitcher } from "./SceneSwitcher/SceneSwitcher"; +import { Teleporter } from "./Teleporter/Teleporter"; import { GameEngine } from "@/lib/GameEngine"; const InteractiveObjectsImports = { - GenericObject, CharacterObject, TextObject, ImageObject, GltfObject, VideoPlayer, Particles, SceneSwitcher, + GenericObject, CharacterObject, TextObject, ImageObject, GltfObject, VideoPlayer, Particles, SceneSwitcher, Teleporter, PuzzleGame1, PuzzleGame2, PuzzleGame4, MazeQuizGame, ClassicPuzzle, PairMatchingGame, SingleQuestion }; @@ -56,6 +57,7 @@ class InteractiveObject extends EventManager{ case 'SingleQuestion': case 'Particles': case 'SceneSwitcher': + case 'Teleporter': this.io = await new InteractiveObjectsImports[obj.type](engine, obj); this.source = this.io.source || this.io; this.object = this.io.object; @@ -174,6 +176,7 @@ const InteractiveObjectTypes = [ 'VideoPlayer', 'Particles', 'SceneSwitcher', + 'Teleporter', 'TextObject', 'ImageObject' ]; diff --git a/src/components/InteractiveObjects/Teleporter/Teleporter.js b/src/components/InteractiveObjects/Teleporter/Teleporter.js new file mode 100644 index 0000000..e731caf --- /dev/null +++ b/src/components/InteractiveObjects/Teleporter/Teleporter.js @@ -0,0 +1,41 @@ +import { Group, CylinderGeometry, Mesh, MeshStandardMaterial } from 'three'; +import { EventManager } from '@/lib/EventManager'; +//import { TextObject } from '../TextObject/TextObject'; + +class Teleporter extends EventManager { + emits = ['interaction'] + constructor(engine, data) { + super(); + return new Promise(async (resolve, reject)=>{ + const container = new Group(); + const geometry = new CylinderGeometry(0.25, 0.25, 0.1); + const material = new MeshStandardMaterial({ + color: 0x55aaff, roughness: 0.1, metalness: 0.9 + }); + const s1 = new Mesh(geometry, material); + s1.isIndividual = true; + s1.name = 'T1'; + engine.clickable.add(s1, ()=>{ + this.dispatchEvent({type:'interaction', value: 'T1'}); + engine.hero?.teleport(s2.position) + }); + const s2 = s1.clone(); + s2.isIndividual = true; + s2.name = 'T2'; + engine.clickable.add(s2, ()=>{ + this.dispatchEvent({type:'interaction', value: 'T2'}) + engine.hero?.teleport(s1.position) + }); + s1.position.x = -1; + s2.position.x = 1; + container.add(s1); + container.add(s2); + + this.object = engine.meshUtils.centerOrigin(container); + this.object.hasIndividualChildren = true; + resolve(this); + }) + } +} + +export { Teleporter } \ No newline at end of file diff --git a/src/components/InteractiveObjects/Teleporter/Teleporter.vue b/src/components/InteractiveObjects/Teleporter/Teleporter.vue new file mode 100644 index 0000000..9a49b60 --- /dev/null +++ b/src/components/InteractiveObjects/Teleporter/Teleporter.vue @@ -0,0 +1,22 @@ + + + \ No newline at end of file diff --git a/src/components/SceneDesigner/GameObject.vue b/src/components/SceneDesigner/GameObject.vue index 9828b6c..0c4e490 100644 --- a/src/components/SceneDesigner/GameObject.vue +++ b/src/components/SceneDesigner/GameObject.vue @@ -59,13 +59,14 @@ import Particles from '../InteractiveObjects/Particles/Particles.vue'; import GenericObject from '../InteractiveObjects/GenericObject/GenericObject.vue'; import CharacterObject from '../InteractiveObjects/CharacterObject/CharacterObject.vue'; import SceneSwitcher from '../InteractiveObjects/SceneSwitcher/SceneSwitcher.vue'; +import Teleporter from '../InteractiveObjects/Teleporter/Teleporter.vue'; import OffsetLine from './OffsetLine.vue'; import { InteractiveObjectTypes } from '../InteractiveObjects/InteractiveObject'; const components = { SvgIcon, OffsetLine, GenericObject, CharacterObject, VideoPlayer, TextObject, ImageObject, SceneSwitcher, - PuzzleGame1, PuzzleGame2, MazeQuizGame, Particles, ClassicPuzzle, PairMatchingGame, SingleQuestion + PuzzleGame1, PuzzleGame2, MazeQuizGame, Particles, ClassicPuzzle, PairMatchingGame, SingleQuestion, Teleporter }; export default { diff --git a/src/lib/Hero.js b/src/lib/Hero.js index 4b3baf1..bd32b47 100644 --- a/src/lib/Hero.js +++ b/src/lib/Hero.js @@ -119,7 +119,7 @@ class Hero{ this.model.rotation.reorder('YZX'); } - update(delta){ + update(delta){ if (this.ready && this.engine.physics.started && !this.disableInput) { this.updateCharacterControls(delta) if (this.engine.renderer.xr.isPresenting && !this.fpv){ @@ -340,6 +340,26 @@ class Hero{ //this.currentAction = 'idle' } + async teleport(v3){ + if (this.model.visible){ + await this.engine.motionQueue.add({ + o: this.model, + a: { visible: k => Math.round(k * 20) % 2 == 0}, + t: 1.5, p: true + }) + this.po.rigidBody.setNextKinematicTranslation(v3); + this.model.position.copy(v3); + await this.engine.motionQueue.add({ + o: this.model, + a: { visible: k => Math.round(k * 20) % 2 == 0}, + t: 1.5, p: true + }) + }else{ + this.po.rigidBody.setNextKinematicTranslation(v3); + this.model.position.copy(v3); + } + } + } export { Hero } \ No newline at end of file diff --git a/src/plugins/lang.js b/src/plugins/lang.js index e08e08f..2d9fcf9 100644 --- a/src/plugins/lang.js +++ b/src/plugins/lang.js @@ -143,6 +143,7 @@ const lang = { ImageObject: 'Image', Particles: 'Particles', SceneSwitcher: 'Scene Switcher', + Teleporter: 'Teleporter', }, errors:{ unauthorized: 'Unauthorized', @@ -310,6 +311,7 @@ const lang = { ImageObject: 'Изображение', Particles: 'Частици', SceneSwitcher: 'Превключвател на сцени', + Teleporter: 'Телепортатор' }, errors:{ unauthorized: 'Отказан достъп',