This commit is contained in:
2025-08-28 20:14:37 +03:00
parent 6d913c7d7c
commit 7eb7eb068a
9 changed files with 68 additions and 10 deletions
@@ -0,0 +1,124 @@
import { Group, RGBAFormat } from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import { MotionEngine } from '../../lib/MotionEngine';
var Game4 = function(context, gltf, w, h){
this.game = new Group();
const aq = new MotionEngine();
const pr = [];
let d = .51, c = w * h / 2, tc = w * h, m0=1, r0=.2;
let lastClicked;
function setMaterial(m, v){
if (v){
m.metalness = .5;
m.roughness = .383;
}else{
m.metalness = m0;
m.roughness = r0;
m.transparent = true;
m.format = RGBAFormat;
}
}
new GLTFLoader().load(gltf, gltf=>{
for (let i = 0; i<c; i++){
let o = gltf.scene.getObjectByName('c'+(i+1));
let ref = [];
for (let j = 0; j<2; j++){
let position;
do {
position = Math.floor(Math.random() * tc);
}while (pr[position]);
ref[j] = o.clone();
ref[j].material = o.material.clone();
setMaterial(ref[j].material, 0);
pr[position] = ref[j];
}
ref[0].$ref = ref[1];
ref[1].$ref = ref[0];
}
pr.forEach((c, i)=>{
c.position.set((i % w)*d , (~~(i / w))*d);
c.rotation.set(0, Math.PI, 0);
this.game.add(c);
context.clickable.add(c, clickFn);
})
this.game.children[0].onBeforeRender = ()=>{
this.update();
}
});
var check = ()=>{
if (!this.game.children.length) return false;
return pr.filter(c=>c.$active === false).length == tc;
}
let clickFn = (i)=>{
let clicked = i.object;
if (this.done && clicked){
aq.add({
o: clicked,
a: {rotation:{y: Math.PI}},
t: 1,
m: 'offset'
});
}
if (!clicked || clicked.$active === false || aq.isActive(clicked)) return;
setMaterial(clicked.material, 1);
let f;
if (lastClicked && lastClicked.$ref == clicked){
clicked.$active = lastClicked.$active = false;
[clicked, lastClicked].forEach(c => {
aq.add({
o: c,
a: {material:{opacity:0}},
t: 1,
d:1
});
});
lastClicked = null;
}else if(!lastClicked){
lastClicked = clicked;
}else{
f = ()=>{
setTimeout(()=>{
[clicked, lastClicked].filter(c=>c).forEach(c=>{
aq.add({
o: c,
a: {rotation:{y: Math.PI}, material:{metalness:m0, roughness:r0}},
t: 1
});
});
lastClicked = null;
}, 500);
}
}
aq.add({
o: clicked,
a: {rotation:{y: 0}},
t: .5,
f
});
}
this.update = ()=>{
aq.update();
if (!this.done && check()){
this.done = true;
this.game.children.forEach((c, i)=>{
aq.add({
o: c,
a: {material:{opacity:1}},
t: 1,
d:1+0.1*i
})
})
this.onfinish && this.onfinish();
//context.dashboard.addPoints(10);
}
}
}
export { Game4 }