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,47 +18,46 @@ const tl = 4;
|
||||
|
||||
class MazeQuizGame {
|
||||
constructor(engine, data) {
|
||||
let questions = data.shuffle ? Utils.shuffleArray(data.questions) : data.questions;
|
||||
let def = this.generate(questions);
|
||||
this.mazeObject = new MazeObject(engine, def)
|
||||
engine.addEventListener('collision', async e=>{
|
||||
let ud1 = engine.physics.world.getCollider(e.handle1)?.parent()?.userData,
|
||||
ud2 = engine.physics.world.getCollider(e.handle2)?.parent()?.userData;
|
||||
let ud = {...ud1, ...ud2}
|
||||
if (ud?.finish){
|
||||
if (e.started){
|
||||
engine.dashboard.updateProgress(1)
|
||||
engine.hero.animationsMap._idle = engine.hero.animationsMap.idle
|
||||
if ( engine.hero.animationsMap?.win){
|
||||
engine.hero.animationsMap.idle = engine.hero.animationsMap.win
|
||||
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)
|
||||
engine.addEventListener('collision', async e=>{
|
||||
let ud1 = engine.physics.world.getCollider(e.handle1)?.parent()?.userData,
|
||||
ud2 = engine.physics.world.getCollider(e.handle2)?.parent()?.userData;
|
||||
let ud = {...ud1, ...ud2}
|
||||
if (ud?.finish){
|
||||
if (e.started){
|
||||
engine.dashboard.updateProgress(1)
|
||||
engine.hero.animationsMap._idle = engine.hero.animationsMap.idle
|
||||
if ( engine.hero.animationsMap?.win){
|
||||
engine.hero.animationsMap.idle = engine.hero.animationsMap.win
|
||||
}
|
||||
await Utils.wait(1000);
|
||||
engine.hero.characterControls.cameraDelta = Math.PI;
|
||||
engine.hero.characterControls.direction += Math.PI;
|
||||
//engine.hero.model.rotation.y += Math.PI;
|
||||
await Utils.wait(10000);
|
||||
this.onfinish?.()
|
||||
}else{
|
||||
engine.hero.animationsMap.idle = engine.hero.animationsMap._idle
|
||||
engine.hero.characterControls.cameraDelta = 0
|
||||
}
|
||||
await Utils.wait(1000);
|
||||
engine.hero.characterControls.cameraDelta = Math.PI;
|
||||
engine.hero.characterControls.direction += Math.PI;
|
||||
//engine.hero.model.rotation.y += Math.PI;
|
||||
await Utils.wait(10000);
|
||||
this.onfinish?.()
|
||||
}else{
|
||||
engine.hero.animationsMap.idle = engine.hero.animationsMap._idle
|
||||
engine.hero.characterControls.cameraDelta = 0
|
||||
}
|
||||
}
|
||||
if (ud.qid !== undefined && e.started){
|
||||
engine.dashboard.update({
|
||||
hint: ud.question.q
|
||||
})
|
||||
engine.dashboard.updateProgress(ud.qid / questions.length)
|
||||
}
|
||||
//console.log(e, ud, engine.hero?.animationsMap);
|
||||
if (ud.qid !== undefined && e.started){
|
||||
engine.dashboard.update({
|
||||
hint: ud.question.q
|
||||
})
|
||||
engine.dashboard.updateProgress(ud.qid / questions.length)
|
||||
}
|
||||
//console.log(e, ud, engine.hero?.animationsMap);
|
||||
})
|
||||
await this.mazeObject.load();
|
||||
this.object = this.mazeObject.object;
|
||||
resolve(this)
|
||||
})
|
||||
}
|
||||
|
||||
async load(){
|
||||
await this.mazeObject.load();
|
||||
this.object = this.mazeObject.object;
|
||||
return this;
|
||||
}
|
||||
|
||||
generate(questions, qid = 0, len){
|
||||
let question = questions[qid]
|
||||
if (!question) return {
|
||||
|
||||
@@ -1,95 +1,99 @@
|
||||
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) {
|
||||
this.object = new Group();
|
||||
const aq = new MotionEngine();
|
||||
const pr = [[0, -1], [0, 1], [1, 0], [-1, 0], [0, 0], [0, 2]];
|
||||
let d = 1.2;
|
||||
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]];
|
||||
let d = 1.2;
|
||||
|
||||
let bm = new BoxGeometry(1, 1, 1);
|
||||
let uv = bm.getAttribute('uv');
|
||||
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];
|
||||
//top left
|
||||
uv.array[8 * i] = s[0];
|
||||
uv.array[8 * i + 1] = s[1] + 1 / h;
|
||||
//top right
|
||||
uv.array[8 * i + 2] = s[0] + 1 / w;
|
||||
uv.array[8 * i + 3] = s[1] + 1 / h;
|
||||
//bottom left
|
||||
uv.array[8 * i + 4] = s[0];
|
||||
uv.array[8 * i + 5] = s[1];
|
||||
//bottom right
|
||||
uv.array[8 * i + 6] = s[0] + 1 / w;
|
||||
uv.array[8 * i + 7] = s[1];
|
||||
}
|
||||
|
||||
let material = new MeshBasicMaterial({
|
||||
map: new TextureLoader().load(image)
|
||||
});
|
||||
//material.map.encoding = sRGBEncoding;
|
||||
|
||||
for (let i = 0; i < 6; i++) {
|
||||
let b = bm.clone();
|
||||
let mesh = new Mesh(b, material);
|
||||
mesh.position.set((i % w) * d, (i % h) * d, 0);
|
||||
let ri;
|
||||
do {
|
||||
ri = Math.floor(Math.random() * 6);
|
||||
} while (ri == this.object.children.length);
|
||||
mesh.rotation.set(pr[ri][0] * Math.PI / 2, pr[ri][1] * Math.PI / 2, 0);
|
||||
mesh._ri = ri;
|
||||
this.object.add(mesh);
|
||||
}
|
||||
|
||||
this.object.children[0].onBeforeRender = () => {
|
||||
this.update();
|
||||
};
|
||||
|
||||
var check = () => {
|
||||
if (!this.object.children.length) return false;
|
||||
let i = 0;
|
||||
for (let c of this.object.children) {
|
||||
if (Math.abs(c.rotation.x - pr[i][0] * Math.PI / 2) > 0.0001 || Math.abs(c.rotation.y - pr[i][1] * Math.PI / 2) > 0.0001) return false;
|
||||
i++;
|
||||
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;
|
||||
//top right
|
||||
uv.array[8 * i + 2] = s[0] + 1 / w;
|
||||
uv.array[8 * i + 3] = s[1] + 1 / h;
|
||||
//bottom left
|
||||
uv.array[8 * i + 4] = s[0];
|
||||
uv.array[8 * i + 5] = s[1];
|
||||
//bottom right
|
||||
uv.array[8 * i + 6] = s[0] + 1 / w;
|
||||
uv.array[8 * i + 7] = s[1];
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
let clickFn = (i) => {
|
||||
if (!this.done && !aq.isActive(i.object)) {
|
||||
i.object._ri = (i.object._ri + 1) % 6;
|
||||
aq.add({
|
||||
o: i.object,
|
||||
a: { rotation: { x: pr[i.object._ri][0] * Math.PI / 2, y: pr[i.object._ri][1] * Math.PI / 2 } },
|
||||
t: .5
|
||||
});
|
||||
let material = new MeshBasicMaterial({
|
||||
map: await engine.loadTexture(data.$go.asset.name)
|
||||
});
|
||||
//material.map.encoding = sRGBEncoding;
|
||||
|
||||
for (let i = 0; i < wh; i++) {
|
||||
let b = bm.clone();
|
||||
let mesh = new Mesh(b, material);
|
||||
mesh.position.set((i % w) * d, (Math.trunc(i / w)) * d, 0);
|
||||
let ri;
|
||||
do {
|
||||
ri = Math.floor(Math.random() * 6);
|
||||
} while (ri == this.object.children.length);
|
||||
mesh.rotation.set(pr[ri][0] * Math.PI / 2, pr[ri][1] * Math.PI / 2, 0);
|
||||
mesh._ri = ri;
|
||||
this.object.add(mesh);
|
||||
}
|
||||
};
|
||||
|
||||
this.object.children.forEach(c => {
|
||||
context.clickable.add(c, clickFn);
|
||||
});
|
||||
this.object.children[0].onBeforeRender = () => {
|
||||
this.update();
|
||||
};
|
||||
|
||||
this.update = () => {
|
||||
aq.update();
|
||||
if (aq.isIdle() && !this.done && check()) {
|
||||
this.done = true;
|
||||
this.object.children.forEach((c, i) => {
|
||||
var check = () => {
|
||||
if (!this.object.children.length) return false;
|
||||
let i = 0;
|
||||
for (let c of this.object.children) {
|
||||
if (Math.abs(c.rotation.x - pr[i][0] * Math.PI / 2) > 0.0001 || Math.abs(c.rotation.y - pr[i][1] * Math.PI / 2) > 0.0001) return false;
|
||||
i++;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
let clickFn = (i) => {
|
||||
if (!this.done && !aq.isActive(i.object)) {
|
||||
i.object._ri = (i.object._ri + 1) % 6;
|
||||
aq.add({
|
||||
o: c,
|
||||
a: { position: { x: i % w, y: i % h } },
|
||||
t: 1,
|
||||
f: i == 0 && this.onfinish
|
||||
o: i.object,
|
||||
a: { rotation: { x: pr[i.object._ri][0] * Math.PI / 2, y: pr[i.object._ri][1] * Math.PI / 2 } },
|
||||
t: .5
|
||||
});
|
||||
});
|
||||
//context.dashboard.addPoints(10);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
this.object.children.forEach(c => {
|
||||
engine.clickable.add(c, clickFn);
|
||||
});
|
||||
|
||||
this.update = () => {
|
||||
aq.update();
|
||||
if (aq.isIdle() && !this.done && check()) {
|
||||
this.done = true;
|
||||
this.object.children.forEach((c, i) => {
|
||||
aq.add({
|
||||
o: c,
|
||||
a: { position: { x: i % w, y: Math.trunc(i/w)} },
|
||||
t: 1,
|
||||
f: i == 0 && this.onfinish
|
||||
});
|
||||
});
|
||||
//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 {
|
||||
|
||||
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,145 +1,147 @@
|
||||
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);
|
||||
//texture.encoding = sRGBEncoding;
|
||||
const material = new MeshBasicMaterial({
|
||||
map: texture
|
||||
});
|
||||
const aq = new MotionEngine();
|
||||
const m2 = new MeshBasicMaterial({
|
||||
map: texture,
|
||||
transparent: true,
|
||||
opacity: 0.37
|
||||
});
|
||||
let last, lidx = w - 1;
|
||||
|
||||
this.object = new Group();
|
||||
let d = 1.2, p = [];
|
||||
|
||||
function check() {
|
||||
if (p.length) {
|
||||
for (let i = 0; i < p.length; i++) {
|
||||
if (p[i] != i) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function xch(x, y) {
|
||||
let temp = p[x];
|
||||
p[x] = p[y];
|
||||
p[y] = temp;
|
||||
}
|
||||
|
||||
this.shuffle = function () {
|
||||
function getMoves() {
|
||||
let m = [], pl = p[lidx];
|
||||
let xl = pl % w, yl = ~~(pl / h);
|
||||
if (xl > 0) m.push(p.indexOf(pl - 1));
|
||||
if (xl < w - 1) m.push(p.indexOf(pl + 1));
|
||||
if (yl > 0) m.push(p.indexOf(pl - w));
|
||||
if (yl < h - 1) m.push(p.indexOf(pl + w));
|
||||
return m;
|
||||
}
|
||||
for (let i = 0; i < w * h; i++) {
|
||||
p[i] = i;
|
||||
}
|
||||
|
||||
for (let iter = 0; iter < 73 * w * h; iter++) {
|
||||
let m = getMoves();
|
||||
xch(m[Math.floor(Math.random() * m.length)], lidx);
|
||||
}
|
||||
// while (p.length<9){
|
||||
// let n = Math.floor(Math.random()*9);
|
||||
// if (p.indexOf(n) == -1) p.push(n);
|
||||
// }
|
||||
p.forEach((e, i) => {
|
||||
let x = e % w, y = ~~(e / h);
|
||||
this.object.children[i].position.set(x * d, y * d, 0);
|
||||
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
|
||||
});
|
||||
};
|
||||
const aq = new MotionEngine();
|
||||
const m2 = new MeshBasicMaterial({
|
||||
map: texture,
|
||||
transparent: true,
|
||||
opacity: 0.37
|
||||
});
|
||||
let last, lidx = w - 1;
|
||||
|
||||
for (let i = 0; i < w * h; i++) {
|
||||
let x = i % w, xp = x / w;
|
||||
let y = ~~(i / h), yp = y / h;
|
||||
let bg = new BoxGeometry(1, 1, 1);
|
||||
let uv = bg.getAttribute('uv');
|
||||
for (let k = 0; k < 6; k++) {
|
||||
//top left
|
||||
uv.array[8 * k] = xp;
|
||||
uv.array[8 * k + 1] = yp + 1 / h;
|
||||
//top right
|
||||
uv.array[8 * k + 2] = xp + 1 / w;
|
||||
uv.array[8 * k + 3] = yp + 1 / h;
|
||||
//bottom left
|
||||
uv.array[8 * k + 4] = xp;
|
||||
uv.array[8 * k + 5] = yp;
|
||||
//bottom right
|
||||
uv.array[8 * k + 6] = xp + 1 / w;
|
||||
uv.array[8 * k + 7] = yp;
|
||||
}
|
||||
let mesh = new Mesh(bg, i != lidx ? material : m2);
|
||||
mesh.position.set(x * d, y * d, 0);
|
||||
this.object.add(mesh);
|
||||
}
|
||||
last = this.object.children[lidx];
|
||||
this.object = new Group();
|
||||
let d = 1.2, p = [];
|
||||
|
||||
this.object.children[0].onBeforeRender = () => {
|
||||
this.update();
|
||||
};
|
||||
|
||||
this.shuffle();
|
||||
|
||||
let clickFn = (i) => {
|
||||
if (!this.done && !aq.isActive(i.object)) {
|
||||
let idx = this.object.children.indexOf(i.object);
|
||||
if (idx == lidx) return; //we ignore the empty cell
|
||||
let xc = p[idx] % w, yc = ~~(p[idx] / h);
|
||||
let xl = p[lidx] % w, yl = ~~(p[lidx] / h);
|
||||
if (Math.abs(xc - xl) + Math.abs(yc - yl) == 1) {
|
||||
aq.add({
|
||||
o: i.object,
|
||||
a: { position: { x: (xl - xc) * d, y: (yl - yc) * d } },
|
||||
t: .3,
|
||||
m: 'offset'
|
||||
});
|
||||
aq.add({
|
||||
o: last,
|
||||
a: { position: { x: (xc - xl) * d, y: (yc - yl) * d } },
|
||||
t: .3,
|
||||
m: 'offset'
|
||||
});
|
||||
xch(idx, lidx);
|
||||
function check() {
|
||||
if (p.length) {
|
||||
for (let i = 0; i < p.length; i++) {
|
||||
if (p[i] != i) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
this.object.children.forEach(c => {
|
||||
context.clickable.add(c, clickFn);
|
||||
});
|
||||
function xch(x, y) {
|
||||
let temp = p[x];
|
||||
p[x] = p[y];
|
||||
p[y] = temp;
|
||||
}
|
||||
|
||||
this.update = () => {
|
||||
aq.update();
|
||||
if (aq.isIdle() && !this.done && check()) {
|
||||
this.done = true;
|
||||
this.object.children.forEach((c, i) => {
|
||||
last.material = material;
|
||||
aq.add({
|
||||
o: c,
|
||||
a: { position: { x: i % w, y: ~~(i / h) } },
|
||||
t: 1,
|
||||
f: i == 0 && this.onfinish
|
||||
});
|
||||
this.shuffle = function () {
|
||||
function getMoves() {
|
||||
let m = [], pl = p[lidx];
|
||||
let xl = pl % w, yl = ~~(pl / h);
|
||||
if (xl > 0) m.push(p.indexOf(pl - 1));
|
||||
if (xl < w - 1) m.push(p.indexOf(pl + 1));
|
||||
if (yl > 0) m.push(p.indexOf(pl - w));
|
||||
if (yl < h - 1) m.push(p.indexOf(pl + w));
|
||||
return m;
|
||||
}
|
||||
for (let i = 0; i < wh; i++) {
|
||||
p[i] = i;
|
||||
}
|
||||
|
||||
for (let iter = 0; iter < 73 * wh; iter++) {
|
||||
let m = getMoves();
|
||||
xch(m[Math.floor(Math.random() * m.length)], lidx);
|
||||
}
|
||||
// while (p.length<9){
|
||||
// let n = Math.floor(Math.random()*9);
|
||||
// if (p.indexOf(n) == -1) p.push(n);
|
||||
// }
|
||||
p.forEach((e, i) => {
|
||||
let x = e % w, y = ~~(e / h);
|
||||
this.object.children[i].position.set(x * d, y * d, 0);
|
||||
});
|
||||
//context.dashboard.addPoints(10);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
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);
|
||||
let uv = bg.getAttribute('uv');
|
||||
for (let k = 0; k < 6; k++) {
|
||||
//top left
|
||||
uv.array[8 * k] = xp;
|
||||
uv.array[8 * k + 1] = yp + 1 / h;
|
||||
//top right
|
||||
uv.array[8 * k + 2] = xp + 1 / w;
|
||||
uv.array[8 * k + 3] = yp + 1 / h;
|
||||
//bottom left
|
||||
uv.array[8 * k + 4] = xp;
|
||||
uv.array[8 * k + 5] = yp;
|
||||
//bottom right
|
||||
uv.array[8 * k + 6] = xp + 1 / w;
|
||||
uv.array[8 * k + 7] = yp;
|
||||
}
|
||||
let mesh = new Mesh(bg, i != lidx ? material : m2);
|
||||
mesh.position.set(x * d, y * d, 0);
|
||||
this.object.add(mesh);
|
||||
}
|
||||
last = this.object.children[lidx];
|
||||
|
||||
this.object.children[0].onBeforeRender = () => {
|
||||
this.update();
|
||||
};
|
||||
|
||||
this.shuffle();
|
||||
|
||||
let clickFn = (i) => {
|
||||
if (!this.done && !aq.isActive(i.object)) {
|
||||
let idx = this.object.children.indexOf(i.object);
|
||||
if (idx == lidx) return; //we ignore the empty cell
|
||||
let xc = p[idx] % w, yc = ~~(p[idx] / h);
|
||||
let xl = p[lidx] % w, yl = ~~(p[lidx] / h);
|
||||
if (Math.abs(xc - xl) + Math.abs(yc - yl) == 1) {
|
||||
aq.add({
|
||||
o: i.object,
|
||||
a: { position: { x: (xl - xc) * d, y: (yl - yc) * d } },
|
||||
t: .3,
|
||||
m: 'offset'
|
||||
});
|
||||
aq.add({
|
||||
o: last,
|
||||
a: { position: { x: (xc - xl) * d, y: (yc - yl) * d } },
|
||||
t: .3,
|
||||
m: 'offset'
|
||||
});
|
||||
xch(idx, lidx);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.object.children.forEach(c => {
|
||||
engine.clickable.add(c, clickFn);
|
||||
});
|
||||
|
||||
this.update = () => {
|
||||
aq.update();
|
||||
if (aq.isIdle() && !this.done && check()) {
|
||||
this.done = true;
|
||||
this.object.children.forEach((c, i) => {
|
||||
last.material = material;
|
||||
aq.add({
|
||||
o: c,
|
||||
a: { position: { x: i % w, y: ~~(i / h) } },
|
||||
t: 1,
|
||||
f: i == 0 && this.onfinish
|
||||
});
|
||||
});
|
||||
//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
|
||||
|
||||
Reference in New Issue
Block a user