diff --git a/src/components/InteractiveObjects/InteractiveObject.js b/src/components/InteractiveObjects/InteractiveObject.js
index 25f946e..a70fbfe 100644
--- a/src/components/InteractiveObjects/InteractiveObject.js
+++ b/src/components/InteractiveObjects/InteractiveObject.js
@@ -1,4 +1,5 @@
-import { Group, EventDispatcher, MeshStandardMaterial, Mesh, SphereGeometry } from "three";
+import { Group, MeshStandardMaterial, Mesh, SphereGeometry, Vector3 } from "three";
+import { EventManager } from '@/lib/EventManager';
import { GenericObject } from "./GenenricObject";
import { TextObject } from "./TextObject";
@@ -15,16 +16,17 @@ import { ClassicPuzzle } from "./ClassicPuzzle";
// import { Game6 } from "./games/Game6";
import { MazeQuizGame } from "./MazeQuizGame/MazeQuizGame";
import { Particles } from "./Particles";
-import { assignMaterial, assignParams, wrapInGroup, getBoundingBoxMaxLength } from "@/lib/MeshUtils";
-import { GameEngine } from "@/lib/GameEngine";
+import { SceneSwitcher } from "./SceneSwitcher";
+import { assignParams, wrapInGroup, getBoundingBoxMaxLength } from "@/lib/MeshUtils";
+import { GameEngine } from "@/lib/GameEngine";
const InteractiveObjectsImports = {
- GenericObject, CharacterObject, TextObject, ImageObject, GltfObject, VideoPlayer, Particles,
+ GenericObject, CharacterObject, TextObject, ImageObject, GltfObject, VideoPlayer, Particles, SceneSwitcher,
PuzzleGame1, PuzzleGame2, PuzzleGame4, MazeQuizGame, ClassicPuzzle
};
-class InteractiveObject extends EventDispatcher{
- constructor(gameEngine, obj) {
+class InteractiveObject extends EventManager{
+ constructor(engine, obj) {
super();
this.name = obj.name;
return new Promise(async (resolve, reject) => {
@@ -32,7 +34,7 @@ class InteractiveObject extends EventDispatcher{
case 'Group':
this.object = new Group();
for (let g of obj.group){
- let gameMesh = await new InteractiveObject(gameEngine, g);
+ let gameMesh = await new InteractiveObject(engine, g);
this.object.add(gameMesh.object);
}
break;
@@ -47,38 +49,72 @@ class InteractiveObject extends EventDispatcher{
case 'MazeQuizGame':
case 'ClassicPuzzle':
case 'Particles':
- this.io = await new InteractiveObjectsImports[obj.type](gameEngine, obj);
+ case 'SceneSwitcher':
+ this.io = await new InteractiveObjectsImports[obj.type](engine, obj);
this.source = this.io.source || this.io;
this.object = this.io.object;
this.emits = this.io.emits;
- this.io.emits?.forEach(event=>{
- this.io.addEventListener?.(event, this.dispatchEvent.bind(this))
- })
+ // this.io.emits?.forEach(event=>{
+ // this.io.addEventListener?.(event, this.dispatchEvent.bind(this))
+ // })
+ this.io.forwardEvents?.(this);
break;
}
if (obj.shouldBeLocked){
this.object = wrapInGroup(this.object)
- this.locker = new Locker(gameEngine, this.object);
- this.locker.lock();
+ this.activator = new (obj.activationType == 'unlock' ? LockActivator : VisibilityActivator)(engine, this.object);
+ this.activator.deactivate();
}
assignParams(this.object, obj);
if (obj.motion){
- gameEngine.motionQueue.add({
+ engine.motionQueue.add({
o: this.object, ...obj.motion
});
}
+
+ if (obj.distance) {
+ const o = this.object;
+ let dstm = obj.distance;
+ let v = new Vector3();
+ o.visible = false;
+ engine.addEventListener('beforeRender', function () {
+ o.getWorldPosition(v);
+ var dst = engine.camera.position.distanceTo(v);
+ if (dst <= dstm && !o.visible) {
+ o.visible = true;
+ }else if (dst > dstm && o.visible){
+ o.visible = false;
+ }
+ });
+ }
resolve(this);
});
}
}
-class Locker{
+class VisibilityActivator{
+ constructor(engine, group){
+ this.deactivate = function(){
+ group.visible = false;
+ group.__active = false;
+ }
+ this.activate = function(){
+ group.visible = true;
+ group.__active = true;
+ }
+ this.isActive = function(){
+ return group.__active;
+ }
+ }
+}
+
+class LockActivator{
static materialLocked = new MeshStandardMaterial({
transparent: true, opacity:1, color: 0xaaaaaa
})
constructor(engine, group){
const bckGeometry = new SphereGeometry(getBoundingBoxMaxLength(group.userData.bbox)/2,8,8)
- const bckMesh = new Mesh(bckGeometry, Locker.materialLocked);
+ const bckMesh = new Mesh(bckGeometry, LockActivator.materialLocked);
bckMesh.visible = false;
group.add(bckMesh)
function animate(){
@@ -91,24 +127,29 @@ class Locker{
)
}
this.object = bckMesh;
- this.lock = function(){
+ this.deactivate = function(){
bckMesh.visible = true;
//bckMesh.material.needsUpdate = true;
engine.motionQueue.clear(bckMesh);
- group.__locked = true;
+ group.__active = false;
animate();
}
- this.unlock = function(){
+ this.activate = function(){
bckMesh.visible = false;
engine.motionQueue.clear(bckMesh);
- group.__locked = false;
+ group.__active = true;
+ }
+ this.isActive = function(){
+ return group.__active;
}
}
}
-GameEngine.loadTexture('locked.webp', '/static/textures/', null, [Locker.materialLocked, 'alphaMap'])
+GameEngine.loadTexture('locked.webp', '/static/textures/', null, [LockActivator.materialLocked, 'alphaMap'])
const InteractiveObjectTypes = [
{
+ id: 'GenericObject', name: 'Generic Game Object'
+ },{
id: 'CharacterObject', name: 'Character'
}, {
id: 'PuzzleGame1', name: 'Puzzle Game 1'
@@ -122,6 +163,8 @@ const InteractiveObjectTypes = [
id: 'VideoPlayer', name: 'Video Player'
},{
id: 'Particles', name: 'Particles'
+ },{
+ id: 'SceneSwitcher', name: 'Scene Switcher'
}
];
diff --git a/src/components/InteractiveObjects/MazeQuizGame/MazeObject.js b/src/components/InteractiveObjects/MazeQuizGame/MazeObject.js
index 795a5a8..50dad0e 100644
--- a/src/components/InteractiveObjects/MazeQuizGame/MazeObject.js
+++ b/src/components/InteractiveObjects/MazeQuizGame/MazeObject.js
@@ -126,6 +126,7 @@ class MazeObject {
go.object.scale.multiplyScalar(wallSize)
go.object.position.multiplyScalar(wallSize)
go.object.applyMatrix4(def.matrix);
+ go.forwardEvents?.(params.io);
root.add(go.object);
});
diff --git a/src/components/InteractiveObjects/MazeQuizGame/MazeQuizGame.js b/src/components/InteractiveObjects/MazeQuizGame/MazeQuizGame.js
index bd89212..38b41c7 100644
--- a/src/components/InteractiveObjects/MazeQuizGame/MazeQuizGame.js
+++ b/src/components/InteractiveObjects/MazeQuizGame/MazeQuizGame.js
@@ -1,6 +1,6 @@
import { MazeObject } from "./MazeObject";
import Utils from "@/lib/Utils";
-import { EventDispatcher } from "three";
+import { EventManager } from '@/lib/EventManager';
const params = {
scale: 3,
@@ -17,7 +17,7 @@ const imgParams = {
}
const textParams = {
- type: 'TextObject', width:0.44,
+ type: 'TextObject', maxWidth:0.44,
fontPath:'/static/fonts/Montserrat-Regular.ttf',
fontSize:0.025, distance: params.wallSize*2
}
@@ -37,12 +37,14 @@ const defaults = {
const tl = 4;
-class MazeQuizGame extends EventDispatcher {
- emits = ['finish']
+class MazeQuizGame extends EventManager {
+ emits = ['finish', 'sceneSwitch']
constructor(engine, data) {
super();
+ this.data = data;
data.noPhysics = true;
params.mazeFile = data.style || 'quiz-s2.gltf';
+ params.io = this;
return new Promise(async (resolve, reject)=>{
let questions = data.shuffle ? Utils.shuffleArray(data.questions) : data.questions;
let def = this.generate(questions);
@@ -101,11 +103,16 @@ class MazeQuizGame extends EventDispatcher {
len,
userData: { finish: true },
objects:[
+ // {
+ // type: 'GltfObject',
+ // position:[0,.22,len + .52], scale: [0.33, 0.33, 0.33], rotation: [0, Math.PI/4, 0],
+ // value: 'trophy.glb', path: imgParams.path, distance: params.wallSize*2,
+ // motion: { a:{rotation: { y: k=>k*Math.PI*2 }}, r: true, t: 4 }
+ // }
{
- type: 'GltfObject',
- position:[0,.22,len + .52], scale: [0.33, 0.33, 0.33], rotation: [0, Math.PI/4, 0],
- value: 'trophy.glb', path: imgParams.path, distance: params.wallSize*2,
- motion: { a:{rotation: { y: k=>k*Math.PI*2 }}, r: true, t: 4 }
+ type: 'SceneSwitcher', switchScene: this.data.switchScene, switchType: this.data.switchType,
+ position:[0,.22,len + .52], scale: [0.33, 0.33, 0.33],
+ distance: params.wallSize*2
}
]
};
@@ -116,7 +123,7 @@ class MazeQuizGame extends EventDispatcher {
len, userData: { question, qid },
objects:[
{
- ...textParams, text: question.q, fontSize:0.033, width:0.55, position:[0,.55,len + .96], rotation:[0,Math.PI, 0]
+ ...textParams, text: question.q, fontSize:0.033, maxWidth:0.55, position:[0,.55,len + .96], rotation:[0,Math.PI, 0]
}
]
}
@@ -149,7 +156,7 @@ class MazeQuizGame extends EventDispatcher {
len: 3,
objects:[
{
- ...textParams, color:0xc71414, text: question.h, fontSize:0.033, width:0.66, position:[0,.44,3+.96], rotation:[0,Math.PI, 0]
+ ...textParams, color:0xc71414, text: question.h, fontSize:0.033, maxWidth:0.66, position:[0,.44,3+.96], rotation:[0,Math.PI, 0]
},{
...imgParams, value:'x.webp', position:[0,.33,3+.96], rotation:[0,Math.PI, 0]
}
diff --git a/src/components/InteractiveObjects/MazeQuizGame/MazeQuizGame.vue b/src/components/InteractiveObjects/MazeQuizGame/MazeQuizGame.vue
index 3ace2c1..8055afa 100644
--- a/src/components/InteractiveObjects/MazeQuizGame/MazeQuizGame.vue
+++ b/src/components/InteractiveObjects/MazeQuizGame/MazeQuizGame.vue
@@ -39,10 +39,13 @@
-
+
+
\ No newline at end of file
diff --git a/src/components/SceneDesigner/GameObject.vue b/src/components/SceneDesigner/GameObject.vue
index 965ff05..d06e32a 100644
--- a/src/components/SceneDesigner/GameObject.vue
+++ b/src/components/SceneDesigner/GameObject.vue
@@ -16,12 +16,14 @@
+
+
+
-
-
- Choose game object
-
-
+
@@ -35,10 +37,10 @@
+
-