From 136daa36ac2f3368b51effcfbcb9ca926445e9ac Mon Sep 17 00:00:00 2001 From: goynov Date: Mon, 2 Feb 2026 17:57:21 +0200 Subject: [PATCH] new interactive object - single question --- .../InteractiveObjects/InteractiveObject.js | 6 ++- .../InteractiveObjects/SingleQuestion.js | 45 +++++++++++++++++++ .../InteractiveObjects/SingleQuestion.vue | 40 +++++++++++++++++ src/components/SceneDesigner/GameObject.vue | 3 +- 4 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 src/components/InteractiveObjects/SingleQuestion.js create mode 100644 src/components/InteractiveObjects/SingleQuestion.vue diff --git a/src/components/InteractiveObjects/InteractiveObject.js b/src/components/InteractiveObjects/InteractiveObject.js index 40f8606..e07c953 100644 --- a/src/components/InteractiveObjects/InteractiveObject.js +++ b/src/components/InteractiveObjects/InteractiveObject.js @@ -13,6 +13,7 @@ import { PuzzleGame2 } from "./PuzzleGame2"; import { PuzzleGame4 } from "./PuzzleGame4"; import { ClassicPuzzle } from "./ClassicPuzzle"; import { PairMatchingGame } from "./PairMatchingGame"; +import { SingleQuestion } from "./SingleQuestion"; // import { Game5 } from "./games/Game5"; // import { Game6 } from "./games/Game6"; import { MazeQuizGame } from "./MazeQuizGame/MazeQuizGame"; @@ -23,7 +24,7 @@ import { GameEngine } from "@/lib/GameEngine"; const InteractiveObjectsImports = { GenericObject, CharacterObject, TextObject, ImageObject, GltfObject, VideoPlayer, Particles, SceneSwitcher, - PuzzleGame1, PuzzleGame2, PuzzleGame4, MazeQuizGame, ClassicPuzzle, PairMatchingGame + PuzzleGame1, PuzzleGame2, PuzzleGame4, MazeQuizGame, ClassicPuzzle, PairMatchingGame, SingleQuestion }; class InteractiveObject extends EventManager{ @@ -52,6 +53,7 @@ class InteractiveObject extends EventManager{ case 'MazeQuizGame': case 'ClassicPuzzle': case 'PairMatchingGame': + case 'SingleQuestion': case 'Particles': case 'SceneSwitcher': this.io = await new InteractiveObjectsImports[obj.type](engine, obj); @@ -165,6 +167,8 @@ const InteractiveObjectTypes = [ id: 'ClassicPuzzle', name: 'Classic Puzzle Game' },{ id: 'PairMatchingGame', name: 'Pair Matching Game' + },{ + id: 'SingleQuestion', name: 'Single Question' },{ id: 'VideoPlayer', name: 'Video Player' },{ diff --git a/src/components/InteractiveObjects/SingleQuestion.js b/src/components/InteractiveObjects/SingleQuestion.js new file mode 100644 index 0000000..677e440 --- /dev/null +++ b/src/components/InteractiveObjects/SingleQuestion.js @@ -0,0 +1,45 @@ +import { Group, Color } from 'three'; +import { centerOrigin } from '@/lib/MeshUtils'; +import { EventManager } from '@/lib/EventManager'; +import { TextObject } from './TextObject'; +import Utils from '@/lib/Utils'; + +class SingleQuestion extends EventManager { + emits = ['finish'] + constructor(engine, data) { + super(); + return new Promise(async (resolve, reject)=>{ + const container = new Group(); + const question = await new TextObject(engine, { text: data.q, fontSize: 0.125 }); + const answers = new Group(); + let ca = data.a[0]; + let ans = Utils.shuffleArray(data.a.filter(e=>!!e)); + for (let i=0; i { + //if (!container.visible) return; + if (qa.object._answer == ca) { + this.dispatchEvent({type:'finish'}) + qa.object.outlineColor = new Color(0x55ff55); + answers.children.forEach(c => engine.clickable.remove(c)); + } else { + qa.object.outlineColor = new Color(0xff5555); + setTimeout(() => { + qa.object.outlineColor = new Color(0xffffff); + }, 1000); + } + }); + } + container.add(question.object); + container.add(answers); + this.object = centerOrigin(container); + resolve(this); + }) + } +} + +export { SingleQuestion } \ No newline at end of file diff --git a/src/components/InteractiveObjects/SingleQuestion.vue b/src/components/InteractiveObjects/SingleQuestion.vue new file mode 100644 index 0000000..a717c36 --- /dev/null +++ b/src/components/InteractiveObjects/SingleQuestion.vue @@ -0,0 +1,40 @@ + + + \ No newline at end of file diff --git a/src/components/SceneDesigner/GameObject.vue b/src/components/SceneDesigner/GameObject.vue index c6ade95..5841140 100644 --- a/src/components/SceneDesigner/GameObject.vue +++ b/src/components/SceneDesigner/GameObject.vue @@ -52,6 +52,7 @@ import PuzzleGame2 from '../InteractiveObjects/PuzzleGame2.vue'; import MazeQuizGame from '../InteractiveObjects/MazeQuizGame/MazeQuizGame.vue'; import ClassicPuzzle from '../InteractiveObjects/ClassicPuzzle.vue'; import PairMatchingGame from '../InteractiveObjects/PairMatchingGame.vue'; +import SingleQuestion from '../InteractiveObjects/SingleQuestion.vue'; import Particles from '../InteractiveObjects/Particles.vue'; import GenericObject from '../InteractiveObjects/GenericObject.vue'; import CharacterObject from '../InteractiveObjects/CharacterObject.vue'; @@ -62,7 +63,7 @@ import { InteractiveObjectTypes } from '../InteractiveObjects/InteractiveObject' const components = { SvgIcon, OffsetLine, GenericObject, CharacterObject, VideoPlayer, SceneSwitcher, - PuzzleGame1, PuzzleGame2, MazeQuizGame, Particles, ClassicPuzzle, PairMatchingGame + PuzzleGame1, PuzzleGame2, MazeQuizGame, Particles, ClassicPuzzle, PairMatchingGame, SingleQuestion }; export default {