refactoring

This commit is contained in:
Adrien MALINGREY 2024-10-03 00:18:42 +02:00
parent 5b058a58b3
commit d3f6cf9b71
3 changed files with 105 additions and 120 deletions

11
app.js
View File

@ -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)

View File

@ -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()
}
}

View File

@ -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)
}
}