From d3f6cf9b71ec444c707270155f41cb1f41a8872b Mon Sep 17 00:00:00 2001 From: adrien Date: Thu, 3 Oct 2024 00:18:42 +0200 Subject: [PATCH] refactoring --- app.js | 11 +-- jsm/Menu.js | 18 ++--- jsm/Tetrominoes.js | 196 +++++++++++++++++++++------------------------ 3 files changed, 105 insertions(+), 120 deletions(-) diff --git a/app.js b/app.js index 18c3383..eba9ccf 100644 --- a/app.js +++ b/app.js @@ -1,6 +1,6 @@ import * as THREE from 'three' import { scheduler } from './jsm/scheduler.js' -import { TRANSLATION, ROTATION, environment, Mino, Playfield, HoldQueue, NextQueue } from './jsm/Tetrominoes.js' +import { TRANSLATION, ROTATION, environment, InstancedMino, Mino, Playfield, HoldQueue, NextQueue } from './jsm/Tetrominoes.js' import Settings from './jsm/Settings.js' import { Stats } from './jsm/Stats.js' import { Menu } from './jsm/Menu.js' @@ -30,7 +30,7 @@ let game = { menu.stats.show() menu.settings.close() - Mino.meshes.clear() + Mino.instances.clear() nextQueue.init() holdQueue.piece = undefined @@ -299,7 +299,8 @@ const settings = new Settings() const scene = new TetraScene(settings, loadingManager) const controls = new TetraControls(scene.camera, renderer.domElement) -scene.add(Mino.meshes) +const minoes = new InstancedMino() +scene.add(minoes) const holdQueue = new HoldQueue() scene.add(holdQueue) const playfield = new Playfield(loadingManager) @@ -307,7 +308,7 @@ scene.add(playfield) const nextQueue = new NextQueue() scene.add(nextQueue) -const menu = new Menu(game, settings, stats, scene, controls, playfield) +const menu = new Menu(game, settings, stats, scene, minoes, playfield) menu.load() let fps @@ -328,7 +329,7 @@ function animate() { scene.updateMatrixWorld() scene.update(delta) playfield.update(delta) - Mino.meshes.update() + minoes.update() controls.update() renderer.render(scene, scene.camera) diff --git a/jsm/Menu.js b/jsm/Menu.js index c645df8..1f8f7e8 100644 --- a/jsm/Menu.js +++ b/jsm/Menu.js @@ -4,7 +4,7 @@ import { Mino, environment } from './Tetrominoes.js' export class Menu extends GUI { - constructor(game, settings, stats, scene, controls, playfield) { + constructor(game, settings, stats, scene, minoes, playfield) { super({title: "ᵀᴱTᴿᴬ"}) this.startButton = this.add(game, "start").name("Jouer").hide() @@ -28,7 +28,7 @@ export class Menu extends GUI { this.settings.add(settings, "theme", ["Plasma", "Espace", "Rétro"]).name("Thème").onChange(theme => { scene.theme = theme - Mino.meshes.theme = theme + minoes.theme = theme if (theme == "Rétro") { playfield.edge.visible = false playfield.retroEdge.visible = true @@ -77,10 +77,10 @@ export class Menu extends GUI { function changeMaterial() { material?.destroy() material = dev.addFolder("minoes material") - material.add(Mino.meshes.material, "constructor", ["MeshBasicMaterial", "MeshStandardMaterial", "MeshPhysicalMaterial"]).listen().onChange(type => { + material.add(minoes.material, "constructor", ["MeshBasicMaterial", "MeshStandardMaterial", "MeshPhysicalMaterial"]).listen().onChange(type => { switch(type) { case "MeshBasicMaterial": - Mino.meshes.material = new THREE.MeshBasicMaterial({ + minoes.material = new THREE.MeshBasicMaterial({ envMap: environment, side: THREE.DoubleSide, transparent: true, @@ -89,7 +89,7 @@ export class Menu extends GUI { }) break case "MeshStandardMaterial": - Mino.meshes.material = new THREE.MeshStandardMaterial({ + minoes.material = new THREE.MeshStandardMaterial({ envMap: environment, side: THREE.DoubleSide, transparent: true, @@ -99,7 +99,7 @@ export class Menu extends GUI { }) break case "MeshPhysicalMaterial": - Mino.meshes.material = new THREE.MeshPhysicalMaterial({ + minoes.material = new THREE.MeshPhysicalMaterial({ envMap: environment, side: THREE.DoubleSide, transparent: true, @@ -111,11 +111,11 @@ export class Menu extends GUI { }) break } - Mino.meshes.update = Mino.meshes.updateColor + minoes.update = minoes.updateColor changeMaterial() }) - let minoMaterial = Mino.meshes.material instanceof Array ? Mino.meshes.material[0] : Mino.meshes.material + let minoMaterial = minoes.material instanceof Array ? minoes.material[0] : minoes.material if ("opacity" in minoMaterial) material.add(minoMaterial, "opacity" ).min(0).max(1) if ("reflectivity" in minoMaterial) material.add(minoMaterial, "reflectivity" ).min(0).max(1) if ("roughness" in minoMaterial) material.add(minoMaterial, "roughness" ).min(0).max(1) @@ -152,7 +152,7 @@ export class Menu extends GUI { vortex.add(scene.vortex.darkCylinder.material, "opacity").name("dark").min(0).max(1) vortex.add(scene.vortex.colorFullCylinder.material, "opacity").name("colorFull").min(0).max(1) - changeMaterial(Mino.meshes.material.constructor.name) + changeMaterial(minoes.material.constructor.name) material.close() } } diff --git a/jsm/Tetrominoes.js b/jsm/Tetrominoes.js index b7fc47a..8902a40 100644 --- a/jsm/Tetrominoes.js +++ b/jsm/Tetrominoes.js @@ -69,107 +69,7 @@ const sideMaterial = new THREE.MeshStandardMaterial({ }) -class InstancedMino extends THREE.InstancedMesh { - constructor(geometry, material, count) { - super(geometry, material, count) - this.instances = new Set() - this.count = 0 - this.offsets = new Uint8Array(2*count) - this.update = this.updateColor - } - - add(instance) { - this.instances.add(instance) - } - - delete(instance) { - this.instances.delete(instance) - } - - clear() { - this.instances.clear() - } - - set theme(theme) { - if (theme == "Rétro") { - this.resetColor() - this.update = this.updateOffset - if (Mino.materials["Rétro"]) { - this.material = Mino.materials["Rétro"] - } else { - Mino.materials["Rétro"] = [] - const loadingManager = new THREE.LoadingManager(() => InstancedMino.material = Mino.materials["Rétro"]) - new THREE.TextureLoader(loadingManager).load("images/sprites.png", (texture) => { - Mino.materials.Rétro[0] = Mino.materials.Rétro[2] = new TileMaterial({ - color: COLORS.RETRO, - map: texture, - bumpMap: texture, - bumpScale: 1.5, - roughness: 0.25, - metalness: 0.9, - transparent: true, - }, 8, 8) - }) - new THREE.TextureLoader(loadingManager).load("images/edges.png", (texture) => { - Mino.materials.Rétro[1] = Mino.materials.Rétro[3] = Mino.materials.Rétro[4] = Mino.materials.Rétro[5] = new TileMaterial({ - color: COLORS.RETRO, - map: texture, - bumpMap: texture, - bumpScale: 1.5, - roughness: 0.25, - metalness: 0.9, - transparent: true, - }, 1, 1) - }) - } - } else { - this.update = this.updateColor - this.material = Mino.materials[theme] - } - } - - setOffsetAt(index, offset) { - this.offsets[2*index] = offset.x - this.offsets[2*index + 1] = offset.y - } - - resetColor() { - this.instanceColor = null - } - - updateColor() { - this.count = 0 - this.instances.forEach(mino => { - if (mino.parent?.visible) { - this.setMatrixAt(this.count, mino.matrixWorld) - this.setColorAt(this.count, mino.color) - this.count++ - } - }) - if (this.count) { - this.instanceMatrix.needsUpdate = true - this.instanceColor.needsUpdate = true - } - } - - updateOffset() { - this.count = 0 - this.instances.forEach(mino => { - if (mino.parent?.visible) { - this.setMatrixAt(this.count, mino.matrixWorld) - this.setOffsetAt(this.count, mino.offset) - this.count++ - } - }) - if (this.count) { - this.instanceMatrix.needsUpdate = true - this.geometry.setAttribute('offset', new THREE.InstancedBufferAttribute(this.offsets, 2)) - } - } -} - - -class Mino extends THREE.Object3D { +export class InstancedMino extends THREE.InstancedMesh { static materials = { Plasma: new THREE.MeshStandardMaterial({ envMap: environment, @@ -188,8 +88,8 @@ class Mino extends THREE.Object3D { metalness: 0.99, }) } - static meshes - static { + + constructor() { let minoFaceShape = new THREE.Shape() minoFaceShape.moveTo(.1, .1) minoFaceShape.lineTo(.1, .9) @@ -206,9 +106,93 @@ class Mino extends THREE.Object3D { bevelSegments: 1 } const geometry = new THREE.ExtrudeGeometry(minoFaceShape, minoExtrudeSettings) - this.meshes = new InstancedMino(geometry, undefined, 2*ROWS*COLUMNS) + super(geometry, undefined, 2*ROWS*COLUMNS) + this.offsets = new Uint8Array(2*this.count) + this.count = 0 } + set theme(theme) { + if (theme == "Rétro") { + this.resetColor() + this.update = this.updateOffset + if (this.constructor.materials["Rétro"]) { + this.material = this.constructor.materials["Rétro"] + } else { + this.constructor.materials["Rétro"] = [] + const loadingManager = new THREE.LoadingManager(() => this.material = this.constructor.materials["Rétro"]) + new THREE.TextureLoader(loadingManager).load("images/sprites.png", (texture) => { + this.constructor.materials.Rétro[0] = this.constructor.materials.Rétro[2] = new TileMaterial({ + color: COLORS.RETRO, + map: texture, + bumpMap: texture, + bumpScale: 1.4, + roughness: 0.25, + metalness: 0.9, + transparent: true, + }, 8, 8) + }) + new THREE.TextureLoader(loadingManager).load("images/edges.png", (texture) => { + this.constructor.materials.Rétro[1] = this.constructor.materials.Rétro[3] = this.constructor.materials.Rétro[4] = this.constructor.materials.Rétro[5] = new TileMaterial({ + color: COLORS.RETRO, + map: texture, + bumpMap: texture, + bumpScale: 1.4, + roughness: 0.25, + metalness: 0.9, + transparent: true, + }, 1, 1) + }) + } + } else { + this.update = this.updateColor + this.material = this.constructor.materials[theme] + } + } + + setOffsetAt(index, offset) { + this.offsets[2*index] = offset.x + this.offsets[2*index + 1] = offset.y + } + + resetColor() { + this.instanceColor = null + } + + updateColor() { + this.count = 0 + Mino.instances.forEach(mino => { + if (mino.parent?.visible) { + this.setMatrixAt(this.count, mino.matrixWorld) + this.setColorAt(this.count, mino.color) + this.count++ + } + }) + if (this.count) { + this.instanceMatrix.needsUpdate = true + this.instanceColor.needsUpdate = true + } + } + + updateOffset() { + this.count = 0 + Mino.instances.forEach(mino => { + if (mino.parent?.visible) { + this.setMatrixAt(this.count, mino.matrixWorld) + this.setOffsetAt(this.count, mino.offset) + this.count++ + } + }) + if (this.count) { + this.instanceMatrix.needsUpdate = true + this.geometry.setAttribute('offset', new THREE.InstancedBufferAttribute(this.offsets, 2)) + } + } +} + + +class Mino extends THREE.Object3D { + static instances = new Set() + constructor(color, offset) { super() this.color = color @@ -216,7 +200,7 @@ class Mino extends THREE.Object3D { this.velocity = P(50 - 100 * Math.random(), 60 - 100 * Math.random(), 50 - 100 * Math.random()) this.rotationAngle = P(Math.random(), Math.random(), Math.random()).normalize() this.angularVelocity = 5 - 10 * Math.random() - this.constructor.meshes.add(this) + this.constructor.instances.add(this) } explode(delta) { @@ -232,7 +216,7 @@ class Mino extends THREE.Object3D { } dispose() { - this.constructor.meshes.delete(this) + this.constructor.instances.delete(this) } }