stable
This commit is contained in:
parent
8bd4405fe8
commit
d5c661bc22
53 changed files with 4264 additions and 950 deletions
83
js/render.js
83
js/render.js
|
|
@ -348,6 +348,55 @@ function isEntityVisibleInRect(entity, rect, extra = 0) {
|
|||
return x + r >= rect.left && x - r <= rect.right && y + r >= rect.top && y - r <= rect.bottom;
|
||||
}
|
||||
|
||||
function renderStackSignature(worldRef) {
|
||||
return [
|
||||
(worldRef.items || []).length,
|
||||
(worldRef.tarinai || []).length,
|
||||
(worldRef.ants || []).length,
|
||||
worldRef.terrainVersion || 0,
|
||||
].join(":");
|
||||
}
|
||||
|
||||
function ensureWorldRenderStack(worldRef) {
|
||||
if (!worldRef._renderStack) {
|
||||
worldRef._renderStack = { signature: "", backItems: [], layered: [], carriedPlushies: [], lodgedPins: [] };
|
||||
}
|
||||
const stack = worldRef._renderStack;
|
||||
const signature = renderStackSignature(worldRef);
|
||||
if (!worldRef.drawListDirty && stack.signature === signature) return stack;
|
||||
|
||||
stack.backItems.length = 0;
|
||||
stack.layered.length = 0;
|
||||
stack.carriedPlushies.length = 0;
|
||||
stack.lodgedPins.length = 0;
|
||||
|
||||
for (const it of worldRef.items || []) {
|
||||
if (!it || it.dead || isCachedTerrainItem(it)) continue;
|
||||
if (isPinType(it.type) && it.pinState === "lodged") {
|
||||
stack.lodgedPins.push(it);
|
||||
continue;
|
||||
}
|
||||
if (it.isStructure && it.type === "plushie" && it.carriedById) {
|
||||
stack.carriedPlushies.push(it);
|
||||
continue;
|
||||
}
|
||||
if (isBehindSpriteLayerItem(it)) stack.backItems.push(it);
|
||||
else stack.layered.push({ entity: it, y: renderLayerSortY(it), rank: renderLayerKindRank(it) });
|
||||
}
|
||||
for (const t of worldRef.tarinai || []) {
|
||||
if (t && !t.dead) stack.layered.push({ entity: t, y: renderLayerSortY(t), rank: renderLayerKindRank(t) });
|
||||
}
|
||||
for (const a of worldRef.ants || []) {
|
||||
if (a && !a.dead) stack.layered.push({ entity: a, y: renderLayerSortY(a), rank: renderLayerKindRank(a) });
|
||||
}
|
||||
|
||||
stack.backItems.sort((a, b) => renderLayerSortY(a) - renderLayerSortY(b) || (a.x || 0) - (b.x || 0));
|
||||
stack.layered.sort((a, b) => a.y - b.y || a.rank - b.rank || ((a.entity.x || 0) - (b.entity.x || 0)));
|
||||
stack.signature = signature;
|
||||
worldRef.drawListDirty = false;
|
||||
return stack;
|
||||
}
|
||||
|
||||
function ensureBackgroundCache(w, h, lighting) {
|
||||
const key = backgroundCacheKey(world, lighting);
|
||||
if (!backgroundCache.canvas) {
|
||||
|
|
@ -756,19 +805,12 @@ function render() {
|
|||
drawPlacementPreview(ctx, world);
|
||||
if (terrainLayer) ctx.drawImage(terrainLayer, 0, 0, sceneW, sceneH);
|
||||
|
||||
// Low bedding is drawn one step behind the live sprite stack.
|
||||
const backItems = [];
|
||||
const layered = [];
|
||||
for (const it of world.items) {
|
||||
if (!it || it.dead || isCachedTerrainItem(it)) continue;
|
||||
if (isPinType(it.type) && it.pinState === "lodged") continue;
|
||||
if (it.isStructure && it.type === "plushie" && it.carriedById) continue;
|
||||
if (!isEntityVisibleInRect(it, visibleRect)) continue;
|
||||
if (isBehindSpriteLayerItem(it)) backItems.push(it);
|
||||
else layered.push({ entity: it, y: renderLayerSortY(it), rank: renderLayerKindRank(it) });
|
||||
// Dynamic render stacks are sorted on a short interval rather than every paint.
|
||||
// Visibility is still checked per frame, so camera movement remains responsive.
|
||||
const renderStack = ensureWorldRenderStack(world);
|
||||
for (const it of renderStack.backItems) {
|
||||
if (isEntityVisibleInRect(it, visibleRect)) it.draw(ctx, world.time, lighting);
|
||||
}
|
||||
backItems.sort((a, b) => renderLayerSortY(a) - renderLayerSortY(b) || (a.x || 0) - (b.x || 0));
|
||||
for (const it of backItems) it.draw(ctx, world.time, lighting);
|
||||
|
||||
ctx.save();
|
||||
ctx.lineWidth = 1.15;
|
||||
|
|
@ -786,20 +828,15 @@ function render() {
|
|||
ctx.setLineDash([]);
|
||||
ctx.restore();
|
||||
|
||||
for (const t of world.tarinai || []) {
|
||||
if (t && !t.dead && isEntityVisibleInRect(t, visibleRect)) layered.push({ entity: t, y: renderLayerSortY(t), rank: renderLayerKindRank(t) });
|
||||
for (const entry of renderStack.layered) {
|
||||
if (isEntityVisibleInRect(entry.entity, visibleRect)) entry.entity.draw(ctx, world.time, lighting);
|
||||
}
|
||||
for (const a of world.ants || []) {
|
||||
if (a && !a.dead && isEntityVisibleInRect(a, visibleRect)) layered.push({ entity: a, y: renderLayerSortY(a), rank: renderLayerKindRank(a) });
|
||||
}
|
||||
layered.sort((a, b) => a.y - b.y || a.rank - b.rank || ((a.entity.x || 0) - (b.entity.x || 0)));
|
||||
for (const entry of layered) entry.entity.draw(ctx, world.time, lighting);
|
||||
|
||||
for (const it of world.items) {
|
||||
if (it.isStructure && it.type === "plushie" && it.carriedById && isEntityVisibleInRect(it, visibleRect)) it.draw(ctx, world.time, lighting);
|
||||
for (const it of renderStack.carriedPlushies) {
|
||||
if (isEntityVisibleInRect(it, visibleRect)) it.draw(ctx, world.time, lighting);
|
||||
}
|
||||
for (const it of world.items) {
|
||||
if (isPinType(it.type) && it.pinState === "lodged" && isEntityVisibleInRect(it, visibleRect)) it.draw(ctx, world.time, lighting);
|
||||
for (const it of renderStack.lodgedPins) {
|
||||
if (isEntityVisibleInRect(it, visibleRect)) it.draw(ctx, world.time, lighting);
|
||||
}
|
||||
for (const ef of world.effects) {
|
||||
if (isEntityVisibleInRect(ef, visibleRect)) ef.draw(ctx);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue