animate
This commit is contained in:
24
engine.js
24
engine.js
@@ -97,6 +97,9 @@ export class Engine {
|
|||||||
this.worldMeshes = new Map();
|
this.worldMeshes = new Map();
|
||||||
this.renderRequested = false;
|
this.renderRequested = false;
|
||||||
|
|
||||||
|
this.observedWorlds = new Set();
|
||||||
|
this.updateRequested = false;
|
||||||
|
|
||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
this.resize();
|
this.resize();
|
||||||
this.requestRender();
|
this.requestRender();
|
||||||
@@ -105,6 +108,19 @@ export class Engine {
|
|||||||
this.resize();
|
this.resize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
requestUpdate() {
|
||||||
|
if (!this.updateRequested) {
|
||||||
|
this.updateRequested = true;
|
||||||
|
|
||||||
|
// Promise.resolve().then() executes immediately after the current synchronous
|
||||||
|
// call stack finishes, ensuring 10 simultaneous setBlock calls only trigger 1 update.
|
||||||
|
Promise.resolve().then(() => {
|
||||||
|
this.updateRequested = false;
|
||||||
|
this.updateAll();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
requestRender() {
|
requestRender() {
|
||||||
if (!this.renderRequested) {
|
if (!this.renderRequested) {
|
||||||
this.renderRequested = true;
|
this.renderRequested = true;
|
||||||
@@ -122,6 +138,14 @@ export class Engine {
|
|||||||
|
|
||||||
addDiorama(diorama) {
|
addDiorama(diorama) {
|
||||||
this.dioramas.push(diorama);
|
this.dioramas.push(diorama);
|
||||||
|
|
||||||
|
// Subscribe to the world if we aren't already watching it
|
||||||
|
if (!this.observedWorlds.has(diorama.world)) {
|
||||||
|
this.observedWorlds.add(diorama.world);
|
||||||
|
|
||||||
|
// Whenever the world changes, queue a single, debounced geometry rebuild
|
||||||
|
diorama.world.subscribe(() => this.requestUpdate());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateAll() {
|
async updateAll() {
|
||||||
|
|||||||
34
index.html
34
index.html
@@ -128,6 +128,40 @@
|
|||||||
|
|
||||||
// Fetch and build everything concurrently!
|
// Fetch and build everything concurrently!
|
||||||
await engine.updateAll();
|
await engine.updateAll();
|
||||||
|
|
||||||
|
function set0() {
|
||||||
|
world2.setBlock('minecraft:sticky_piston', 2, 0, 2, {facing: 'east', extended: 'false'});
|
||||||
|
world2.setBlock('minecraft:redstone_block', 3, 0, 2);
|
||||||
|
world2.removeBlock(2.5, 0, 2);
|
||||||
|
world2.removeBlock(3.5, 0, 2);
|
||||||
|
setTimeout(set1, 250)
|
||||||
|
}
|
||||||
|
|
||||||
|
function set1() {
|
||||||
|
world2.setBlock('minecraft:sticky_piston', 2, 0, 2, {facing: 'east', extended: 'true'});
|
||||||
|
world2.removeBlock(3, 0, 2)
|
||||||
|
world2.setBlock('minecraft:piston_head', 2.5, 0, 2, {facing: 'east', short: 'true', type: 'sticky'});
|
||||||
|
world2.setBlock('minecraft:redstone_block', 3.5, 0, 2);
|
||||||
|
setTimeout(set2, 250)
|
||||||
|
}
|
||||||
|
|
||||||
|
function set2() {
|
||||||
|
world2.setBlock('minecraft:piston_head', 3, 0, 2, {facing: 'east', short: 'false', type: 'sticky'});
|
||||||
|
world2.removeBlock(2.5, 0, 2);
|
||||||
|
world2.removeBlock(3.5, 0, 2);
|
||||||
|
world2.setBlock('minecraft:redstone_block', 4, 0, 2);
|
||||||
|
setTimeout(set3, 250)
|
||||||
|
}
|
||||||
|
|
||||||
|
function set3() {
|
||||||
|
world2.removeBlock(4, 0, 2)
|
||||||
|
world2.removeBlock(3, 0, 2)
|
||||||
|
world2.setBlock('minecraft:piston_head', 2.5, 0, 2, {facing: 'east', short: 'true', type: 'sticky'});
|
||||||
|
world2.setBlock('minecraft:redstone_block', 3.5, 0, 2);
|
||||||
|
setTimeout(set0, 250)
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(set3, 1000)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Renderer Initialization Failed:", err);
|
console.error("Renderer Initialization Failed:", err);
|
||||||
}
|
}
|
||||||
|
|||||||
19
world.js
19
world.js
@@ -1,16 +1,30 @@
|
|||||||
// world.js
|
// world.js
|
||||||
export class World {
|
export class World {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.blocks = new Map(); // Keyed by "x,y,z"
|
this.blocks = new Map();
|
||||||
|
this.listeners = new Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subscribe to changes (returns an unsubscribe function)
|
||||||
|
subscribe(callback) {
|
||||||
|
this.listeners.add(callback);
|
||||||
|
return () => this.listeners.delete(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
notify() {
|
||||||
|
for (const listener of this.listeners) listener();
|
||||||
}
|
}
|
||||||
|
|
||||||
setBlock(id, x, y, z, props = {}) {
|
setBlock(id, x, y, z, props = {}) {
|
||||||
const key = `${x},${y},${z}`;
|
const key = `${x},${y},${z}`;
|
||||||
this.blocks.set(key, { id, x, y, z, props });
|
this.blocks.set(key, { id, x, y, z, props });
|
||||||
|
this.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
removeBlock(x, y, z) {
|
removeBlock(x, y, z) {
|
||||||
this.blocks.delete(`${x},${y},${z}`);
|
if (this.blocks.delete(`${x},${y},${z}`)) {
|
||||||
|
this.notify();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateBlock(x, y, z, newProps) {
|
updateBlock(x, y, z, newProps) {
|
||||||
@@ -18,6 +32,7 @@ export class World {
|
|||||||
const block = this.blocks.get(key);
|
const block = this.blocks.get(key);
|
||||||
if (block) {
|
if (block) {
|
||||||
block.props = { ...block.props, ...newProps };
|
block.props = { ...block.props, ...newProps };
|
||||||
|
this.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user