Sprite system (#512)

## Description:

This adds the spriteLoader that loads and caches sprites to be used in
the unitlayer for rendering units as well as sprites for all units and
an alternative mirv sprite to show what can be done using sprites

color codes for grayscaled sprites:
b4b4b4 = territory color
464646 = border color
828282 = spawnhighlight color

The sprites are grayscaled and recolored to have a single base png for
all units

Fixes #505 

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors

## Please put your Discord username so you can be contacted if a bug or
regression is found:

Readix
This commit is contained in:
Readixyee
2025-04-15 11:41:06 -07:00
committed by GitHub
parent 6d295fe0f6
commit a8c87e3bf1
10 changed files with 166 additions and 147 deletions
+30 -147
View File
@@ -19,6 +19,8 @@ import { MoveWarshipIntentEvent } from "../../Transport";
import { TransformHandler } from "../TransformHandler";
import { Layer } from "./Layer";
import { getColoredSprite, loadAllSprites } from "../SpriteLoader";
enum Relationship {
Self,
Ally,
@@ -77,6 +79,8 @@ export class UnitLayer implements Layer {
this.eventBus.on(MouseUpEvent, (e) => this.onMouseUp(e));
this.eventBus.on(UnitSelectionEvent, (e) => this.onUnitSelectionChange(e));
this.redraw();
loadAllSprites();
}
/**
@@ -258,56 +262,13 @@ export class UnitLayer implements Layer {
this.clearCell(this.game.x(t), this.game.y(t));
}
if (!unit.isActive()) {
return;
}
let outerColor = this.theme.territoryColor(unit.owner());
if (unit.warshipTargetId()) {
const targetOwner = this.game
.units()
.find((u) => u.id() == unit.warshipTargetId())
?.owner();
if (targetOwner == this.myPlayer) {
outerColor = colord({ r: 200, b: 0, g: 0 });
if (unit.isActive()) {
if (unit.warshipTargetId()) {
this.drawSprite(unit, colord({ r: 200, b: 0, g: 0 }));
} else {
this.drawSprite(unit);
}
}
// Paint outer territory
for (const t of this.game.bfs(
unit.tile(),
euclDistFN(unit.tile(), 5, false),
)) {
this.paintCell(this.game.x(t), this.game.y(t), rel, outerColor, 255);
}
// Paint border
for (const t of this.game.bfs(
unit.tile(),
manhattanDistFN(unit.tile(), 4),
)) {
this.paintCell(
this.game.x(t),
this.game.y(t),
rel,
this.theme.borderColor(unit.owner()),
255,
);
}
// Paint inner territory
for (const t of this.game.bfs(
unit.tile(),
euclDistFN(unit.tile(), 1, false),
)) {
this.paintCell(
this.game.x(t),
this.game.y(t),
rel,
this.theme.territoryColor(unit.owner()),
255,
);
}
}
private handleShellEvent(unit: UnitView) {
@@ -355,32 +316,13 @@ export class UnitLayer implements Layer {
}
if (unit.isActive()) {
for (const t of this.game.bfs(
unit.tile(),
euclDistFN(unit.tile(), range, false),
)) {
this.paintCell(
this.game.x(t),
this.game.y(t),
rel,
this.theme.spawnHighlightColor(),
255,
);
}
this.paintCell(
this.game.x(unit.tile()),
this.game.y(unit.tile()),
rel,
this.theme.borderColor(unit.owner()),
255,
);
this.drawSprite(unit);
}
}
private handleNuke(unit: UnitView) {
const rel = this.relationship(unit);
let range = 0;
switch (unit.type()) {
case UnitType.AtomBomb:
range = 4;
@@ -393,7 +335,6 @@ export class UnitLayer implements Layer {
break;
}
// Clear previous area
for (const t of this.game.bfs(
unit.lastTile(),
euclDistFN(unit.lastTile(), range, false),
@@ -402,30 +343,7 @@ export class UnitLayer implements Layer {
}
if (unit.isActive()) {
for (const t of this.game.bfs(
unit.tile(),
euclDistFN(unit.tile(), range, false),
)) {
this.paintCell(
this.game.x(t),
this.game.y(t),
rel,
this.theme.spawnHighlightColor(),
255,
);
}
for (const t of this.game.bfs(
unit.tile(),
euclDistFN(unit.tile(), 2, false),
)) {
this.paintCell(
this.game.x(t),
this.game.y(t),
rel,
this.theme.borderColor(unit.owner()),
255,
);
}
this.drawSprite(unit);
}
}
@@ -458,33 +376,7 @@ export class UnitLayer implements Layer {
}
if (unit.isActive()) {
// Paint territory
for (const t of this.game.bfs(
unit.tile(),
manhattanDistFN(unit.tile(), 2),
)) {
this.paintCell(
this.game.x(t),
this.game.y(t),
rel,
this.theme.territoryColor(unit.owner()),
255,
);
}
// Paint border
for (const t of this.game.bfs(
unit.tile(),
manhattanDistFN(unit.tile(), 1),
)) {
this.paintCell(
this.game.x(t),
this.game.y(t),
rel,
this.theme.borderColor(unit.owner()),
255,
);
}
this.drawSprite(unit);
}
}
@@ -500,7 +392,7 @@ export class UnitLayer implements Layer {
// Clear previous area
for (const t of this.game.bfs(
unit.lastTile(),
manhattanDistFN(unit.lastTile(), 2),
manhattanDistFN(unit.lastTile(), 4),
)) {
this.clearCell(this.game.x(t), this.game.y(t));
}
@@ -518,31 +410,7 @@ export class UnitLayer implements Layer {
);
}
for (const t of this.game.bfs(
unit.tile(),
manhattanDistFN(unit.tile(), 2),
)) {
this.paintCell(
this.game.x(t),
this.game.y(t),
rel,
this.theme.borderColor(unit.owner()),
255,
);
}
for (const t of this.game.bfs(
unit.tile(),
manhattanDistFN(unit.tile(), 1),
)) {
this.paintCell(
this.game.x(t),
this.game.y(t),
rel,
this.theme.territoryColor(unit.owner()),
255,
);
}
this.drawSprite(unit);
} else {
for (const t of trail) {
this.clearCell(
@@ -606,4 +474,19 @@ export class UnitLayer implements Layer {
) {
context.clearRect(x, y, 1, 1);
}
drawSprite(unit: UnitView, customTerritoryColor?: Colord) {
const x = this.game.x(unit.tile());
const y = this.game.y(unit.tile());
const sprite = getColoredSprite(unit, this.theme, customTerritoryColor);
this.context.drawImage(
sprite,
Math.round(x - sprite.width / 2),
Math.round(y - sprite.height / 2),
sprite.width,
sprite.width,
);
}
}