Feature: band of different musicians

This commit is contained in:
Dejvino 2025-11-21 21:42:32 +01:00
parent 4726b419f4
commit d36313df37
4 changed files with 25 additions and 11 deletions

View File

@ -2,7 +2,12 @@ import * as THREE from 'three';
import { state } from '../state.js'; import { state } from '../state.js';
import { SceneFeature } from './SceneFeature.js'; import { SceneFeature } from './SceneFeature.js';
import sceneFeatureManager from './SceneFeatureManager.js'; import sceneFeatureManager from './SceneFeatureManager.js';
import musiciansTextureUrl from '/textures/musician1.png'; const musicianTextureUrls = [
'/textures/musician1.png',
'/textures/musician2.png',
'/textures/musician3.png',
'/textures/musician4.png',
];
// --- Stage dimensions for positioning --- // --- Stage dimensions for positioning ---
const stageHeight = 1.5; const stageHeight = 1.5;
@ -20,9 +25,8 @@ export class MedievalMusicians extends SceneFeature {
sceneFeatureManager.register(this); sceneFeatureManager.register(this);
} }
init() { async init() {
// Load the texture and create the material inside the callback const processTexture = (texture) => {
state.loader.load(musiciansTextureUrl, (texture) => {
// 1. Draw texture to canvas to process it // 1. Draw texture to canvas to process it
const image = texture.image; const image = texture.image;
const canvas = document.createElement('canvas'); const canvas = document.createElement('canvas');
@ -53,18 +57,23 @@ export class MedievalMusicians extends SceneFeature {
} }
context.putImageData(imageData, 0, 0); context.putImageData(imageData, 0, 0);
// 4. Create a new texture from the modified canvas return new THREE.CanvasTexture(canvas);
const processedTexture = new THREE.CanvasTexture(canvas); };
// 5. Create a standard material with the new texture // Load and process all textures, creating a material for each
const material = new THREE.MeshStandardMaterial({ const materials = await Promise.all(musicianTextureUrls.map(async (url) => {
const texture = await state.loader.loadAsync(url);
const processedTexture = processTexture(texture);
return new THREE.MeshStandardMaterial({
map: processedTexture, map: processedTexture,
side: THREE.DoubleSide, side: THREE.DoubleSide,
alphaTest: 0.5, // Treat pixels with alpha < 0.5 as fully transparent alphaTest: 0.5, // Treat pixels with alpha < 0.5 as fully transparent
roughness: 0.7, roughness: 0.7,
metalness: 0.1, metalness: 0.1,
}); });
}));
const createMusicians = () => {
// 6. Create and position the musicians // 6. Create and position the musicians
const geometry = new THREE.PlaneGeometry(musicianWidth, musicianHeight); const geometry = new THREE.PlaneGeometry(musicianWidth, musicianHeight);
@ -72,9 +81,12 @@ export class MedievalMusicians extends SceneFeature {
new THREE.Vector3(-2, stageHeight + musicianHeight / 2, -length / 2 + stageDepth / 2 - 1), new THREE.Vector3(-2, stageHeight + musicianHeight / 2, -length / 2 + stageDepth / 2 - 1),
new THREE.Vector3(0, stageHeight + musicianHeight / 2, -length / 2 + stageDepth / 2 - 1.5), new THREE.Vector3(0, stageHeight + musicianHeight / 2, -length / 2 + stageDepth / 2 - 1.5),
new THREE.Vector3(2.5, stageHeight + musicianHeight / 2, -length / 2 + stageDepth / 2 - 1.2), new THREE.Vector3(2.5, stageHeight + musicianHeight / 2, -length / 2 + stageDepth / 2 - 1.2),
new THREE.Vector3(1.2, stageHeight + musicianHeight / 2, -length / 2 + stageDepth / 2 - 0.4),
]; ];
musicianPositions.forEach(pos => { musicianPositions.forEach((pos, index) => {
// Randomly pick one of the created materials
const material = materials[Math.floor(index % materials.length)];
const musician = new THREE.Mesh(geometry, material); const musician = new THREE.Mesh(geometry, material);
musician.position.copy(pos); musician.position.copy(pos);
state.scene.add(musician); state.scene.add(musician);
@ -97,7 +109,9 @@ export class MedievalMusicians extends SceneFeature {
jumpStartTime: 0, jumpStartTime: 0,
}); });
}); });
}); };
createMusicians();
} }
update(deltaTime) { update(deltaTime) {
@ -131,7 +145,7 @@ export class MedievalMusicians extends SceneFeature {
// --- Decide to jump to the other plane --- // --- Decide to jump to the other plane ---
musicianObj.state = 'PREPARING_JUMP'; musicianObj.state = 'PREPARING_JUMP';
const targetX = (Math.random() - 0.5) * area.x; const targetX = (Math.random() - 0.5) * area.x;
musicianObj.targetPosition = new THREE.Vector3(targetX, mesh.position.y, planeEdgeZ); musicianObj.targetPosition = new THREE.Vector3(targetX, area.y + musicianHeight/2, planeEdgeZ);
} else { } else {
// --- Decide to move to a new spot on the current plane --- // --- Decide to move to a new spot on the current plane ---
const newTarget = new THREE.Vector3( const newTarget = new THREE.Vector3(

Binary file not shown.

After

Width:  |  Height:  |  Size: 1004 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 941 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB