feat: re-implement rune ring (portal-tethered) Fixes #476
Some checks failed
CI / validate (pull_request) Failing after 4s
Some checks failed
CI / validate (pull_request) Failing after 4s
This commit is contained in:
60
app.js
60
app.js
@@ -821,6 +821,33 @@ function createPortal(config) {
|
||||
light.position.set(0, 3.5, 1);
|
||||
group.add(light);
|
||||
|
||||
// Rune Ring (Portal-tethered)
|
||||
const runeCount = 8;
|
||||
const runeRingRadius = 4.5;
|
||||
const runes = [];
|
||||
for (let i = 0; i < runeCount; i++) {
|
||||
const angle = (i / runeCount) * Math.PI * 2;
|
||||
const runeGeo = new THREE.BoxGeometry(0.3, 0.8, 0.1);
|
||||
const runeMat = new THREE.MeshStandardMaterial({
|
||||
color: portalColor,
|
||||
emissive: portalColor,
|
||||
emissiveIntensity: 0.8,
|
||||
transparent: true,
|
||||
opacity: 0.7,
|
||||
roughness: 0.2,
|
||||
metalness: 0.5,
|
||||
});
|
||||
const rune = new THREE.Mesh(runeGeo, runeMat);
|
||||
rune.position.set(
|
||||
Math.cos(angle) * runeRingRadius,
|
||||
4,
|
||||
Math.sin(angle) * runeRingRadius
|
||||
);
|
||||
rune.rotation.y = angle + Math.PI / 2;
|
||||
group.add(rune);
|
||||
runes.push(rune);
|
||||
}
|
||||
|
||||
// Label
|
||||
const labelCanvas = document.createElement('canvas');
|
||||
labelCanvas.width = 512;
|
||||
@@ -860,7 +887,8 @@ function createPortal(config) {
|
||||
ring,
|
||||
swirl,
|
||||
pSystem,
|
||||
light
|
||||
light,
|
||||
runes
|
||||
};
|
||||
}
|
||||
|
||||
@@ -986,20 +1014,7 @@ function createAmbientStructures() {
|
||||
scene.add(crystal);
|
||||
});
|
||||
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const angle = (i / 5) * Math.PI * 2;
|
||||
const r = 10;
|
||||
const geo = new THREE.OctahedronGeometry(0.4, 0);
|
||||
const mat = new THREE.MeshStandardMaterial({
|
||||
color: NEXUS.colors.primary,
|
||||
emissive: NEXUS.colors.primary,
|
||||
emissiveIntensity: 0.5,
|
||||
});
|
||||
const stone = new THREE.Mesh(geo, mat);
|
||||
stone.position.set(Math.cos(angle) * r, 5 + Math.sin(i * 1.3) * 1.5, Math.sin(angle) * r);
|
||||
stone.name = 'runestone_' + i;
|
||||
scene.add(stone);
|
||||
}
|
||||
|
||||
|
||||
const coreGeo = new THREE.IcosahedronGeometry(0.6, 2);
|
||||
const coreMat = new THREE.MeshPhysicalMaterial({
|
||||
@@ -1427,6 +1442,12 @@ function gameLoop() {
|
||||
positions[i * 3 + 1] += Math.sin(elapsed + i) * 0.002;
|
||||
}
|
||||
portal.pSystem.geometry.attributes.position.needsUpdate = true;
|
||||
|
||||
// Animate runes
|
||||
portal.runes.forEach((rune, i) => {
|
||||
rune.position.y = 4 + Math.sin(elapsed * 2 + i * 0.5) * 0.2;
|
||||
rune.rotation.z = elapsed * 0.8 + i;
|
||||
});
|
||||
});
|
||||
|
||||
// Animate Vision Points
|
||||
@@ -1463,14 +1484,7 @@ function gameLoop() {
|
||||
dustParticles.rotation.y = elapsed * 0.01;
|
||||
}
|
||||
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const stone = scene.getObjectByName('runestone_' + i);
|
||||
if (stone) {
|
||||
stone.position.y = 5 + Math.sin(elapsed * 0.8 + i * 1.3) * 0.8;
|
||||
stone.rotation.y = elapsed * 0.5 + i;
|
||||
stone.rotation.x = elapsed * 0.3 + i * 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const core = scene.getObjectByName('nexus-core');
|
||||
if (core) {
|
||||
|
||||
Reference in New Issue
Block a user