massive interactive objects refactoring
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
import { BoxGeometry, Mesh, MeshStandardMaterial, Group, Vector3, CatmullRomCurve3} from 'three';
|
||||
import { LineMaterial, LineGeometry, Line2 } from 'three/examples/jsm/Addons.js';
|
||||
import { EventManager } from '@/lib/EventManager';
|
||||
import Utils from '#/app/Utils';
|
||||
|
||||
class PairMatchingGame extends EventManager {
|
||||
emits = ['finish', 'interaction']
|
||||
constructor(engine, data) {
|
||||
super();
|
||||
return new Promise(async (resolve, reject)=>{
|
||||
let container = new Group();
|
||||
let c = data.c, orderArray = Array.from({length:c}, (_, i)=>i);
|
||||
let o = [ Utils.shuffleArray(orderArray), Utils.shuffleArray(orderArray) ]
|
||||
const aq = engine.motionQueue;
|
||||
let dx = 3, dy = 1.2;
|
||||
|
||||
let bm = new BoxGeometry(1, 1, 1);
|
||||
|
||||
let material = new MeshStandardMaterial({
|
||||
map: await engine.loadTexture(data.$go.asset.name),
|
||||
alphaTest: 0.5,
|
||||
emissive: 0x00ff00,
|
||||
emissiveIntensity: 0
|
||||
// roughness:1, metalness:0,
|
||||
// normalMap: await engine.loadTexture('NormalMap.png', '/static/textures/'),
|
||||
});
|
||||
//material.map.encoding = sRGBEncoding;
|
||||
|
||||
for (let i = 0; i < c; i++) {
|
||||
let b = [], uv = [], p = [];
|
||||
for (let xi = 0; xi < 2; xi++){
|
||||
b[xi] = bm.clone();
|
||||
uv[xi] = b[xi].getAttribute('uv');
|
||||
let s = [xi/2, i / c];
|
||||
for (let i = 0; i < 6; i++) {
|
||||
//top left
|
||||
uv[xi].array[8 * i] = s[0];
|
||||
uv[xi].array[8 * i + 1] = s[1] + 1 / c;
|
||||
//top right
|
||||
uv[xi].array[8 * i + 2] = s[0] + 1 / 2;
|
||||
uv[xi].array[8 * i + 3] = s[1] + 1 / c;
|
||||
//bottom left
|
||||
uv[xi].array[8 * i + 4] = s[0];
|
||||
uv[xi].array[8 * i + 5] = s[1];
|
||||
//bottom right
|
||||
uv[xi].array[8 * i + 6] = s[0] + 1 / 2;
|
||||
uv[xi].array[8 * i + 7] = s[1];
|
||||
}
|
||||
let mesh = new Mesh(b[xi], material.clone());
|
||||
mesh.position.set(xi * dx + Math.random() * (xi+0.5) * dx, o[xi][i] * dy, Math.random() * (xi+0.5) * dx);
|
||||
mesh.userData.gd = {
|
||||
pair: xi,
|
||||
id: i
|
||||
}
|
||||
container.add(mesh);
|
||||
}
|
||||
}
|
||||
|
||||
let clicked, done = [];
|
||||
|
||||
let connect = (a, b)=>{
|
||||
let crc = new CatmullRomCurve3([
|
||||
a.position,
|
||||
new Vector3().copy(a.position).lerpVectors(a.position, b.position, 0.5).multiplyScalar(1 + Math.random() * 0.1 * done.length / c),
|
||||
b.position
|
||||
])
|
||||
let g = new LineGeometry().setFromPoints( crc.getPoints(7) );
|
||||
let m = new Line2(g, new LineMaterial( {
|
||||
color: 0x00FF00,
|
||||
linewidth: 5, // in world units with size attenuation, pixels otherwise
|
||||
} ));
|
||||
container.add(m)
|
||||
}
|
||||
|
||||
let actionDef = {material:{emissiveIntensity:k=>(1+Math.sin((k*2+1.5)*Math.PI))*4 }};
|
||||
|
||||
var clickFn = (i) => {
|
||||
this.dispatchEvent({type:'interaction'});
|
||||
let oc = clicked;
|
||||
if (done.includes(i.object.userData.gd.id)) return;
|
||||
clicked = i.object;
|
||||
clicked.material.emissive.setHex(0x00ff00);
|
||||
if (oc && oc.userData.gd.pair != clicked.userData.gd.pair){
|
||||
if (oc.userData.gd.id === clicked.userData.gd.id){
|
||||
connect(oc, clicked);
|
||||
done.push(oc.userData.gd.id)
|
||||
if (done.length == c) {
|
||||
this.dispatchEvent({type:'finish'})
|
||||
}
|
||||
}else{
|
||||
clicked.material.emissive.setHex(0xff0000);
|
||||
oc.material.emissive.setHex(0xff0000);
|
||||
}
|
||||
aq.clear(oc, true);
|
||||
aq.add({ o: clicked, a: actionDef, t: 1 });
|
||||
aq.add({ o: oc, a: actionDef, t: 1 });
|
||||
clicked = null;
|
||||
}else{
|
||||
aq.add({ o: clicked, a: actionDef, t: 1, r: true })
|
||||
}
|
||||
};
|
||||
|
||||
container.children.forEach(c => {
|
||||
engine.clickable.add(c, clickFn);
|
||||
});
|
||||
|
||||
this.update = () => {
|
||||
|
||||
};
|
||||
|
||||
this.object = engine.meshUtils.centerOrigin(container);
|
||||
|
||||
this.dispose = () => {
|
||||
engine.meshUtils.clearMaterial(material);
|
||||
bm.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
resolve(this);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export { PairMatchingGame }
|
||||
Reference in New Issue
Block a user