massive interactive objects refactoring

This commit is contained in:
2026-04-04 10:57:43 +03:00
parent 401a6cb144
commit 6009d52139
30 changed files with 104 additions and 28 deletions
@@ -3,6 +3,10 @@ import { MeshStandardMaterial, MeshBasicMaterial, PlaneGeometry, Mesh, DoubleSid
class ImageObject { class ImageObject {
constructor(engine, obj) { constructor(engine, obj) {
return new Promise(async(resolve, reject)=>{ return new Promise(async(resolve, reject)=>{
if (obj.$go){
obj.path = engine.assetPath;
obj.value = obj.$go.asset.name;
}
var t = await engine.loadTexture(obj.value, obj.path) var t = await engine.loadTexture(obj.value, obj.path)
var mp = { var mp = {
map: t, map: t,
@@ -0,0 +1,34 @@
<template>
<div v-if="modelValue.go">
<v-img :src="`/asset/thumb/${modelValue.go}.webp`" />
<div class="text-caption text-center">{{ modelValue.title }}</div>
</div>
<asset-selector @select="assignTexture" :type="['Texture']">
<template v-slot:activator="props">
<v-btn v-bind="props" prepend-icon="mdi-video-box" color="deep-orange-darken-4" block>{{ l.chooseImage }}</v-btn>
</template>
</asset-selector>
</template>
<script>
export default {
data(){
return {
active: false
}
},
mounted(){
this.active = true;
},
props:{
modelValue: Object
},
methods:{
assignTexture(e){
this.modelValue.go = e.id;
this.modelValue.title = e.name;
}
}
}
</script>
@@ -1,24 +1,24 @@
import { Group, MeshStandardMaterial, Mesh, SphereGeometry, Vector3 } from "three"; import { Group, MeshStandardMaterial, Mesh, SphereGeometry, Vector3 } from "three";
import { EventManager } from '@/lib/EventManager'; import { EventManager } from '@/lib/EventManager';
import { GenericObject } from "./GenericObject"; import { GenericObject } from "./GenericObject/GenericObject";
import { TextObject } from "./TextObject"; import { TextObject } from "./TextObject/TextObject";
import { ImageObject } from "./ImageObject"; import { ImageObject } from "./ImageObject/ImageObject";
import { GltfObject } from "./GltfObject"; import { GltfObject } from "./GltfObject";
import { CharacterObject } from "./CharacterObject"; import { CharacterObject } from "./CharacterObject/CharacterObject";
import { VideoPlayer } from "./VideoPlayer"; import { VideoPlayer } from "./VideoPlayer/VideoPlayer";
import { PuzzleGame1 } from "./PuzzleGame1"; import { PuzzleGame1 } from "./PuzzleGame1/PuzzleGame1";
import { PuzzleGame2 } from "./PuzzleGame2"; import { PuzzleGame2 } from "./PuzzleGame2/PuzzleGame2";
// import { Game3 } from "./games/Game3"; // import { Game3 } from "./games/Game3";
import { PuzzleGame4 } from "./PuzzleGame4"; import { PuzzleGame4 } from "./PuzzleGame4";
import { ClassicPuzzle } from "./ClassicPuzzle"; import { ClassicPuzzle } from "./ClassicPuzzle/ClassicPuzzle";
import { PairMatchingGame } from "./PairMatchingGame"; import { PairMatchingGame } from "./PairMatchingGame/PairMatchingGame";
import { SingleQuestion } from "./SingleQuestion"; import { SingleQuestion } from "./SingleQuestion/SingleQuestion";
// import { Game5 } from "./games/Game5"; // import { Game5 } from "./games/Game5";
// import { Game6 } from "./games/Game6"; // import { Game6 } from "./games/Game6";
import { MazeQuizGame } from "./MazeQuizGame/MazeQuizGame"; import { MazeQuizGame } from "./MazeQuizGame/MazeQuizGame";
import { Particles } from "./Particles"; import { Particles } from "./Particles/Particles";
import { SceneSwitcher } from "./SceneSwitcher"; import { SceneSwitcher } from "./SceneSwitcher/SceneSwitcher";
import { GameEngine } from "@/lib/GameEngine"; import { GameEngine } from "@/lib/GameEngine";
const InteractiveObjectsImports = { const InteractiveObjectsImports = {
@@ -174,6 +174,8 @@ const InteractiveObjectTypes = [
'VideoPlayer', 'VideoPlayer',
'Particles', 'Particles',
'SceneSwitcher', 'SceneSwitcher',
'TextObject',
'ImageObject'
]; ];
export { InteractiveObject, InteractiveObjectTypes, InteractiveObjectsImports } export { InteractiveObject, InteractiveObjectTypes, InteractiveObjectsImports }
@@ -47,7 +47,7 @@
</template> </template>
<script> <script>
import SceneSwitcher from '../SceneSwitcher.vue'; import SceneSwitcher from '../SceneSwitcher/SceneSwitcher.vue';
export default { export default {
props:['modelValue'], props:['modelValue'],
@@ -11,7 +11,7 @@
<script> <script>
import { computed } from 'vue'; import { computed } from 'vue';
import OffsetLine from '../SceneDesigner/OffsetLine.vue'; import OffsetLine from '../../SceneDesigner/OffsetLine.vue';
export default { export default {
components:{ OffsetLine }, components:{ OffsetLine },
@@ -1,6 +1,6 @@
import { Group, Color } from 'three'; import { Group, Color } from 'three';
import { EventManager } from '@/lib/EventManager'; import { EventManager } from '@/lib/EventManager';
import { TextObject } from './TextObject'; import { TextObject } from '../TextObject/TextObject';
import Utils from '#/app/Utils'; import Utils from '#/app/Utils';
class SingleQuestion extends EventManager { class SingleQuestion extends EventManager {
@@ -0,0 +1,26 @@
<template>
<div>
<v-textarea :label="l.text" v-model="modelValue.text" class="mt-3"></v-textarea>
<v-number-input density="compact" :precision="null" :label="l.maxWidth" :step="0.1" v-model="modelValue.maxWidth"></v-number-input>
</div>
</template>
<script>
export default {
data(){
return {
active: false
}
},
mounted(){
this.modelValue.maxWidth ??= 1;
this.active = true;
},
props:{
modelValue: Object
},
methods:{
}
}
</script>
+13 -11
View File
@@ -46,23 +46,25 @@
<script> <script>
import SvgIcon from './SvgIcon.vue'; import SvgIcon from './SvgIcon.vue';
import VideoPlayer from '../InteractiveObjects/VideoPlayer.vue'; import VideoPlayer from '../InteractiveObjects/VideoPlayer/VideoPlayer.vue';
import PuzzleGame1 from '../InteractiveObjects/PuzzleGame1.vue'; import TextObject from '../InteractiveObjects/TextObject/TextObject.vue';
import PuzzleGame2 from '../InteractiveObjects/PuzzleGame2.vue'; import ImageObject from '../InteractiveObjects/ImageObject/ImageObject.vue';
import PuzzleGame1 from '../InteractiveObjects/PuzzleGame1/PuzzleGame1.vue';
import PuzzleGame2 from '../InteractiveObjects/PuzzleGame2/PuzzleGame2.vue';
import MazeQuizGame from '../InteractiveObjects/MazeQuizGame/MazeQuizGame.vue'; import MazeQuizGame from '../InteractiveObjects/MazeQuizGame/MazeQuizGame.vue';
import ClassicPuzzle from '../InteractiveObjects/ClassicPuzzle.vue'; import ClassicPuzzle from '../InteractiveObjects/ClassicPuzzle/ClassicPuzzle.vue';
import PairMatchingGame from '../InteractiveObjects/PairMatchingGame.vue'; import PairMatchingGame from '../InteractiveObjects/PairMatchingGame/PairMatchingGame.vue';
import SingleQuestion from '../InteractiveObjects/SingleQuestion.vue'; import SingleQuestion from '../InteractiveObjects/SingleQuestion/SingleQuestion.vue';
import Particles from '../InteractiveObjects/Particles.vue'; import Particles from '../InteractiveObjects/Particles/Particles.vue';
import GenericObject from '../InteractiveObjects/GenericObject.vue'; import GenericObject from '../InteractiveObjects/GenericObject/GenericObject.vue';
import CharacterObject from '../InteractiveObjects/CharacterObject.vue'; import CharacterObject from '../InteractiveObjects/CharacterObject/CharacterObject.vue';
import SceneSwitcher from '../InteractiveObjects/SceneSwitcher.vue'; import SceneSwitcher from '../InteractiveObjects/SceneSwitcher/SceneSwitcher.vue';
import OffsetLine from './OffsetLine.vue'; import OffsetLine from './OffsetLine.vue';
import { InteractiveObjectTypes } from '../InteractiveObjects/InteractiveObject'; import { InteractiveObjectTypes } from '../InteractiveObjects/InteractiveObject';
const components = { const components = {
SvgIcon, OffsetLine, GenericObject, CharacterObject, VideoPlayer, SceneSwitcher, SvgIcon, OffsetLine, GenericObject, CharacterObject, VideoPlayer, TextObject, ImageObject, SceneSwitcher,
PuzzleGame1, PuzzleGame2, MazeQuizGame, Particles, ClassicPuzzle, PairMatchingGame, SingleQuestion PuzzleGame1, PuzzleGame2, MazeQuizGame, Particles, ClassicPuzzle, PairMatchingGame, SingleQuestion
}; };
+1 -1
View File
@@ -6,7 +6,7 @@ import {
import { Text } from "troika-three-text"; import { Text } from "troika-three-text";
import { EventManager } from "./EventManager"; import { EventManager } from "./EventManager";
import Utils from "#/app/Utils"; import Utils from "#/app/Utils";
import { TextObject } from "@/components/InteractiveObjects/TextObject"; import { TextObject } from "@/components/InteractiveObjects/TextObject/TextObject";
class DashBoard extends EventManager { class DashBoard extends EventManager {
#points = 0; #points = 0;
constructor(engine) { constructor(engine) {
+1 -1
View File
@@ -1,5 +1,5 @@
import { InteractiveObject } from "@/components/InteractiveObjects/InteractiveObject"; import { InteractiveObject } from "@/components/InteractiveObjects/InteractiveObject";
import { VideoPlayer } from '@/components/InteractiveObjects/VideoPlayer'; import { VideoPlayer } from '@/components/InteractiveObjects/VideoPlayer/VideoPlayer';
import { Hero } from "./Hero"; import { Hero } from "./Hero";
import { api } from "./Api"; import { api } from "./Api";
import { EventManager } from "./EventManager"; import { EventManager } from "./EventManager";
+8
View File
@@ -71,7 +71,9 @@ const lang = {
selectIntroduction: 'Select introduction video', selectIntroduction: 'Select introduction video',
selectAmbientSound: 'Select ambient music', selectAmbientSound: 'Select ambient music',
width: 'Width', width: 'Width',
maxWidth: 'Max width',
height: 'Height', height: 'Height',
text: 'Text',
question: 'Question', question: 'Question',
addQuestion: 'Add question', addQuestion: 'Add question',
manageQuestions: 'Manage questions', manageQuestions: 'Manage questions',
@@ -137,6 +139,8 @@ const lang = {
PairMatchingGame: 'Pair Matching Game', PairMatchingGame: 'Pair Matching Game',
SingleQuestion: 'Single Question', SingleQuestion: 'Single Question',
VideoPlayer: 'Video Player', VideoPlayer: 'Video Player',
TextObject: 'Text',
ImageObject: 'Image',
Particles: 'Particles', Particles: 'Particles',
SceneSwitcher: 'Scene Switcher', SceneSwitcher: 'Scene Switcher',
}, },
@@ -234,7 +238,9 @@ const lang = {
selectIntroduction: 'Избери въвеждащо видео', selectIntroduction: 'Избери въвеждащо видео',
selectAmbientSound: 'Избери фонова музика', selectAmbientSound: 'Избери фонова музика',
width: 'Ширина', width: 'Ширина',
maxWidth: 'Максимална ширина',
height: 'Височина', height: 'Височина',
text: 'Текст',
question: 'Въпрос', question: 'Въпрос',
addQuestion: 'Добавяне на въпрос', addQuestion: 'Добавяне на въпрос',
manageQuestions: 'Въвеждане на въпросите', manageQuestions: 'Въвеждане на въпросите',
@@ -300,6 +306,8 @@ const lang = {
PairMatchingGame: 'Игра за съпоставяне на двойки', PairMatchingGame: 'Игра за съпоставяне на двойки',
SingleQuestion: 'Единичен въпрос', SingleQuestion: 'Единичен въпрос',
VideoPlayer: 'Видео обект', VideoPlayer: 'Видео обект',
TextObject: 'Текст',
ImageObject: 'Изображение',
Particles: 'Частици', Particles: 'Частици',
SceneSwitcher: 'Превключвател на сцени', SceneSwitcher: 'Превключвател на сцени',
}, },