Skip to content

Commit

Permalink
Render main map on a single canvas instead of using two with a buffer.
Browse files Browse the repository at this point in the history
GitOrigin-RevId: 94c1e5f02f8b490ed47bfea4c1aeed6ae8230508
  • Loading branch information
cpojer committed Jan 24, 2025
1 parent f0b5a63 commit 5e4faa3
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 51 deletions.
20 changes: 15 additions & 5 deletions athena/info/Tile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,7 @@ export const DeepSea = new TileInfo(
{ fallback: Sea, isolated: true },
);

// Keep in sync with `getFloatingEdgeAnimation`.
export const WaterfallModifiers = new Set([
Modifier.RiverFlowsFromTop,
Modifier.RiverFlowsFromBottom,
Expand Down Expand Up @@ -1570,12 +1571,21 @@ export const FloatingWaterEdge = new TileInfo(
},
);

export const getFloatingEdgeAnimation = (modifier: Modifier, biome: Biome) => {
const wallAreaAnimation = { ...SeaAnimation, offset: 1 };
const areaAnimation = { ...SeaAnimation, offset: 2 };

export function getFloatingEdgeAnimation(modifier: Modifier, biome: Biome) {
if (biome === Biome.Spaceship) {
return null;
}

if (WaterfallModifiers.has(modifier)) {
// Keep in sync with `WaterfallModifiers`.
if (
modifier === Modifier.RiverFlowsFromTop ||
modifier === Modifier.RiverFlowsFromBottom ||
modifier === Modifier.RiverFlowsFromLeft ||
modifier === Modifier.RiverFlowsFromRight
) {
return WaterfallAnimation;
}

Expand All @@ -1585,7 +1595,7 @@ export const getFloatingEdgeAnimation = (modifier: Modifier, biome: Biome) => {
modifier === Modifier.LeftWallAreaDecorator ||
modifier === Modifier.RightWallAreaDecorator
) {
return { ...SeaAnimation, offset: 1 };
return wallAreaAnimation;
}

if (
Expand All @@ -1594,11 +1604,11 @@ export const getFloatingEdgeAnimation = (modifier: Modifier, biome: Biome) => {
modifier === Modifier.BottomLeftAreaDecorator ||
modifier === Modifier.BottomRightAreaDecorator
) {
return { ...SeaAnimation, offset: 2 };
return areaAnimation;
}

return null;
};
}

export type MaybeTileID = number | null | false;

Expand Down
2 changes: 1 addition & 1 deletion athena/lib/indexToSpriteVector.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import SpriteVector from '../map/SpriteVector.tsx';

export default function indexToVector(
export default function indexToSpriteVector(
index: number,
width: number,
): SpriteVector {
Expand Down
61 changes: 18 additions & 43 deletions hera/Tiles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from '@deities/athena/info/Tile.tsx';
import getBiomeStyle from '@deities/athena/lib/getBiomeStyle.tsx';
import getFloatingEdgeModifier from '@deities/athena/lib/getFloatingEdgeModifier.tsx';
import indexToVector from '@deities/athena/lib/indexToVector.tsx';
import { Biome } from '@deities/athena/map/Biome.tsx';
import vec from '@deities/athena/map/vec.tsx';
import Vector from '@deities/athena/map/Vector.tsx';
Expand Down Expand Up @@ -65,16 +66,6 @@ const sprites = {
[Biome.Luna]: Tiles6,
} as const;

const createCanvas = (
mapSize: { height: number; width: number },
size: number,
) => {
const canvas = document.createElement('canvas');
canvas.height = (mapSize.height + 2) * size;
canvas.width = (mapSize.width + 2) * size;
return canvas;
};

export default memo(function Tiles({
map,
paused,
Expand All @@ -91,37 +82,28 @@ export default memo(function Tiles({
vision: VisionT;
}) {
const ref = useRef<HTMLDivElement>(null);
const canvasRefs = useRef<Array<HTMLCanvasElement>>([]);
const canvasRef = useRef<HTMLCanvasElement>(null);
const isVisible = useVisibilityState();
const hasSprites = useSprites('all');
const { biome } = map.config;
const biomeStyle = getBiomeStyle(biome);

useLayoutEffect(() => {
if (!hasSprites) {
if (!hasSprites || !canvasRef.current) {
return;
}

if (!canvasRefs.current.length) {
canvasRefs.current = [
createCanvas(map.size, size),
createCanvas(map.size, size),
];
}

const tileset = {
buildings: spriteImage('BuildingsShadow', biome),
structures: spriteImage('StructuresShadow', biome),
tiles: sprites[biome],
};

const [visibleCanvas, mainCanvas] = canvasRefs.current;
const context = visibleCanvas.getContext('2d')!;
const mainContext = mainCanvas.getContext('2d')!;
const canvas = canvasRef.current;
const context = canvas.getContext('2d')!;
const currentTick = getTick();

context.clearRect(0, 0, visibleCanvas.width, visibleCanvas.height);
mainContext.clearRect(0, 0, mainCanvas.width, mainCanvas.height);
context.clearRect(0, 0, canvas.width, canvas.height);

map.forEachTile(
(vector: Vector, tile: TileInfo, layer: TileLayer, modifier: number) => {
Expand Down Expand Up @@ -153,7 +135,6 @@ export default memo(function Tiles({
}
renderFloatingTile(
context,
mainContext,
tileset,
map,
vision,
Expand All @@ -168,22 +149,14 @@ export default memo(function Tiles({
}
}

mainContext.drawImage(visibleCanvas, 0, 0);

if (style === 'clip') {
clip(mainContext, size, map);
}

if (ref.current) {
ref.current.innerHTML = '';
if (!mainCanvas.parentNode) {
ref.current.append(mainCanvas);
}
clip(context, size, map);
}

if (!paused && isVisible) {
return tick((tick) => {
map.forEachField((vector: Vector) => {
for (let i = 0; i < map.map.length; i++) {
const vector = indexToVector(i, map.size.width);
const tile =
map.buildings.get(vector)?.info === Shelter
? Campsite
Expand All @@ -199,8 +172,6 @@ export default memo(function Tiles({
frame != null ||
(layer1TileInfo?.sprite?.animation && !tile.sprite.animation);
if (renderLayer0) {
mainContext.clearRect(vector.x * size, vector.y * size, size, size);
context.clearRect(vector.x * size, vector.y * size, size, size);
renderTile(
context,
tileset,
Expand Down Expand Up @@ -233,12 +204,11 @@ export default memo(function Tiles({
renderEntities,
);
}
});
}

for (const [vector, modifier] of floatingTiles) {
renderFloatingTile(
context,
mainContext,
tileset,
map,
vision,
Expand All @@ -251,9 +221,8 @@ export default memo(function Tiles({
);
}

mainContext.drawImage(visibleCanvas, 0, 0);
if (style === 'clip') {
clip(mainContext, size, map);
clip(context, size, map);
}
});
}
Expand Down Expand Up @@ -295,7 +264,13 @@ export default memo(function Tiles({
position: 'absolute',
top: -size,
}}
/>
>
<canvas
height={(map.size.height + 2) * size}
ref={canvasRef}
width={(map.size.width + 2) * size}
/>
</div>
</div>
);
});
2 changes: 0 additions & 2 deletions hera/render/renderFloatingTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import renderTile, { TileSet } from './renderTile.tsx';

export default function renderFloatingTile(
context: CanvasRenderingContext2D,
mainContext: CanvasRenderingContext2D,
tileset: TileSet,
map: MapData,
vision: VisionT,
Expand All @@ -27,7 +26,6 @@ export default function renderFloatingTile(
const targetX = vector.x * size;
const targetY = vector.y * size;
context.clearRect(targetX, targetY, size, size);
mainContext.clearRect(targetX, targetY, size, size);
}

const [modifier0, modifier1] = Array.isArray(modifier)
Expand Down

0 comments on commit 5e4faa3

Please sign in to comment.