You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tobspr_shapez.io/src/js/game/map_chunk_view.js

202 lines
6.2 KiB

import { MapChunk } from "./map_chunk";
import { GameRoot } from "./root";
import { globalConfig } from "../core/config";
import { DrawParameters } from "../core/draw_parameters";
import { round1Digit } from "../core/utils";
import { Rectangle } from "../core/rectangle";
import { createLogger } from "../core/logging";
import { smoothenDpi } from "../core/dpi_manager";
import { THEME } from "./theme";
const logger = createLogger("chunk");
const chunkSizePixels = globalConfig.mapChunkSize * globalConfig.tileSize;
export class MapChunkView extends MapChunk {
/**
*
* @param {GameRoot} root
* @param {number} x
* @param {number} y
*/
constructor(root, x, y) {
super(root, x, y);
this.boundInternalDrawBackgroundToContext = this.internalDrawBackgroundToContext.bind(this);
this.boundInternalDrawForegroundToContext = this.internalDrawForegroundToContext.bind(this);
/**
* Whenever something changes, we increase this number - so we know we need to redraw
*/
this.renderIteration = 0;
this.markDirty();
}
/**
* Marks this chunk as dirty, rerendering all caches
*/
markDirty() {
++this.renderIteration;
this.renderKey = this.x + "/" + this.y + "@" + this.renderIteration;
}
/**
* Draws the background layer
* @param {DrawParameters} parameters
*/
drawBackgroundLayer(parameters) {
if (parameters.zoomLevel > globalConfig.mapChunkPrerenderMinZoom) {
this.internalDrawBackgroundSystems(parameters);
return;
}
const dpi = smoothenDpi(parameters.zoomLevel);
const buffer = this.root.buffers.getForKey(
"" + dpi,
this.renderKey + "@bg",
chunkSizePixels,
chunkSizePixels,
dpi,
this.boundInternalDrawBackgroundToContext,
{ zoomLevel: parameters.zoomLevel }
);
parameters.context.drawImage(
buffer,
this.tileX * globalConfig.tileSize,
this.tileY * globalConfig.tileSize,
chunkSizePixels,
chunkSizePixels
);
}
/**
* Draws the foreground layer
* @param {DrawParameters} parameters
*/
drawForegroundLayer(parameters) {
if (parameters.zoomLevel > globalConfig.mapChunkPrerenderMinZoom) {
this.internalDrawForegroundSystems(parameters);
return;
}
const dpi = smoothenDpi(parameters.zoomLevel);
const buffer = this.root.buffers.getForKey(
"" + dpi,
this.renderKey + "@fg",
chunkSizePixels,
chunkSizePixels,
dpi,
this.boundInternalDrawForegroundToContext,
{ zoomLevel: parameters.zoomLevel }
);
parameters.context.drawImage(
buffer,
this.tileX * globalConfig.tileSize,
this.tileY * globalConfig.tileSize,
chunkSizePixels,
chunkSizePixels
);
}
/**
*
* @param {HTMLCanvasElement} canvas
* @param {CanvasRenderingContext2D} context
* @param {number} w
* @param {number} h
* @param {number} dpi
*/
internalDrawBackgroundToContext(canvas, context, w, h, dpi, { zoomLevel }) {
const pattern = context.createPattern(this.root.map.cachedBackgroundCanvas, "repeat");
context.scale(dpi, dpi);
if (zoomLevel >= globalConfig.mapChunkOverviewMinZoom) {
const bgDpi = this.root.map.backgroundCacheDPI;
context.scale(1 / bgDpi, 1 / bgDpi);
context.fillStyle = pattern;
context.fillRect(0, 0, chunkSizePixels * bgDpi, chunkSizePixels * bgDpi);
context.scale(bgDpi, bgDpi);
} else {
if (this.containedEntities.length > 0) {
context.fillStyle = THEME.map.chunkOverview.filled;
} else {
context.fillStyle = THEME.map.chunkOverview.empty;
}
context.fillRect(0, 0, 10000, 10000);
}
if (G_IS_DEV && globalConfig.debug.showChunkBorders) {
context.fillStyle = "rgba(0, 0, 255, 0.1)";
context.fillRect(0, 0, 10000, 10000);
}
const parameters = new DrawParameters({
context,
visibleRect: new Rectangle(
this.tileX * globalConfig.tileSize,
this.tileY * globalConfig.tileSize,
chunkSizePixels,
chunkSizePixels
),
desiredAtlasScale: "1",
zoomLevel,
root: this.root,
});
parameters.context.translate(
-this.tileX * globalConfig.tileSize,
-this.tileY * globalConfig.tileSize
);
this.internalDrawBackgroundSystems(parameters);
}
/**
*
* @param {HTMLCanvasElement} canvas
* @param {CanvasRenderingContext2D} context
* @param {number} w
* @param {number} h
* @param {number} dpi
*/
internalDrawForegroundToContext(canvas, context, w, h, dpi, { zoomLevel }) {
context.scale(dpi, dpi);
const parameters = new DrawParameters({
context,
visibleRect: new Rectangle(
this.tileX * globalConfig.tileSize,
this.tileY * globalConfig.tileSize,
chunkSizePixels,
chunkSizePixels
),
desiredAtlasScale: "1",
zoomLevel,
root: this.root,
});
parameters.context.translate(
-this.tileX * globalConfig.tileSize,
-this.tileY * globalConfig.tileSize
);
this.internalDrawForegroundSystems(parameters);
}
/**
* @param {DrawParameters} parameters
*/
internalDrawBackgroundSystems(parameters) {
const systems = this.root.systemMgr.systems;
systems.mapResources.drawChunk(parameters, this);
systems.belt.drawChunk(parameters, this);
}
/**
* @param {DrawParameters} parameters
*/
internalDrawForegroundSystems(parameters) {
const systems = this.root.systemMgr.systems;
systems.miner.drawChunk(parameters, this);
systems.staticMapEntities.drawChunk(parameters, this);
}
}