use drawRect instead of putimagedata for units (25% cpu usage reduction)

This commit is contained in:
Evan
2024-11-26 13:16:23 -08:00
parent 8abc5e4aed
commit 982caa3b23
4 changed files with 14 additions and 61 deletions
+3 -3
View File
@@ -196,11 +196,11 @@
* nukes break alliance DONE 11/25/2024
* BUG: nuke yourself makes you traitor DONE 11/25/2024
* make ports cost more for more ports DONE 11/25/2024
* add battleship
* cache images in UnitLayer
* add battleship DONE 11/26/2024
* use drawRect() instead of putImageData DONE 11/26/2024
* add radiation from nuke
* NPC has relations
* add defense post
* add radiation from nuke
* only show units you can build in the build menu
* REFACTOR: make TransportShip follow build unit flow
* use twitter emojis
+5 -24
View File
@@ -18,7 +18,6 @@ interface UnitRenderConfig {
export class StructureLayer implements Layer {
private canvas: HTMLCanvasElement;
private context: CanvasRenderingContext2D;
private imageData: ImageData;
private unitImages: Map<string, HTMLImageElement> = new Map();
private theme: Theme = null;
@@ -60,27 +59,14 @@ export class StructureLayer implements Layer {
init(game: Game) {
this.canvas = document.createElement('canvas');
this.context = this.canvas.getContext("2d");
this.imageData = this.context.getImageData(0, 0, this.game.width(), this.game.height());
this.context = this.canvas.getContext("2d", { alpha: true });
this.canvas.width = this.game.width();
this.canvas.height = this.game.height();
this.context.putImageData(this.imageData, 0, 0);
this.initImageData();
this.eventBus.on(UnitEvent, e => this.onUnitEvent(e));
}
initImageData() {
this.game.forEachTile((tile) => {
const index = (tile.cell().y * this.game.width()) + tile.cell().x;
const offset = index * 4;
this.imageData.data[offset + 3] = 0;
});
}
renderLayer(context: CanvasRenderingContext2D) {
this.context.putImageData(this.imageData, 0, 0);
context.drawImage(
this.canvas,
-this.game.width() / 2,
@@ -171,17 +157,12 @@ export class StructureLayer implements Layer {
}
paintCell(cell: Cell, color: Colord, alpha: number) {
const index = (cell.y * this.game.width()) + cell.x;
const offset = index * 4;
this.imageData.data[offset] = color.rgba.r;
this.imageData.data[offset + 1] = color.rgba.g;
this.imageData.data[offset + 2] = color.rgba.b;
this.imageData.data[offset + 3] = alpha;
this.clearCell(cell)
this.context.fillStyle = color.alpha(alpha / 255).toRgbString();
this.context.fillRect(cell.x, cell.y, 1, 1);
}
clearCell(cell: Cell) {
const index = (cell.y * this.game.width()) + cell.x;
const offset = index * 4;
this.imageData.data[offset + 3] = 0;
this.context.clearRect(cell.x, cell.y, 1, 1);
}
}
+4 -32
View File
@@ -10,9 +10,6 @@ import anchorIcon from '../../../../resources/images/AnchorIcon.png';
export class UnitLayer implements Layer {
private canvas: HTMLCanvasElement;
private context: CanvasRenderingContext2D;
private imageData: ImageData;
private anchorImage: HTMLImageElement;
private anchorImageLoaded: boolean = false;
private boatToTrail = new Map<Unit, Set<Tile>>();
@@ -20,16 +17,8 @@ export class UnitLayer implements Layer {
constructor(private game: Game, private eventBus: EventBus) {
this.theme = game.config().theme();
this.loadAnchorImage();
}
private loadAnchorImage() {
this.anchorImage = new Image();
this.anchorImage.onload = () => {
this.anchorImageLoaded = true;
};
this.anchorImage.src = anchorIcon;
}
shouldTransform(): boolean {
return true;
@@ -42,25 +31,13 @@ export class UnitLayer implements Layer {
this.canvas = document.createElement('canvas');
this.context = this.canvas.getContext("2d");
this.imageData = this.context.getImageData(0, 0, this.game.width(), this.game.height());
this.canvas.width = this.game.width();
this.canvas.height = this.game.height();
this.context.putImageData(this.imageData, 0, 0);
this.initImageData();
this.eventBus.on(UnitEvent, e => this.onUnitEvent(e));
}
initImageData() {
this.game.forEachTile((tile) => {
const index = (tile.cell().y * this.game.width()) + tile.cell().x;
const offset = index * 4;
this.imageData.data[offset + 3] = 0;
});
}
renderLayer(context: CanvasRenderingContext2D) {
this.context.putImageData(this.imageData, 0, 0);
context.drawImage(
this.canvas,
-this.game.width() / 2,
@@ -185,17 +162,12 @@ export class UnitLayer implements Layer {
paintCell(cell: Cell, color: Colord, alpha: number) {
const index = (cell.y * this.game.width()) + cell.x;
const offset = index * 4;
this.imageData.data[offset] = color.rgba.r;
this.imageData.data[offset + 1] = color.rgba.g;
this.imageData.data[offset + 2] = color.rgba.b;
this.imageData.data[offset + 3] = alpha;
this.clearCell(cell)
this.context.fillStyle = color.alpha(alpha / 255).toRgbString();
this.context.fillRect(cell.x, cell.y, 1, 1);
}
clearCell(cell: Cell) {
const index = (cell.y * this.game.width()) + cell.x;
const offset = index * 4;
this.imageData.data[offset + 3] = 0; // Set alpha to 0 (fully transparent)
this.context.clearRect(cell.x, cell.y, 1, 1);
}
}
+2 -2
View File
@@ -5,7 +5,7 @@ export const devConfig = new class extends DefaultConfig {
unitInfo(type: UnitType): UnitInfo {
const info = super.unitInfo(type)
const oldCost = info.cost
info.cost = (p: Player) => oldCost(p) / 10000
info.cost = (p: Player) => 0 * oldCost(p) / 10000
return info
}
@@ -13,7 +13,7 @@ export const devConfig = new class extends DefaultConfig {
return 95
}
numSpawnPhaseTurns(): number {
return 80
return 40
}
gameCreationRate(): number {
return 20 * 1000