integrate game1 and game2
This commit is contained in:
@@ -62,14 +62,14 @@ export default{
|
||||
if (this.forRendering) {
|
||||
gameEngine.activeObjects.clear();
|
||||
if (this.obj.type == 'panorama2d') {
|
||||
await gameEngine.loadPanorama(`/asset/default/${this.obj.asset.name}`);
|
||||
await gameEngine.loadPanorama(this.obj.asset.name);
|
||||
// let t = await gameEngine.loadTexture(`/asset/default/${this.obj.asset.name}`);
|
||||
// t.mapping = gameEngine.$.EquirectangularReflectionMapping;
|
||||
// gameEngine.scene.background = t;
|
||||
// gameEngine.scene.environment = t;
|
||||
// gameEngine.scene.add(gameEngine.camera);
|
||||
} else {
|
||||
let gltf = await gameEngine.load(`/asset/default/${this.obj.asset.name}`);
|
||||
let gltf = await gameEngine.load(this.obj.asset.name);
|
||||
//console.debug('GLTF', gltf);
|
||||
this.loadedAsset = gltf;
|
||||
this.animations = gltf.animations.map(a => ({
|
||||
|
||||
@@ -11,7 +11,7 @@ import { VideoPlayer } from "./VideoPlayer";
|
||||
import { MazeQuizGame } from "./MazeQuizGame/MazeQuizGame";
|
||||
import { assignMaterial, assignParams } from "@/lib/MeshUtils";
|
||||
|
||||
const games = {PuzzleGame1, PuzzleGame2, PuzzleGame4};
|
||||
const games = {PuzzleGame1, PuzzleGame2, PuzzleGame4, MazeQuizGame};
|
||||
|
||||
class InteractiveObject {
|
||||
constructor(obj, gameEngine, params) {
|
||||
@@ -35,7 +35,7 @@ class InteractiveObject {
|
||||
this.object = this.source.object;
|
||||
break;
|
||||
case 'Gltf':
|
||||
let gltf = await gameEngine.load(obj.value);
|
||||
let gltf = await gameEngine.load(obj.value, '');
|
||||
let gltfObj = gltf.scene;
|
||||
gltfObj.traverse(function (object) {
|
||||
object.frustumCulled = false;
|
||||
@@ -58,11 +58,9 @@ class InteractiveObject {
|
||||
this.source = gltf;
|
||||
break;
|
||||
case 'GenericObject':
|
||||
this.source = await gameEngine.load(`/asset/default/${obj.$go.asset.name}`);
|
||||
this.source = await gameEngine.load(obj.$go.asset.name);
|
||||
this.object = this.source.scene;
|
||||
break;
|
||||
case 'PuzzleGame1':
|
||||
case 'PuzzleGame2':
|
||||
case 'PuzzleGame3':
|
||||
case 'PuzzleGame4':
|
||||
case 'PuzzleGame5':
|
||||
@@ -72,13 +70,14 @@ class InteractiveObject {
|
||||
this.object.game = game;
|
||||
break;
|
||||
case 'VideoPlayer':
|
||||
let vp = new VideoPlayer(gameEngine, `/asset/default/${obj.$go.asset.name}`);
|
||||
let vp = new VideoPlayer(gameEngine, gameEngine.assetPath + obj.$go.asset.name);
|
||||
this.source = await vp.ready;
|
||||
this.object = vp.object;
|
||||
break;
|
||||
case 'PuzzleGame1':
|
||||
case 'PuzzleGame2':
|
||||
case 'MazeQuizGame':
|
||||
this.source = new MazeQuizGame(gameEngine, obj);
|
||||
await this.source.load();
|
||||
this.source = await new games[obj.type](gameEngine, obj);
|
||||
this.object = this.source.object;
|
||||
break;
|
||||
}
|
||||
@@ -91,9 +90,11 @@ class InteractiveObject {
|
||||
const InteractiveObjectTypes = [
|
||||
{
|
||||
id: 'PuzzleGame1', name: 'Puzzle Game 1'
|
||||
}, {
|
||||
},{
|
||||
id: 'PuzzleGame2', name: 'Puzzle Game 2'
|
||||
},{
|
||||
id: 'MazeQuizGame', name: 'Maze Quiz Game'
|
||||
}, {
|
||||
},{
|
||||
id: 'VideoPlayer', name: 'Video Player'
|
||||
}
|
||||
];
|
||||
|
||||
@@ -144,7 +144,7 @@ class MazeObject {
|
||||
};
|
||||
|
||||
this.load = async function(){
|
||||
let mazeAsset = await engine.load('/static/meshes/quiz.gltf');
|
||||
let mazeAsset = await engine.load('/static/meshes/quiz.gltf', '');
|
||||
['tunnel', 'wall', 'door', 'floor'].forEach(e => {
|
||||
o[e] = mazeAsset.scene.getObjectByName(e);
|
||||
//o[e].frustumCulled = false;
|
||||
|
||||
@@ -18,6 +18,7 @@ const tl = 4;
|
||||
|
||||
class MazeQuizGame {
|
||||
constructor(engine, data) {
|
||||
return new Promise(async (resolve, reject)=>{
|
||||
let questions = data.shuffle ? Utils.shuffleArray(data.questions) : data.questions;
|
||||
let def = this.generate(questions);
|
||||
this.mazeObject = new MazeObject(engine, def)
|
||||
@@ -51,12 +52,10 @@ class MazeQuizGame {
|
||||
}
|
||||
//console.log(e, ud, engine.hero?.animationsMap);
|
||||
})
|
||||
}
|
||||
|
||||
async load(){
|
||||
await this.mazeObject.load();
|
||||
this.object = this.mazeObject.object;
|
||||
return this;
|
||||
resolve(this)
|
||||
})
|
||||
}
|
||||
|
||||
generate(questions, qid = 0, len){
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { BoxGeometry, Mesh, MeshBasicMaterial, Group } from 'three';
|
||||
import { TextureLoader } from 'three/src/loaders/TextureLoader';
|
||||
import { MotionEngine } from '../../lib/MotionEngine';
|
||||
|
||||
class PuzzleGame1 {
|
||||
constructor(context, image, w, h) {
|
||||
constructor(engine, data) {
|
||||
return new Promise(async (resolve, reject)=>{
|
||||
let w = data.w, h = data.h, wh = w*h;
|
||||
this.object = new Group();
|
||||
const aq = new MotionEngine();
|
||||
const pr = [[0, -1], [0, 1], [1, 0], [-1, 0], [0, 0], [0, 2]];
|
||||
@@ -12,8 +13,8 @@ class PuzzleGame1 {
|
||||
let bm = new BoxGeometry(1, 1, 1);
|
||||
let uv = bm.getAttribute('uv');
|
||||
|
||||
for (let i = 0; i < 6; i++) {
|
||||
let s = [(i % w) / w, (i % h) / h];
|
||||
for (let i = 0; i < wh; i++) {
|
||||
let s = [(i % w) / w, Math.trunc(i / w) / h];
|
||||
//top left
|
||||
uv.array[8 * i] = s[0];
|
||||
uv.array[8 * i + 1] = s[1] + 1 / h;
|
||||
@@ -29,14 +30,14 @@ class PuzzleGame1 {
|
||||
}
|
||||
|
||||
let material = new MeshBasicMaterial({
|
||||
map: new TextureLoader().load(image)
|
||||
map: await engine.loadTexture(data.$go.asset.name)
|
||||
});
|
||||
//material.map.encoding = sRGBEncoding;
|
||||
|
||||
for (let i = 0; i < 6; i++) {
|
||||
for (let i = 0; i < wh; i++) {
|
||||
let b = bm.clone();
|
||||
let mesh = new Mesh(b, material);
|
||||
mesh.position.set((i % w) * d, (i % h) * d, 0);
|
||||
mesh.position.set((i % w) * d, (Math.trunc(i / w)) * d, 0);
|
||||
let ri;
|
||||
do {
|
||||
ri = Math.floor(Math.random() * 6);
|
||||
@@ -72,7 +73,7 @@ class PuzzleGame1 {
|
||||
};
|
||||
|
||||
this.object.children.forEach(c => {
|
||||
context.clickable.add(c, clickFn);
|
||||
engine.clickable.add(c, clickFn);
|
||||
});
|
||||
|
||||
this.update = () => {
|
||||
@@ -82,14 +83,17 @@ class PuzzleGame1 {
|
||||
this.object.children.forEach((c, i) => {
|
||||
aq.add({
|
||||
o: c,
|
||||
a: { position: { x: i % w, y: i % h } },
|
||||
a: { position: { x: i % w, y: Math.trunc(i/w)} },
|
||||
t: 1,
|
||||
f: i == 0 && this.onfinish
|
||||
});
|
||||
});
|
||||
//context.dashboard.addPoints(10);
|
||||
//engine.dashboard.addPoints(10);
|
||||
}
|
||||
};
|
||||
|
||||
resolve(this);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,40 @@
|
||||
<template>
|
||||
<v-card v-if="modelValue.go">
|
||||
<v-card-item>
|
||||
<v-number-input density="compact" label="Width" v-model="modelValue.w"></v-number-input>
|
||||
<v-number-input density="compact" label="Height" v-model="modelValue.h"></v-number-input>
|
||||
<v-img :src="`/asset/thumb/${modelValue.go}.webp`" />
|
||||
<div class="text-caption text-center">{{ modelValue.title }}</div>
|
||||
</v-card-item>
|
||||
</v-card>
|
||||
<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>Choose image object</v-btn>
|
||||
</template>
|
||||
</asset-selector>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
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
|
||||
this.modelValue.w = 2;
|
||||
this.modelValue.h = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,10 +1,11 @@
|
||||
import { BoxGeometry, Mesh, MeshBasicMaterial, Group } from 'three';
|
||||
import { TextureLoader } from 'three/src/loaders/TextureLoader';
|
||||
import { MotionEngine } from '../../lib/MotionEngine';
|
||||
|
||||
class PuzzleGame2 {
|
||||
constructor(context, image, w, h) {
|
||||
const texture = new TextureLoader().load(image);
|
||||
constructor(engine, data) {
|
||||
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);
|
||||
//texture.encoding = sRGBEncoding;
|
||||
const material = new MeshBasicMaterial({
|
||||
map: texture
|
||||
@@ -46,11 +47,11 @@ class PuzzleGame2 {
|
||||
if (yl < h - 1) m.push(p.indexOf(pl + w));
|
||||
return m;
|
||||
}
|
||||
for (let i = 0; i < w * h; i++) {
|
||||
for (let i = 0; i < wh; i++) {
|
||||
p[i] = i;
|
||||
}
|
||||
|
||||
for (let iter = 0; iter < 73 * w * h; iter++) {
|
||||
for (let iter = 0; iter < 73 * wh; iter++) {
|
||||
let m = getMoves();
|
||||
xch(m[Math.floor(Math.random() * m.length)], lidx);
|
||||
}
|
||||
@@ -64,7 +65,7 @@ class PuzzleGame2 {
|
||||
});
|
||||
};
|
||||
|
||||
for (let i = 0; i < w * h; i++) {
|
||||
for (let i = 0; i < wh; i++) {
|
||||
let x = i % w, xp = x / w;
|
||||
let y = ~~(i / h), yp = y / h;
|
||||
let bg = new BoxGeometry(1, 1, 1);
|
||||
@@ -120,7 +121,7 @@ class PuzzleGame2 {
|
||||
};
|
||||
|
||||
this.object.children.forEach(c => {
|
||||
context.clickable.add(c, clickFn);
|
||||
engine.clickable.add(c, clickFn);
|
||||
});
|
||||
|
||||
this.update = () => {
|
||||
@@ -136,10 +137,11 @@ class PuzzleGame2 {
|
||||
f: i == 0 && this.onfinish
|
||||
});
|
||||
});
|
||||
//context.dashboard.addPoints(10);
|
||||
//engine.dashboard.addPoints(10);
|
||||
}
|
||||
};
|
||||
|
||||
resolve(this)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<v-card v-if="modelValue.go">
|
||||
<v-card-item>
|
||||
<v-number-input density="compact" label="Width" v-model="modelValue.w"></v-number-input>
|
||||
<v-number-input density="compact" label="Height" v-model="modelValue.h"></v-number-input>
|
||||
<v-img :src="`/asset/thumb/${modelValue.go}.webp`" />
|
||||
<div class="text-caption text-center">{{ modelValue.title }}</div>
|
||||
</v-card-item>
|
||||
</v-card>
|
||||
<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>Choose image object</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
|
||||
this.modelValue.w = 3;
|
||||
this.modelValue.h = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -34,12 +34,13 @@ import Utils from '@/lib/Utils';
|
||||
|
||||
import VideoPlayer from '../InteractiveObjects/VideoPlayer.vue';
|
||||
import PuzzleGame1 from '../InteractiveObjects/PuzzleGame1.vue';
|
||||
import PuzzleGame2 from '../InteractiveObjects/PuzzleGame2.vue';
|
||||
import MazeQuizGame from '../InteractiveObjects/MazeQuizGame/MazeQuizGame.vue';
|
||||
import GenericObject from '../InteractiveObjects/GenericObject.vue';
|
||||
|
||||
export default {
|
||||
emits:['target', 'preview'],
|
||||
components: { SvgIcon, VideoPlayer, PuzzleGame1, MazeQuizGame, GenericObject },
|
||||
components: { SvgIcon, VideoPlayer, PuzzleGame1, PuzzleGame2, MazeQuizGame, GenericObject },
|
||||
data(){
|
||||
return {
|
||||
active: false
|
||||
|
||||
+11
-8
@@ -16,6 +16,8 @@ import { Clickable } from './Clickable.js';
|
||||
import { DashBoard } from './Dashboard.js';
|
||||
import { MotionEngine } from './MotionEngine.js';
|
||||
|
||||
const assetPath = '/asset/default/';
|
||||
|
||||
class GameEngine extends THREE.EventDispatcher{
|
||||
async init(domNode, opts = {}) {
|
||||
this.w = domNode.clientWidth || 1200, this.h = domNode.clientHeight || 800;
|
||||
@@ -101,6 +103,7 @@ class GameEngine extends THREE.EventDispatcher{
|
||||
this.dashboard = dashboard;
|
||||
|
||||
this.motionQueue = new MotionEngine();
|
||||
this.assetPath = assetPath;
|
||||
|
||||
this.activeObjects = new THREE.Group();
|
||||
scene.add(this.activeObjects);
|
||||
@@ -158,7 +161,7 @@ class GameEngine extends THREE.EventDispatcher{
|
||||
|
||||
domNode.appendChild(renderer.domElement);
|
||||
|
||||
let texture = await this.loadTexture('/static/textures/bck.webp');
|
||||
let texture = await this.loadTexture('/static/textures/bck.webp', '');
|
||||
// let bck = await this.loadTexture('/static/textures/bck.webp');
|
||||
// bck.premultiplyAlpha = true;
|
||||
texture.mapping = THREE.EquirectangularReflectionMapping;
|
||||
@@ -383,12 +386,12 @@ class GameEngine extends THREE.EventDispatcher{
|
||||
|
||||
$ = THREE;
|
||||
|
||||
async load(url, progress) {
|
||||
async load(url, path = assetPath, progress) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.loader.load(url, o => {
|
||||
this.loader.load(`${path}${url}`, o => {
|
||||
o.scene.traverse(object => {
|
||||
if (object.name == 'environment' || object.material){
|
||||
console.log('env recomputing')
|
||||
//console.log('env recomputing')
|
||||
object.material.shading = THREE.SmoothShading;
|
||||
object.geometry.computeVertexNormals(true);
|
||||
//object.material.metalness = 0;
|
||||
@@ -408,9 +411,9 @@ class GameEngine extends THREE.EventDispatcher{
|
||||
})
|
||||
}
|
||||
|
||||
async loadTexture(url, progress) {
|
||||
async loadTexture(url, path = assetPath, progress) {
|
||||
return new Promise((resolve, reject) => {
|
||||
new THREE.TextureLoader().load(url, texture => {
|
||||
new THREE.TextureLoader().load(`${path}${url}`, texture => {
|
||||
//texture.encoding = THREE.sRGBEncoding;
|
||||
texture.colorSpace = THREE.SRGBColorSpace;
|
||||
resolve(texture)
|
||||
@@ -418,8 +421,8 @@ class GameEngine extends THREE.EventDispatcher{
|
||||
})
|
||||
}
|
||||
|
||||
async loadPanorama(url) {
|
||||
let t = await this.loadTexture(url);
|
||||
async loadPanorama(url, path = assetPath) {
|
||||
let t = await this.loadTexture(url, path);
|
||||
t.mapping = THREE.EquirectangularReflectionMapping;
|
||||
this.scene.background = t;
|
||||
this.scene.environment = t;
|
||||
|
||||
@@ -102,14 +102,8 @@ export default {
|
||||
})
|
||||
|
||||
for (let i of scene.data.items || []) {
|
||||
if (i.data.io){
|
||||
if (i.data.io.go){
|
||||
promises.push(this.$api.gameObject.load(i.data.io.go).then(r=>i.data.io.$go = r.data));
|
||||
}
|
||||
}else{
|
||||
promises.push(this.$api.gameObject.load(i.data.go).then(r=>i.data.$go = r.data));
|
||||
}
|
||||
}
|
||||
await Promise.all(promises);
|
||||
},
|
||||
|
||||
@@ -128,10 +122,10 @@ export default {
|
||||
target.objects = target.objects || {};
|
||||
let l = target.objects;
|
||||
if (this.scene.data.$environment){
|
||||
await gameEngine.loadPanorama(`/asset/default/${this.scene.data.$environment.asset.name}`);
|
||||
await gameEngine.loadPanorama(this.scene.data.$environment.asset.name);
|
||||
}
|
||||
if (this.scene.data.$scene){
|
||||
let env = await gameEngine.load(`/asset/default/${this.scene.data.$scene.asset.name}`);
|
||||
let env = await gameEngine.load(this.scene.data.$scene.asset.name);
|
||||
//console.log('ENV', env)
|
||||
this.setObjectAttributes(l, this.scene.data, env.scene, env, 100);
|
||||
gameEngine.activeObjects.add(env.scene);
|
||||
@@ -193,7 +187,7 @@ export default {
|
||||
['position', 'scale', 'rotation'].forEach(p=>{
|
||||
object[p].copy(l[data.id][p])
|
||||
})
|
||||
}else{
|
||||
}else if (!data.type || data.type == 'GenericObject'){
|
||||
gameEngine.autoScale(object, autoScaleFactor);
|
||||
}
|
||||
l[data.id] = l[data.id] || {};
|
||||
|
||||
@@ -22,7 +22,7 @@ export default {
|
||||
}, {
|
||||
value: 'object2d',
|
||||
icon: 'file-image-outline',
|
||||
type: 'Descriptive',
|
||||
type: 'Texture',
|
||||
color: 'cyan-darken-3'
|
||||
}, {
|
||||
value: 'player3d',
|
||||
|
||||
Reference in New Issue
Block a user