import { BoxGeometry, Mesh, MeshStandardMaterial, Group } from 'three'; import { centerOrigin } from '@/lib/MeshUtils'; import { EventManager } from '@/lib/EventManager'; class PuzzleGame1 extends EventManager { emits = ['finish', 'interaction'] constructor(engine, data) { super(); return new Promise(async (resolve, reject)=>{ let w = data.w, h = data.h, wh = w*h; let container = new Group(); const aq = engine.motionQueue; const pr = [[0, 2], [0, -1], [0, 1], [1, 0], [-1, 0], [0, 0]]; let d = 1.2; let bm = new BoxGeometry(1, 1, 1); let material = new MeshStandardMaterial({ map: await engine.loadTexture(data.$go.asset.name), // roughness:1, metalness:0, // normalMap: await engine.loadTexture('NormalMap.png', '/static/textures/'), }); //material.map.encoding = sRGBEncoding; for (let i = 0; i < wh; i++) { let b = bm.clone(); let uv = b.getAttribute('uv'); //0-8->R, 8-16->L, 16-24->Top, 24-32->Bottom, 32-40->Front, 40-48->Back let x = i % w, y = Math.trunc(i / w); let idxs = [(i+1) % wh, (i+2)%wh, (i+3)%wh, (i+4)%wh, i, y*w + w - x -1] for (let i = 0; i < 6; i++) { let idx = idxs[i]; let x = idx % w, y = Math.trunc(idx / w) let s = [x / w, y / 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 mesh = new Mesh(b, material); mesh.position.set((i % w) * d, (Math.trunc(i / w)) * d, 0); let ri = Math.floor(Math.random() * 5); mesh.rotation.set(pr[ri][0] * Math.PI / 2, pr[ri][1] * Math.PI / 2, 0); mesh._ri = ri; if (idxs[4] == idxs[5]){ mesh._dd = true; } container.add(mesh); } container.children[0].onBeforeRender = () => { this.update(); }; var check = () => { let i = 0; container.children.forEach(o=>{ if (o._ri == 5 || o._dd && o._ri == 0) i++; }) return i == wh; }; let clickFn = (i) => { this.dispatchEvent({type:'interaction'}); 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, s: 'PG2' }); } }; container.children.forEach(c => { engine.clickable.add(c, clickFn); }); this.update = () => { if (aq.isIdle('PG2') && !this.done && check()) { this.done = true; container.children.forEach((c, i) => { aq.add({ o: c, a: { position: { x: i % w, y: Math.trunc(i/w)} }, t: 1, f: i == 0 ? ()=>{ this.dispatchEvent({type:'finish'}) } : undefined, s: 'PG2' }); }); //engine.dashboard.addPoints(10); } }; this.object = centerOrigin(container); resolve(this); }) } } export { PuzzleGame1 }