1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2026-03-02 03:39:21 +00:00

Add setting to show chunk borders

This commit is contained in:
tobspr
2020-08-29 22:52:52 +02:00
parent 49ea6fc381
commit bca379ee89
10 changed files with 347 additions and 308 deletions

View File

@@ -9,7 +9,8 @@ import { DrawParameters } from "../core/draw_parameters";
import { gMetaBuildingRegistry } from "../core/global_registries";
import { createLogger } from "../core/logging";
import { Rectangle } from "../core/rectangle";
import { randomInt, round2Digits, round3Digits } from "../core/utils";
import { ORIGINAL_SPRITE_SCALE } from "../core/sprites";
import { lerp, randomInt, round2Digits } from "../core/utils";
import { Vector } from "../core/vector";
import { Savegame } from "../savegame/savegame";
import { SavegameSerializer } from "../savegame/savegame_serializer";
@@ -30,7 +31,6 @@ import { GameRoot } from "./root";
import { ShapeDefinitionManager } from "./shape_definition_manager";
import { SoundProxy } from "./sound_proxy";
import { GameTime } from "./time/game_time";
import { ORIGINAL_SPRITE_SCALE } from "../core/sprites";
const logger = createLogger("ingame/core");
@@ -61,6 +61,12 @@ export class GameCore {
// Cached
this.boundInternalTick = this.updateLogic.bind(this);
/**
* Opacity of the overview alpha
* @TODO Doesn't belong here
*/
this.overlayAlpha = 0;
}
/**
@@ -385,10 +391,10 @@ export class GameCore {
// Main rendering order
// -----
if (this.root.camera.getIsMapOverlayActive()) {
// Map overview
root.map.drawOverlay(params);
} else {
const desiredOverlayAlpha = this.root.camera.getIsMapOverlayActive() ? 1 : 0;
this.overlayAlpha = lerp(this.overlayAlpha, desiredOverlayAlpha, 0.25);
if (this.overlayAlpha < 0.99) {
// Background (grid, resources, etc)
root.map.drawBackground(params);
@@ -410,6 +416,13 @@ export class GameCore {
}
}
if (this.overlayAlpha > 0.01) {
// Map overview
context.globalAlpha = this.overlayAlpha;
root.map.drawOverlay(params);
context.globalAlpha = 1;
}
if (G_IS_DEV) {
root.map.drawStaticEntityDebugOverlays(params);
}

View File

@@ -1,96 +1,92 @@
import { makeOffscreenBuffer } from "../../../core/buffer_utils";
import { globalConfig } from "../../../core/config";
import { DrawParameters } from "../../../core/draw_parameters";
import { KEYMAPPINGS } from "../../key_action_mapper";
import { THEME } from "../../theme";
import { BaseHUDPart } from "../base_hud_part";
import { Loader } from "../../../core/loader";
import { lerp } from "../../../core/utils";
const wiresBackgroundDpi = 4;
export class HUDWiresOverlay extends BaseHUDPart {
createElements(parent) {}
initialize() {
// Probably not the best location, but the one which makes most sense
this.root.keyMapper.getBinding(KEYMAPPINGS.ingame.switchLayers).add(this.switchLayers, this);
this.generateTilePattern();
this.currentAlpha = 0.0;
}
/**
* Switches between layers
*/
switchLayers() {
if (this.root.currentLayer === "regular") {
this.root.currentLayer = "wires";
} else {
this.root.currentLayer = "regular";
}
this.root.signals.editModeChanged.dispatch(this.root.currentLayer);
}
/**
* Generates the background pattern for the wires overlay
*/
generateTilePattern() {
const overlayTile = Loader.getSprite("sprites/wires/overlay_tile.png");
const dims = globalConfig.tileSize * wiresBackgroundDpi;
const [canvas, context] = makeOffscreenBuffer(dims, dims, {
smooth: false,
reusable: false,
label: "wires-tile-pattern",
});
context.clearRect(0, 0, dims, dims);
overlayTile.draw(context, 0, 0, dims, dims);
this.tilePatternCanvas = canvas;
}
update() {
const desiredAlpha = this.root.currentLayer === "wires" ? 1.0 : 0.0;
this.currentAlpha = lerp(this.currentAlpha, desiredAlpha, 0.12);
}
/**
*
* @param {DrawParameters} parameters
*/
draw(parameters) {
if (this.currentAlpha < 0.02) {
return;
}
if (this.root.camera.getIsMapOverlayActive()) {
return;
}
if (!this.cachedPatternBackground) {
this.cachedPatternBackground = parameters.context.createPattern(this.tilePatternCanvas, "repeat");
}
const bounds = parameters.visibleRect;
parameters.context.globalAlpha = this.currentAlpha;
const scaleFactor = 1 / wiresBackgroundDpi;
parameters.context.globalCompositeOperation = "overlay";
parameters.context.fillStyle = "rgba(50, 200, 150, 1)";
parameters.context.fillRect(bounds.x, bounds.y, bounds.w, bounds.h);
parameters.context.globalCompositeOperation = "source-over";
parameters.context.scale(scaleFactor, scaleFactor);
parameters.context.fillStyle = this.cachedPatternBackground;
parameters.context.fillRect(
bounds.x / scaleFactor,
bounds.y / scaleFactor,
bounds.w / scaleFactor,
bounds.h / scaleFactor
);
parameters.context.scale(1 / scaleFactor, 1 / scaleFactor);
parameters.context.globalAlpha = 1;
}
}
import { makeOffscreenBuffer } from "../../../core/buffer_utils";
import { globalConfig } from "../../../core/config";
import { DrawParameters } from "../../../core/draw_parameters";
import { KEYMAPPINGS } from "../../key_action_mapper";
import { THEME } from "../../theme";
import { BaseHUDPart } from "../base_hud_part";
import { Loader } from "../../../core/loader";
import { lerp } from "../../../core/utils";
const wiresBackgroundDpi = 4;
export class HUDWiresOverlay extends BaseHUDPart {
createElements(parent) {}
initialize() {
// Probably not the best location, but the one which makes most sense
this.root.keyMapper.getBinding(KEYMAPPINGS.ingame.switchLayers).add(this.switchLayers, this);
this.generateTilePattern();
this.currentAlpha = 0.0;
}
/**
* Switches between layers
*/
switchLayers() {
if (this.root.currentLayer === "regular") {
this.root.currentLayer = "wires";
} else {
this.root.currentLayer = "regular";
}
this.root.signals.editModeChanged.dispatch(this.root.currentLayer);
}
/**
* Generates the background pattern for the wires overlay
*/
generateTilePattern() {
const overlayTile = Loader.getSprite("sprites/wires/overlay_tile.png");
const dims = globalConfig.tileSize * wiresBackgroundDpi;
const [canvas, context] = makeOffscreenBuffer(dims, dims, {
smooth: false,
reusable: false,
label: "wires-tile-pattern",
});
context.clearRect(0, 0, dims, dims);
overlayTile.draw(context, 0, 0, dims, dims);
this.tilePatternCanvas = canvas;
}
update() {
const desiredAlpha = this.root.currentLayer === "wires" ? 1.0 : 0.0;
this.currentAlpha = lerp(this.currentAlpha, desiredAlpha, 0.12);
}
/**
*
* @param {DrawParameters} parameters
*/
draw(parameters) {
if (this.currentAlpha < 0.02) {
return;
}
if (!this.cachedPatternBackground) {
this.cachedPatternBackground = parameters.context.createPattern(this.tilePatternCanvas, "repeat");
}
const bounds = parameters.visibleRect;
parameters.context.globalAlpha = this.currentAlpha;
const scaleFactor = 1 / wiresBackgroundDpi;
parameters.context.globalCompositeOperation = "overlay";
parameters.context.fillStyle = "rgba(50, 200, 150, 1)";
parameters.context.fillRect(bounds.x, bounds.y, bounds.w, bounds.h);
parameters.context.globalCompositeOperation = "source-over";
parameters.context.scale(scaleFactor, scaleFactor);
parameters.context.fillStyle = this.cachedPatternBackground;
parameters.context.fillRect(
bounds.x / scaleFactor,
bounds.y / scaleFactor,
bounds.w / scaleFactor,
bounds.h / scaleFactor
);
parameters.context.scale(1 / scaleFactor, 1 / scaleFactor);
parameters.context.globalAlpha = 1;
}
}

View File

@@ -133,6 +133,12 @@ export class MapChunkView extends MapChunk {
: THEME.map.chunkOverview.empty;
context.fillRect(0, 0, w, h);
if (this.root.app.settings.getAllSettings().displayChunkBorders) {
context.fillStyle = THEME.map.chunkBorders;
context.fillRect(0, 0, w, 1);
context.fillRect(0, 1, 1, h);
}
for (let x = 0; x < globalConfig.mapChunkSize; ++x) {
const lowerArray = this.lowerLayer[x];
const upperArray = this.contents[x];

View File

@@ -196,6 +196,7 @@ export class MapView extends BaseMap {
);
}
// Render tile grid
if (!this.root.app.settings.getAllSettings().disableTileGrid) {
const dpi = this.backgroundCacheDPI;
parameters.context.scale(1 / dpi, 1 / dpi);

View File

@@ -1,107 +1,113 @@
import { globalConfig } from "../../core/config";
import { DrawParameters } from "../../core/draw_parameters";
import { GameSystem } from "../game_system";
import { MapChunkView } from "../map_chunk_view";
import { THEME } from "../theme";
import { drawSpriteClipped } from "../../core/draw_utils";
export class MapResourcesSystem extends GameSystem {
/**
* Draws the map resources
* @param {DrawParameters} parameters
* @param {MapChunkView} chunk
*/
drawChunk(parameters, chunk) {
const basicChunkBackground = this.root.buffers.getForKey({
key: "mapresourcebg",
subKey: chunk.renderKey,
w: globalConfig.mapChunkSize,
h: globalConfig.mapChunkSize,
dpi: 1,
redrawMethod: this.generateChunkBackground.bind(this, chunk),
});
parameters.context.imageSmoothingEnabled = false;
drawSpriteClipped({
parameters,
sprite: basicChunkBackground,
x: chunk.tileX * globalConfig.tileSize,
y: chunk.tileY * globalConfig.tileSize,
w: globalConfig.mapChunkWorldSize,
h: globalConfig.mapChunkWorldSize,
originalW: globalConfig.mapChunkSize,
originalH: globalConfig.mapChunkSize,
});
parameters.context.imageSmoothingEnabled = true;
parameters.context.globalAlpha = 0.5;
if (this.root.app.settings.getAllSettings().lowQualityMapResources) {
// LOW QUALITY: Draw patch items only
for (let i = 0; i < chunk.patches.length; ++i) {
const patch = chunk.patches[i];
const destX = chunk.x * globalConfig.mapChunkWorldSize + patch.pos.x * globalConfig.tileSize;
const destY = chunk.y * globalConfig.mapChunkWorldSize + patch.pos.y * globalConfig.tileSize;
const diameter = Math.min(80, 40 / parameters.zoomLevel);
patch.item.drawItemCenteredClipped(destX, destY, parameters, diameter);
}
} else {
// HIGH QUALITY: Draw all items
const layer = chunk.lowerLayer;
for (let x = 0; x < globalConfig.mapChunkSize; ++x) {
const row = layer[x];
const worldX = (chunk.tileX + x) * globalConfig.tileSize;
for (let y = 0; y < globalConfig.mapChunkSize; ++y) {
const lowerItem = row[y];
if (lowerItem) {
const worldY = (chunk.tileY + y) * globalConfig.tileSize;
const destX = worldX + globalConfig.halfTileSize;
const destY = worldY + globalConfig.halfTileSize;
lowerItem.drawItemCenteredClipped(
destX,
destY,
parameters,
globalConfig.defaultItemDiameter
);
}
}
}
}
parameters.context.globalAlpha = 1;
}
/**
*
* @param {MapChunkView} chunk
* @param {HTMLCanvasElement} canvas
* @param {CanvasRenderingContext2D} context
* @param {number} w
* @param {number} h
* @param {number} dpi
*/
generateChunkBackground(chunk, canvas, context, w, h, dpi) {
if (this.root.app.settings.getAllSettings().disableTileGrid) {
// The map doesn't draw a background, so we have to
context.fillStyle = THEME.map.background;
context.fillRect(0, 0, w, h);
} else {
context.clearRect(0, 0, w, h);
}
context.globalAlpha = 0.5;
const layer = chunk.lowerLayer;
for (let x = 0; x < globalConfig.mapChunkSize; ++x) {
const row = layer[x];
for (let y = 0; y < globalConfig.mapChunkSize; ++y) {
const item = row[y];
if (item) {
context.fillStyle = item.getBackgroundColorAsResource();
context.fillRect(x, y, 1, 1);
}
}
}
}
}
import { globalConfig } from "../../core/config";
import { DrawParameters } from "../../core/draw_parameters";
import { GameSystem } from "../game_system";
import { MapChunkView } from "../map_chunk_view";
import { THEME } from "../theme";
import { drawSpriteClipped } from "../../core/draw_utils";
export class MapResourcesSystem extends GameSystem {
/**
* Draws the map resources
* @param {DrawParameters} parameters
* @param {MapChunkView} chunk
*/
drawChunk(parameters, chunk) {
const basicChunkBackground = this.root.buffers.getForKey({
key: "mapresourcebg",
subKey: chunk.renderKey,
w: globalConfig.mapChunkSize,
h: globalConfig.mapChunkSize,
dpi: 1,
redrawMethod: this.generateChunkBackground.bind(this, chunk),
});
parameters.context.imageSmoothingEnabled = false;
drawSpriteClipped({
parameters,
sprite: basicChunkBackground,
x: chunk.tileX * globalConfig.tileSize,
y: chunk.tileY * globalConfig.tileSize,
w: globalConfig.mapChunkWorldSize,
h: globalConfig.mapChunkWorldSize,
originalW: globalConfig.mapChunkSize,
originalH: globalConfig.mapChunkSize,
});
parameters.context.imageSmoothingEnabled = true;
parameters.context.globalAlpha = 0.5;
if (this.root.app.settings.getAllSettings().lowQualityMapResources) {
// LOW QUALITY: Draw patch items only
for (let i = 0; i < chunk.patches.length; ++i) {
const patch = chunk.patches[i];
const destX = chunk.x * globalConfig.mapChunkWorldSize + patch.pos.x * globalConfig.tileSize;
const destY = chunk.y * globalConfig.mapChunkWorldSize + patch.pos.y * globalConfig.tileSize;
const diameter = Math.min(80, 40 / parameters.zoomLevel);
patch.item.drawItemCenteredClipped(destX, destY, parameters, diameter);
}
} else {
// HIGH QUALITY: Draw all items
const layer = chunk.lowerLayer;
for (let x = 0; x < globalConfig.mapChunkSize; ++x) {
const row = layer[x];
const worldX = (chunk.tileX + x) * globalConfig.tileSize;
for (let y = 0; y < globalConfig.mapChunkSize; ++y) {
const lowerItem = row[y];
if (lowerItem) {
const worldY = (chunk.tileY + y) * globalConfig.tileSize;
const destX = worldX + globalConfig.halfTileSize;
const destY = worldY + globalConfig.halfTileSize;
lowerItem.drawItemCenteredClipped(
destX,
destY,
parameters,
globalConfig.defaultItemDiameter
);
}
}
}
}
parameters.context.globalAlpha = 1;
}
/**
*
* @param {MapChunkView} chunk
* @param {HTMLCanvasElement} canvas
* @param {CanvasRenderingContext2D} context
* @param {number} w
* @param {number} h
* @param {number} dpi
*/
generateChunkBackground(chunk, canvas, context, w, h, dpi) {
if (this.root.app.settings.getAllSettings().disableTileGrid) {
// The map doesn't draw a background, so we have to
context.fillStyle = THEME.map.background;
context.fillRect(0, 0, w, h);
} else {
context.clearRect(0, 0, w, h);
}
context.globalAlpha = 0.5;
const layer = chunk.lowerLayer;
for (let x = 0; x < globalConfig.mapChunkSize; ++x) {
const row = layer[x];
for (let y = 0; y < globalConfig.mapChunkSize; ++y) {
const item = row[y];
if (item) {
context.fillStyle = item.getBackgroundColorAsResource();
context.fillRect(x, y, 1, 1);
}
}
}
if (this.root.app.settings.getAllSettings().displayChunkBorders) {
context.fillStyle = THEME.map.chunkBorders;
context.fillRect(0, 0, w, 1);
context.fillRect(0, 1, 1, h);
}
}
}

View File

@@ -1,48 +1,50 @@
{
"uiStyle": "dark",
"map": {
"background": "#2e2f37",
"grid": "rgba(255, 255, 255, 0.02)",
"gridLineWidth": 0.5,
"selectionOverlay": "rgba(74, 163, 223, 0.7)",
"selectionOutline": "rgba(74, 163, 223, 0.5)",
"selectionBackground": "rgba(74, 163, 223, 0.2)",
"directionLock": {
"regular": {
"color": "rgb(74, 237, 134)",
"background": "rgba(74, 237, 134, 0.2)"
},
"wires": {
"color": "rgb(209, 107, 203)",
"background": "rgba(209, 107, 203, 0.2)"
}
},
"colorBlindPickerTile": "rgba(255, 255, 255, 0.5)",
"resources": {
"shape": "#3d3f4a",
"red": "#4a3d3f",
"green": "#3e4a3d",
"blue": "#35384a"
},
"chunkOverview": {
"empty": "#444856",
"filled": "#646b7d"
},
"wires": {
"overlayColor": "rgba(97, 161, 152, 0.75)",
"previewColor": "rgb(97, 161, 152, 0.5)",
"highlightColor": "rgba(0, 0, 255, 0.5)"
}
},
"items": {
"outline": "#111418",
"outlineWidth": 0.75,
"circleBackground": "rgba(20, 30, 40, 0.3)"
}
}
{
"uiStyle": "dark",
"map": {
"background": "#2e2f37",
"grid": "rgba(255, 255, 255, 0.02)",
"gridLineWidth": 0.5,
"selectionOverlay": "rgba(74, 163, 223, 0.7)",
"selectionOutline": "rgba(74, 163, 223, 0.5)",
"selectionBackground": "rgba(74, 163, 223, 0.2)",
"chunkBorders": "rgba(127, 190, 255, 0.04)",
"directionLock": {
"regular": {
"color": "rgb(74, 237, 134)",
"background": "rgba(74, 237, 134, 0.2)"
},
"wires": {
"color": "rgb(209, 107, 203)",
"background": "rgba(209, 107, 203, 0.2)"
}
},
"colorBlindPickerTile": "rgba(255, 255, 255, 0.5)",
"resources": {
"shape": "#3d3f4a",
"red": "#4a3d3f",
"green": "#3e4a3d",
"blue": "#35384a"
},
"chunkOverview": {
"empty": "#444856",
"filled": "#646b7d"
},
"wires": {
"overlayColor": "rgba(97, 161, 152, 0.75)",
"previewColor": "rgb(97, 161, 152, 0.5)",
"highlightColor": "rgba(0, 0, 255, 0.5)"
}
},
"items": {
"outline": "#111418",
"outlineWidth": 0.75,
"circleBackground": "rgba(20, 30, 40, 0.3)"
}
}

View File

@@ -1,49 +1,51 @@
{
"uiStyle": "light",
"map": {
"background": "#fff",
"grid": "#fafafa",
"gridLineWidth": 1,
"selectionOverlay": "rgba(74, 163, 223, 0.7)",
"selectionOutline": "rgba(74, 163, 223, 0.5)",
"selectionBackground": "rgba(74, 163, 223, 0.2)",
"directionLock": {
"regular": {
"color": "rgb(74, 237, 134)",
"background": "rgba(74, 237, 134, 0.2)"
},
"wires": {
"color": "rgb(209, 107, 203)",
"background": "rgba(209, 107, 203, 0.2)"
}
},
"colorBlindPickerTile": "rgba(50, 50, 50, 0.4)",
"resources": {
"shape": "#eaebec",
"red": "#ffbfc1",
"green": "#cbffc4",
"blue": "#bfdaff"
},
"chunkOverview": {
"empty": "#a6afbb",
"filled": "#c5ccd6"
},
"wires": {
"overlayColor": "rgba(97, 161, 152, 0.75)",
"previewColor": "rgb(97, 161, 152, 0.4)",
"highlightColor": "rgba(72, 137, 255, 0.8)"
}
},
"items": {
"outline": "#55575a",
"outlineWidth": 0.75,
"circleBackground": "rgba(40, 50, 65, 0.1)"
}
}
{
"uiStyle": "light",
"map": {
"background": "#fff",
"grid": "#fafafa",
"gridLineWidth": 1,
"selectionOverlay": "rgba(74, 163, 223, 0.7)",
"selectionOutline": "rgba(74, 163, 223, 0.5)",
"selectionBackground": "rgba(74, 163, 223, 0.2)",
"chunkBorders": "rgba(0, 30, 50, 0.03)",
"directionLock": {
"regular": {
"color": "rgb(74, 237, 134)",
"background": "rgba(74, 237, 134, 0.2)"
},
"wires": {
"color": "rgb(209, 107, 203)",
"background": "rgba(209, 107, 203, 0.2)"
}
},
"colorBlindPickerTile": "rgba(50, 50, 50, 0.4)",
"resources": {
"shape": "#eaebec",
"red": "#ffbfc1",
"green": "#cbffc4",
"blue": "#bfdaff"
},
"chunkOverview": {
"empty": "#a6afbb",
"filled": "#c5ccd6"
},
"wires": {
"overlayColor": "rgba(97, 161, 152, 0.75)",
"previewColor": "rgb(97, 161, 152, 0.4)",
"highlightColor": "rgba(72, 137, 255, 0.8)"
}
},
"items": {
"outline": "#55575a",
"outlineWidth": 0.75,
"circleBackground": "rgba(40, 50, 65, 0.1)"
}
}