classic puzzle v1

This commit is contained in:
2025-11-14 18:41:57 +02:00
parent 8eea84b697
commit 3d86e2574a
10 changed files with 2754 additions and 5 deletions
@@ -0,0 +1,75 @@
import { Color, Group, EventDispatcher, DoubleSide } from "three"
import { centerOrigin } from "@/lib/MeshUtils";
class ClassicPuzzle extends EventDispatcher {
emits = ['finish']
constructor(engine, data, gltfName, objPrefix='Plane'){
super();
const container = new Group();
const that = this;
return new Promise(async (resolve, reject)=>{
let gltf = await engine.load('puzzle-5x4/puzzle-5x4.gltf', '/static/meshes/');
let dragZone = gltf.scene.getObjectByName('DragZone');
dragZone.material.side = DoubleSide;
let eventsFn= {
start(){},
drag(){},
end(e){
if (Math.abs(e.o.position.x)<.1 && Math.abs(e.o.position.y)<.1){
e.o.position.set(0,0,0);
engine.draggable.remove(e.o);
e.o.material = doneMaterial;
done++;
if (done == pCount){
doneMaterial.emissiveIntensity = .5;
engine.motionQueue.add({
o: doneMaterial,
t:1.5,
d:1,
a:{ emissiveIntensity:0 },
f:()=>{
that.dispatchEvent({type:'finish'})
}
});
}
}
}
}
let pCount = 0;
dragZone.visible = false;
gltf.scene.children.forEach((o, i)=>{
if (o.name.startsWith(objPrefix)){
let pp = o.clone();
container.add(pp);
pp.position.set(2*Math.random()-1, 2*Math.random() - 1, 0.01*(i+1));
engine.draggable.add(pp, dragZone, eventsFn);
pCount++;
}
});
let defaultMaterial = container.children[0].material;
defaultMaterial.emissiveIntensity=.05
let doneMaterial = defaultMaterial.clone();
doneMaterial.emissive = new Color(10,114,10);
defaultMaterial.emissive = new Color(114,10,10);
engine.motionQueue.add(
{
o: defaultMaterial,
r: true,
t:1.5,
d:1,
rd:true,
a:{emissiveIntensity:function(k){return .05*Math.sin(k*3.14);}}
});
let done0 = container.children[Math.floor(Math.random() * container.children.length)];
let done = 1;
done0.material = doneMaterial;
done0.position.set(0,0,0);
engine.draggable.remove(done0)
container.add(dragZone);
this.object = centerOrigin(container);
resolve(this);
})
}
}
export { ClassicPuzzle }