change event dispatcher

This commit is contained in:
2025-11-11 15:15:13 +02:00
parent 35fa1863ff
commit 351c6097f3
10 changed files with 71 additions and 67 deletions
@@ -1,7 +1,9 @@
import { getBoundingBox, getBoundingBoxCenterPoint, getBoundingBoxMaxLength, centerOrigin } from "@/lib/MeshUtils";
import { EventDispatcher } from "three";
class GenericObject{
class GenericObject extends EventDispatcher{
constructor(engine, data){
super();
return new Promise(async(resolve, reject)=>{
this.source = await engine.load(data.$go.asset.name);
this.object = centerOrigin(this.source.scene)
@@ -34,7 +36,7 @@ class GenericObject{
}
if (data.description){
engine.dashboard.updateText(this.object._active ? data.description : '', (d)=>{
console.log('DONETEXT', d)
d && this.dispatchEvent({type:'finish'})
})
}
}
@@ -1,4 +1,4 @@
import { Group } from "three";
import { Group, EventDispatcher } from "three";
import { GenericObject } from "./GenenricObject";
import { TextObject } from "./TextObject";
@@ -16,12 +16,13 @@ import { Particles } from "./Particles";
import { assignMaterial, assignParams } from "@/lib/MeshUtils";
const InteractiveObjectsImports = {
PuzzleGame1, PuzzleGame2, PuzzleGame4, VideoPlayer,
GenericObject, CharacterObject, MazeQuizGame, Particles
GenericObject, CharacterObject, TextObject, ImageObject, VideoPlayer, Particles,
PuzzleGame1, PuzzleGame2, PuzzleGame4, MazeQuizGame
};
class InteractiveObject {
class InteractiveObject extends EventDispatcher{
constructor(gameEngine, obj) {
super();
this.name = obj.name;
return new Promise(async (resolve, reject) => {
switch (obj.type || 'GenericObject') {
@@ -32,14 +33,6 @@ class InteractiveObject {
this.object.add(gameMesh.object);
}
break;
case 'Text':
this.source = new TextObject(gameEngine, obj);
this.object = this.source.object;
break;
case 'Image':
this.source = new ImageObject(gameEngine, obj);
this.object = this.source.object;
break;
case 'Gltf':
let gltf = await gameEngine.load(obj.value, '');
let gltfObj = gltf.scene;
@@ -63,27 +56,20 @@ class InteractiveObject {
this.object = gltfObj;
this.source = gltf;
break;
case 'Text':
case 'Image':
case 'GenericObject':
case 'CharacterObject':
let go = await new InteractiveObjectsImports[obj.type](gameEngine, obj) //await gameEngine.load(obj.$go.asset.name);
this.source = go.source;
this.object = go.object;
break;
case 'PuzzleGame3':
case 'PuzzleGame4':
case 'PuzzleGame5':
case 'PuzzleGame6':
let game = new InteractiveObjectsImports[obj.type](gameEngine, obj.args[0], obj.args[1], obj.args[2]);
this.object = game.object;
this.object.game = game;
break;
case 'VideoPlayer':
case 'PuzzleGame1':
case 'PuzzleGame2':
case 'MazeQuizGame':
case 'Particles':
this.source = await new InteractiveObjectsImports[obj.type](gameEngine, obj);
this.object = this.source.object;
this.io = await new InteractiveObjectsImports[obj.type](gameEngine, obj);
this.source = this.io.source || this.io;
this.object = this.io.object;
this.io.addEventListener?.('finish', this.dispatchEvent.bind(this))
break;
}
assignParams(this.object, obj);
@@ -1,5 +1,6 @@
import { MazeObject } from "./MazeObject";
import Utils from "@/lib/Utils";
import { EventDispatcher } from "three";
const params = {
scale: 5,
@@ -34,7 +35,7 @@ const defaults = {
const tl = 4;
class MazeQuizGame {
class MazeQuizGame extends EventDispatcher {
constructor(engine, data) {
data.noPhysics = true;
return new Promise(async (resolve, reject)=>{
@@ -57,7 +58,7 @@ class MazeQuizGame {
engine.hero.characterControls.direction += Math.PI;
//engine.hero.model.rotation.y += Math.PI;
await Utils.wait(10000);
this.onfinish?.()
this.dispatchEvent({type:'finish'})
}else{
engine.hero.animationsMap.idle = engine.hero.animationsMap._idle
engine.hero.characterControls.cameraDelta = 0
@@ -1,9 +1,10 @@
import { BoxGeometry, Mesh, MeshStandardMaterial, Group } from 'three';
import { BoxGeometry, Mesh, MeshStandardMaterial, Group, EventDispatcher } from 'three';
import { MotionEngine } from '../../lib/MotionEngine';
import { centerOrigin } from '@/lib/MeshUtils';
class PuzzleGame1 {
class PuzzleGame1 extends EventDispatcher {
constructor(engine, data) {
super();
return new Promise(async (resolve, reject)=>{
let w = data.w, h = data.h, wh = w*h;
let container = new Group();
@@ -92,7 +93,9 @@ class PuzzleGame1 {
o: c,
a: { position: { x: i % w, y: Math.trunc(i/w)} },
t: 1,
f: i == 0 && this.onfinish || undefined
f: i == 0 ? ()=>{
this.dispatchEvent({type:'finish'})
} : undefined
});
});
//engine.dashboard.addPoints(10);
@@ -1,9 +1,10 @@
import { BoxGeometry, Mesh, MeshBasicMaterial, Group } from 'three';
import { BoxGeometry, Mesh, MeshBasicMaterial, Group, EventDispatcher } from 'three';
import { MotionEngine } from '../../lib/MotionEngine';
import { centerOrigin } from '@/lib/MeshUtils';
class PuzzleGame2 {
class PuzzleGame2 extends EventDispatcher {
constructor(engine, data) {
super();
return new Promise(async (resolve, reject)=>{
let w = data.w, h = data.h, wh = w*h;
const texture = await engine.loadTexture(data.$go.asset.name);
@@ -137,7 +138,9 @@ class PuzzleGame2 {
o: c,
a: { position: { x: i % w, y: ~~(i / h) } },
t: 1,
f: i == 0 ? this.onfinish : undefined
f: i == 0 ? ()=>{
this.dispatchEvent({type:'finish'})
} : undefined
});
});
//engine.dashboard.addPoints(10);
@@ -115,7 +115,7 @@ var PuzzleGame4 = function(context, gltf, w, h){
d:1+0.1*i
})
})
this.onfinish && this.onfinish();
this.dispatchEvent({type:'finish'})
//context.dashboard.addPoints(10);
}
}
@@ -1,25 +1,28 @@
import * as THREE from 'three';
import {
PlaneGeometry, MeshStandardMaterial, SRGBColorSpace,
VideoTexture, DoubleSide, Mesh, EventDispatcher
} from 'three';
class VideoPlayer {
class VideoPlayer extends EventDispatcher {
constructor(engine, data){
super();
let vi, plane;
return new Promise((resolve, reject)=>{
vi = document.createElement('video');
vi.src = engine.assetPath + data.$go.asset.name;
vi.addEventListener('loadedmetadata', ()=>{
this.aspect = vi.videoWidth / vi.videoHeight;
let geometry = new THREE.PlaneGeometry( this.aspect, 1 );
let map = new THREE.VideoTexture( vi );
map.colorSpace = THREE.SRGBColorSpace;
let material = new THREE.MeshStandardMaterial( {
let geometry = new PlaneGeometry( this.aspect, 1 );
let map = new VideoTexture( vi );
map.colorSpace = SRGBColorSpace;
let material = new MeshStandardMaterial( {
color: 0xffffff,
map,
transparent: true,
opacity: 0.5,
side: THREE.DoubleSide
side: DoubleSide
} );
plane = new THREE.Mesh( geometry, material );
plane = new Mesh( geometry, material );
this.object = plane;
engine.clickable.add(plane, ()=>{
if (vi.paused){
@@ -46,7 +49,7 @@ class VideoPlayer {
}
})
vi.addEventListener('ended', ()=>{
this.onfinish?.();
this.dispatchEvent({type:'finish'})
})
this.video = vi;
+20 -11
View File
@@ -53,11 +53,13 @@ class DashBoard {
const loadingPlane = new Mesh(
new PlaneGeometry(engine.aspect, 1),
new MeshBasicMaterial({
color:0xFAFAFA,
new MeshStandardMaterial({
color:0xffffff,
opacity:0, transparent:true,
roughness:0, metalness:0.1
})
);
const loadingProgress = new ProgressBar();
const loadingProgress = new ProgressBar(engine);
loadingProgress.object.scale.set(engine.aspect*0.8, 0.05, 0.05)
loadingProgress.object.position.set(-engine.aspect/2 + engine.aspect*0.1, 0, 0.1)
loadingPlane.add(loadingProgress.object);
@@ -135,7 +137,7 @@ class DashBoard {
})
}
levelProgress = new ProgressBar({})
levelProgress = new ProgressBar(engine)
dash.add(levelProgress.object);
levelProgress.object.position.set(-engine.aspect/2 + engine.aspect/30, 0.45, -0.01)
levelProgress.object.scale.set(engine.aspect/3, 0.02, 0.02)
@@ -230,11 +232,11 @@ class DashBoard {
hudAnimation = null;
}
this.loading = function(progress){
this.loading = function(progress, tt){
loadingPlane.visible = progress > 0 && progress < 1;
loadingProgress.update(progress)
loadingProgress.update(progress, tt)
}
this.loading(1);
this.loading(0,0);
}
get active(){
@@ -247,7 +249,7 @@ class DashBoard {
}
class ProgressBar{
constructor(params = {}){
constructor(engine, params = {}){
this.object = new Group();
const geometry = new CylinderGeometry( 0.5, 0.5, 1, 3, 1, false, 0, Math.PI );
const staticCylinder = new Mesh( geometry, new MeshStandardMaterial({
@@ -263,10 +265,17 @@ class ProgressBar{
progressCylinder.rotation.set(Math.PI/2, 0, Math.PI/2,)
this.object.add( progressCylinder );
this.update = function(value){
this.update = function(value, transitionTime = 0.5){
progressCylinder.visible = !!value;
progressCylinder.scale.y = value;
progressCylinder.position.x = progressCylinder.scale.y / 2
engine.motionQueue.clear(progressCylinder);
engine.motionQueue.add({
o: progressCylinder,
a: {
scale: {y: value},
position: {x: value / 2}
},
t: transitionTime
})
}
this.update(0)
+3 -3
View File
@@ -99,12 +99,12 @@ class GameEngine extends THREE.EventDispatcher{
this.stereo = new StereoEffect(renderer);
this.stereo.setSize(this.w, this.h);
const dashboard = new DashBoard(this);
this.dashboard = dashboard;
this.motionQueue = new MotionEngine();
this.assetPath = assetPath;
const dashboard = new DashBoard(this);
this.dashboard = dashboard;
this.activeObjects = new THREE.Group();
scene.add(this.activeObjects);
+3 -6
View File
@@ -119,7 +119,7 @@ export default {
//await gameEngine.loadPanorama(`/asset/default/43.webp`);
gameEngine.clearScene();
gameEngine.activeObjects.visible = false;
gameEngine.dashboard?.loading(0);
gameEngine.dashboard?.loading(0,0);
await this.expandScenarioData(scene);
gameEngine.dashboard?.loading(0.1);
@@ -147,9 +147,6 @@ export default {
let loaded = 0;
for (let i of this.scene.data.items) {
let io = await new InteractiveObject(gameEngine, i.data)
//let gltf = await gameEngine.load(`/asset/default/${i.data.$go.asset.name}`);
//console.log(i.data, io.object)
this.setObjectAttributes(l, i.data, io.object, io.source, 1);
gameEngine.activeObjects.add(io.object);
if (this.env == 'GamePlaying'){
@@ -169,10 +166,10 @@ export default {
})
}
}
io.onfinish=()=>{
io.addEventListener('finish', ()=>{
gameEngine.dashboard?.addPoints(i.data.points)
i.data.points = 0;
}
})
}
loaded += 1/this.scene.data.items.length
gameEngine.dashboard?.loading(0.1 + 0.89*loaded);