Blockify collectibles
This commit is contained in:
parent
4a1f06e6bd
commit
27459787c1
BIN
src/art/pickups/collectibles.png
Normal file
BIN
src/art/pickups/collectibles.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 605 B |
BIN
src/art/pickups/collectibles_silhouettes.png
Normal file
BIN
src/art/pickups/collectibles_silhouettes.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 471 B |
Binary file not shown.
Before Width: | Height: | Size: 455 B |
Binary file not shown.
Before Width: | Height: | Size: 431 B |
@ -1,4 +1,5 @@
|
||||
import { Color } from "./engine/datatypes.ts";
|
||||
import { Stat } from "./datatypes.ts";
|
||||
|
||||
export const BG_OUTER = Color.parseHexCode("#143464");
|
||||
export const BG_WALL_OR_UNREVEALED = Color.parseHexCode("#143464");
|
||||
@ -10,3 +11,36 @@ export const FG_TEXT_ENDORSED = Color.parseHexCode("#80ff80");
|
||||
export const FG_BOLD = Color.parseHexCode("#ffffff");
|
||||
export const BG_CEILING = Color.parseHexCode("#143464");
|
||||
export const FG_MOULDING = FG_TEXT;
|
||||
|
||||
// stat colors
|
||||
export const SWATCH_EXP: [Color, Color] = [
|
||||
Color.parseHexCode("#b9bffb"),
|
||||
Color.parseHexCode("#e3e6ff"),
|
||||
];
|
||||
|
||||
export const SWATCH_AGI: [Color, Color] = [
|
||||
Color.parseHexCode("#df3e23"),
|
||||
Color.parseHexCode("#fa6a0a"),
|
||||
];
|
||||
|
||||
export const SWATCH_INT: [Color, Color] = [
|
||||
Color.parseHexCode("#285cc4"),
|
||||
Color.parseHexCode("#249fde"),
|
||||
];
|
||||
|
||||
export const SWATCH_CHA: [Color, Color] = [
|
||||
Color.parseHexCode("#793a80"),
|
||||
Color.parseHexCode("#bc4a9b"),
|
||||
];
|
||||
|
||||
export const SWATCH_PSI: [Color, Color] = [
|
||||
Color.parseHexCode("#9cdb43"),
|
||||
Color.parseHexCode("#d6f264"),
|
||||
];
|
||||
|
||||
export const SWATCH_STAT: Record<Stat, [Color, Color]> = {
|
||||
AGI: SWATCH_AGI,
|
||||
INT: SWATCH_INT,
|
||||
CHA: SWATCH_CHA,
|
||||
PSI: SWATCH_PSI,
|
||||
};
|
||||
|
130
src/huntmode.ts
130
src/huntmode.ts
@ -4,9 +4,6 @@ import { D, I } from "./engine/public.ts";
|
||||
import { sprThrallLore } from "./sprites.ts";
|
||||
import {
|
||||
BG_INSET,
|
||||
BG_WALL_OR_UNREVEALED,
|
||||
FG_BOLD,
|
||||
FG_MOULDING,
|
||||
FG_TEXT,
|
||||
FG_TEXT_ENDORSED,
|
||||
FG_TOO_EXPENSIVE,
|
||||
@ -18,6 +15,7 @@ import { shadowcast } from "./shadowcast.ts";
|
||||
import { withCamera } from "./layout.ts";
|
||||
import { getCheckModal } from "./checkmodal.ts";
|
||||
import { CARDINAL_DIRECTIONS } from "./mapgen.ts";
|
||||
import { Block3D, Floor3D, World3D } from "./world3d.ts";
|
||||
|
||||
export class HuntMode {
|
||||
map: LoadedNewMap;
|
||||
@ -113,14 +111,22 @@ export class HuntMode {
|
||||
this.#updateFov();
|
||||
this.#updatePickups();
|
||||
|
||||
let world3d = new World3D(this.map.size);
|
||||
for (let y = 0; y < this.map.size.h; y += 1) {
|
||||
for (let x = 0; x < this.map.size.w; x += 1) {
|
||||
this.#writeMapCellToWorld(world3d, new Point(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
for (let y = 0; y < this.map.size.h; y += 1) {
|
||||
for (let x = 0; x < this.map.size.w; x += 1) {
|
||||
let offsetInPixels = new Point(x, y)
|
||||
.scale(FLOOR_CELL_SIZE)
|
||||
.offset(this.pixelPlayer.negate());
|
||||
this.#drawMapCell(offsetInPixels, new Point(x, y));
|
||||
this.#drawMapCell(offsetInPixels, world3d, new Point(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
this.#drawPlayer(globalOffset);
|
||||
|
||||
this.#drawBadges(globalOffset);
|
||||
@ -181,8 +187,8 @@ export class HuntMode {
|
||||
}
|
||||
|
||||
let nSteps = 40;
|
||||
let szX = 0.75;
|
||||
let szY = 0.75;
|
||||
let szX = 0.5;
|
||||
let szY = 0.5;
|
||||
|
||||
this.velocity = new Point(dx, dy);
|
||||
|
||||
@ -190,7 +196,7 @@ export class HuntMode {
|
||||
for (let offset of CARDINAL_DIRECTIONS.values()) {
|
||||
let bigBbox = new Rect(
|
||||
this.floatingPlayer
|
||||
.offset(offset.scale(new Size(0.02, 0.02)))
|
||||
.offset(offset.scale(new Size(0.12, 0.12)))
|
||||
.offset(new Point(-szX / 2, -szY / 2)),
|
||||
new Size(szX, szY),
|
||||
);
|
||||
@ -293,26 +299,14 @@ export class HuntMode {
|
||||
this.drawpile.draw();
|
||||
}
|
||||
|
||||
#drawMapCell(offsetInPixels: Point, mapPosition: Point) {
|
||||
const OFFSET_UNDER_FLOOR = -512 + mapPosition.y;
|
||||
#drawMapCell(offsetInPixels: Point, world3d: World3D, mapPosition: Point) {
|
||||
const OFFSET_FLOOR = -256 + mapPosition.y;
|
||||
const OFFSET_AIR = 0 + mapPosition.y;
|
||||
const OFFSET_TOP = 256 + mapPosition.y;
|
||||
const OFFSET_TOP_OF_TOP = 512 + mapPosition.y;
|
||||
|
||||
const gridArt = new GridArt(offsetInPixels);
|
||||
|
||||
let cellData = this.map.get(mapPosition);
|
||||
world3d.drawCell(this.drawpile, gridArt, mapPosition);
|
||||
|
||||
this.drawpile.add(OFFSET_UNDER_FLOOR, () => {
|
||||
gridArt.drawCeiling(BG_WALL_OR_UNREVEALED);
|
||||
});
|
||||
if (cellData.architecture == Architecture.Wall || !cellData.revealed) {
|
||||
this.drawpile.add(OFFSET_TOP, () => {
|
||||
gridArt.drawCeiling(BG_WALL_OR_UNREVEALED);
|
||||
});
|
||||
return;
|
||||
}
|
||||
let cellData = this.map.get(mapPosition);
|
||||
|
||||
if (!cellData.revealed) {
|
||||
return;
|
||||
@ -343,7 +337,6 @@ export class HuntMode {
|
||||
}
|
||||
|
||||
gridArt.drawFloor(color);
|
||||
pickup?.drawFloor(gridArt);
|
||||
},
|
||||
gridArt.floorRect,
|
||||
true,
|
||||
@ -369,70 +362,32 @@ export class HuntMode {
|
||||
);
|
||||
|
||||
if (pickup != null) {
|
||||
this.drawpile.add(OFFSET_AIR, () => {
|
||||
pickup.drawInAir(gridArt);
|
||||
});
|
||||
}
|
||||
|
||||
const isRevealedBlock = (dx: number, dy: number) => {
|
||||
let other = this.map.get(mapPosition.offset(new Point(dx, dy)));
|
||||
return other.revealed && other.architecture == Architecture.Wall;
|
||||
};
|
||||
if (isRevealedBlock(0, -1) && isRevealedBlock(-1, 0)) {
|
||||
this.drawpile.add(OFFSET_TOP_OF_TOP, () => {
|
||||
gridArt.drawMouldingTopLeft(FG_MOULDING);
|
||||
});
|
||||
}
|
||||
if (isRevealedBlock(0, -1)) {
|
||||
this.drawpile.add(OFFSET_AIR, () => {
|
||||
gridArt.drawWallTop(FG_TEXT);
|
||||
});
|
||||
this.drawpile.add(OFFSET_TOP_OF_TOP, () => {
|
||||
gridArt.drawMouldingTop(FG_MOULDING);
|
||||
});
|
||||
}
|
||||
if (isRevealedBlock(0, -1) && isRevealedBlock(1, 0)) {
|
||||
this.drawpile.add(OFFSET_TOP_OF_TOP, () => {
|
||||
gridArt.drawMouldingTopRight(FG_MOULDING);
|
||||
});
|
||||
}
|
||||
if (isRevealedBlock(-1, 0)) {
|
||||
this.drawpile.add(OFFSET_AIR, () => {
|
||||
gridArt.drawWallLeft(FG_TEXT);
|
||||
});
|
||||
this.drawpile.add(OFFSET_TOP_OF_TOP, () => {
|
||||
gridArt.drawMouldingLeft(FG_MOULDING);
|
||||
});
|
||||
}
|
||||
if (isRevealedBlock(0, 1) && isRevealedBlock(-1, 0)) {
|
||||
this.drawpile.add(OFFSET_TOP_OF_TOP, () => {
|
||||
gridArt.drawMouldingBottomLeft(FG_MOULDING);
|
||||
});
|
||||
}
|
||||
if (isRevealedBlock(0, 1)) {
|
||||
this.drawpile.add(OFFSET_AIR, () => {
|
||||
gridArt.drawWallBottom(FG_BOLD);
|
||||
});
|
||||
this.drawpile.add(OFFSET_TOP_OF_TOP, () => {
|
||||
gridArt.drawMouldingBottom(FG_MOULDING);
|
||||
});
|
||||
}
|
||||
if (isRevealedBlock(0, 1) && isRevealedBlock(1, 0)) {
|
||||
this.drawpile.add(OFFSET_TOP_OF_TOP, () => {
|
||||
gridArt.drawMouldingBottomRight(FG_MOULDING);
|
||||
});
|
||||
}
|
||||
if (isRevealedBlock(1, 0)) {
|
||||
this.drawpile.add(OFFSET_AIR, () => {
|
||||
gridArt.drawWallRight(FG_BOLD);
|
||||
});
|
||||
this.drawpile.add(OFFSET_TOP_OF_TOP, () => {
|
||||
gridArt.drawMouldingRight(FG_MOULDING);
|
||||
});
|
||||
pickup.draw(this.drawpile, gridArt);
|
||||
}
|
||||
}
|
||||
|
||||
#drawPlayer(globalOffset: Point) {
|
||||
#writeMapCellToWorld(world3d: World3D, mapPosition: Point) {
|
||||
let cellData = this.map.get(mapPosition);
|
||||
if (!cellData.revealed) {
|
||||
return;
|
||||
}
|
||||
|
||||
let pickupBlock = cellData.pickup?.getBlock();
|
||||
if (pickupBlock) {
|
||||
world3d.set(mapPosition, pickupBlock);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cellData.architecture == Architecture.Wall) {
|
||||
world3d.set(mapPosition, Block3D.standardWall());
|
||||
return;
|
||||
}
|
||||
|
||||
world3d.set(mapPosition, new Floor3D());
|
||||
}
|
||||
|
||||
#drawPlayer(_globalOffset: Point) {
|
||||
/*
|
||||
let cellOffset = this.pixelPlayer.offset(globalOffset.negate());
|
||||
this.drawpile.add(1024, () => {
|
||||
D.drawSprite(sprThrallLore, cellOffset, 1, {
|
||||
@ -440,6 +395,13 @@ export class HuntMode {
|
||||
yScale: 2,
|
||||
});
|
||||
});
|
||||
*/
|
||||
this.drawpile.add(1024, () => {
|
||||
D.drawSprite(sprThrallLore, new Point(192, 192), 1, {
|
||||
xScale: this.faceLeft ? -2 : 2,
|
||||
yScale: 2,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
#drawBadges(globalOffset: Point) {
|
||||
|
120
src/pickups.ts
120
src/pickups.ts
@ -6,16 +6,24 @@ import { generateMap } from "./mapgen.ts";
|
||||
import { ALL_STATS, Stat } from "./datatypes.ts";
|
||||
import { D } from "./engine/public.ts";
|
||||
import {
|
||||
sprCollectibles,
|
||||
sprCollectiblesSilhouettes,
|
||||
sprLadder,
|
||||
sprLock,
|
||||
sprResourcePickup,
|
||||
sprStatPickup,
|
||||
} from "./sprites.ts";
|
||||
import { GridArt } from "./gridart.ts";
|
||||
import { getCheckModal } from "./checkmodal.ts";
|
||||
import { Point, Size } from "./engine/datatypes.ts";
|
||||
import { choose } from "./utils.ts";
|
||||
import { FG_TEXT } from "./colors.ts";
|
||||
import {
|
||||
BG_CEILING,
|
||||
FG_BOLD,
|
||||
FG_TEXT,
|
||||
SWATCH_EXP,
|
||||
SWATCH_STAT,
|
||||
} from "./colors.ts";
|
||||
import { Block3D } from "./world3d.ts";
|
||||
import { DrawPile } from "./drawpile.ts";
|
||||
|
||||
export type Pickup =
|
||||
| LockPickup
|
||||
@ -52,14 +60,19 @@ export class LockPickup {
|
||||
return true;
|
||||
}
|
||||
|
||||
drawFloor() {}
|
||||
drawInAir(gridArt: GridArt) {
|
||||
draw(drawpile: DrawPile, gridArt: GridArt) {
|
||||
drawpile.add(0, () => {
|
||||
for (let z = 0; z < 5; z += 0.25) {
|
||||
D.drawSprite(sprLock, gridArt.project(z), 0, {
|
||||
xScale: 2.0,
|
||||
yScale: 2.0,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getBlock(): Block3D | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
update() {}
|
||||
@ -102,9 +115,13 @@ export class BreakableBlockPickup {
|
||||
return true;
|
||||
}
|
||||
|
||||
drawFloor() {}
|
||||
drawInAir(gridArt: GridArt) {
|
||||
let progress = Math.pow(this.breakProgress, 2.15);
|
||||
get #adjustedProgress(): number {
|
||||
return Math.pow(this.breakProgress, 2.15);
|
||||
}
|
||||
|
||||
draw(drawpile: DrawPile, gridArt: GridArt) {
|
||||
drawpile.add(384, () => {
|
||||
let progress = this.#adjustedProgress;
|
||||
let extraMult = 1.0;
|
||||
let angleRange = 0;
|
||||
if (progress != 0) {
|
||||
@ -112,11 +129,16 @@ export class BreakableBlockPickup {
|
||||
angleRange = 10;
|
||||
}
|
||||
|
||||
this.callbacks.draw(gridArt.project(5), {
|
||||
this.callbacks.draw(gridArt, {
|
||||
xScale: 2 * (1.0 - progress * 0.7) * extraMult,
|
||||
yScale: 2 * (1.0 - progress * 0.7) * extraMult,
|
||||
angle: (2 * progress - 1) * angleRange,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getBlock(): Block3D | null {
|
||||
return this.callbacks.getBlock(this.breakProgress);
|
||||
}
|
||||
|
||||
update(cellData: CellView) {
|
||||
@ -157,8 +179,16 @@ export class StatPickupCallbacks {
|
||||
getPlayerProgress().purloinItem();
|
||||
}
|
||||
|
||||
getBlock(progress: number) {
|
||||
return new Block3D(
|
||||
progress > 0.6 ? FG_BOLD : SWATCH_STAT[this.#stat][1],
|
||||
progress > 0.6 ? FG_TEXT : SWATCH_STAT[this.#stat][0],
|
||||
progress > 0.6 ? FG_BOLD : SWATCH_STAT[this.#stat][1],
|
||||
);
|
||||
}
|
||||
|
||||
draw(
|
||||
at: Point,
|
||||
gridArt: GridArt,
|
||||
options: { xScale?: number; yScale?: number; angle?: number },
|
||||
) {
|
||||
let statIndex = ALL_STATS.indexOf(this.#stat);
|
||||
@ -166,7 +196,8 @@ export class StatPickupCallbacks {
|
||||
return;
|
||||
}
|
||||
|
||||
D.drawSprite(sprStatPickup, at, statIndex, options);
|
||||
let at = gridArt.project(100);
|
||||
D.drawSprite(sprCollectiblesSilhouettes, at, statIndex, options);
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,11 +213,20 @@ export class ExperiencePickupCallbacks {
|
||||
getPlayerProgress().purloinItem();
|
||||
}
|
||||
|
||||
getBlock(progress: number) {
|
||||
return new Block3D(
|
||||
progress > 0.6 ? FG_BOLD : SWATCH_EXP[1],
|
||||
progress > 0.6 ? FG_TEXT : SWATCH_EXP[0],
|
||||
progress > 0.6 ? FG_BOLD : SWATCH_EXP[1],
|
||||
);
|
||||
}
|
||||
|
||||
draw(
|
||||
at: Point,
|
||||
gridArt: GridArt,
|
||||
options: { xScale?: number; yScale?: number; angle?: number },
|
||||
) {
|
||||
D.drawSprite(sprResourcePickup, at, 0, options);
|
||||
let at = gridArt.project(100);
|
||||
D.drawSprite(sprCollectiblesSilhouettes, at, 0, options);
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,13 +251,18 @@ export class LadderPickup {
|
||||
return false;
|
||||
}
|
||||
|
||||
drawFloor(gridArt: GridArt) {
|
||||
draw(drawpile: DrawPile, gridArt: GridArt) {
|
||||
drawpile.add(-128, () => {
|
||||
D.drawSprite(sprLadder, gridArt.project(0.0), 0, {
|
||||
xScale: 2.0,
|
||||
yScale: 2.0,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getBlock(): Block3D | null {
|
||||
return null;
|
||||
}
|
||||
drawInAir() {}
|
||||
|
||||
update() {}
|
||||
|
||||
@ -257,13 +302,18 @@ export class ThrallPickup {
|
||||
return false;
|
||||
}
|
||||
|
||||
drawFloor() {}
|
||||
drawInAir(gridArt: GridArt) {
|
||||
draw(drawpile: DrawPile, gridArt: GridArt) {
|
||||
drawpile.add(0, () => {
|
||||
let data = getThralls().get(this.thrall);
|
||||
D.drawSprite(data.sprite, gridArt.project(0.0), 0, {
|
||||
xScale: 2.0,
|
||||
yScale: 2.0,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getBlock(): Block3D | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
update() {}
|
||||
@ -307,13 +357,18 @@ export class ThrallPosterPickup {
|
||||
return false;
|
||||
}
|
||||
|
||||
drawFloor() {}
|
||||
drawInAir(gridArt: GridArt) {
|
||||
draw(drawpile: DrawPile, gridArt: GridArt) {
|
||||
drawpile.add(0, () => {
|
||||
let data = getThralls().get(this.thrall);
|
||||
D.drawSprite(data.sprite, gridArt.project(0.0), 2, {
|
||||
xScale: 2.0,
|
||||
yScale: 2.0,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getBlock(): Block3D | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
update() {}
|
||||
@ -358,8 +413,8 @@ export class ThrallRecruitedPickup {
|
||||
return false;
|
||||
}
|
||||
|
||||
drawFloor() {}
|
||||
drawInAir(gridArt: GridArt) {
|
||||
draw(drawpile: DrawPile, gridArt: GridArt) {
|
||||
drawpile.add(0, () => {
|
||||
let data = getThralls().get(this.thrall);
|
||||
let lifeStage = getPlayerProgress().getThrallLifeStage(this.thrall);
|
||||
let ix = 0;
|
||||
@ -377,6 +432,11 @@ export class ThrallRecruitedPickup {
|
||||
yScale: 2.0,
|
||||
angle: rot,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getBlock(): Block3D | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
update() {}
|
||||
@ -477,8 +537,8 @@ export class ThrallCollectionPlatePickup {
|
||||
return false;
|
||||
}
|
||||
|
||||
drawFloor() {}
|
||||
drawInAir(gridArt: GridArt) {
|
||||
draw(drawpile: DrawPile, gridArt: GridArt) {
|
||||
drawpile.add(0, () => {
|
||||
let itemStage = getPlayerProgress().getThrallItemStage(this.thrall);
|
||||
let data = getThralls().get(this.thrall);
|
||||
|
||||
@ -494,6 +554,11 @@ export class ThrallCollectionPlatePickup {
|
||||
yScale: 2.0,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getBlock(): Block3D | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
update() {}
|
||||
@ -585,14 +650,19 @@ export class ThrallItemPickup {
|
||||
return false;
|
||||
}
|
||||
|
||||
drawFloor() {}
|
||||
drawInAir(gridArt: GridArt) {
|
||||
draw(drawpile: DrawPile, gridArt: GridArt) {
|
||||
drawpile.add(0, () => {
|
||||
let data = getThralls().get(this.thrall);
|
||||
|
||||
D.drawSprite(data.sprite, gridArt.project(2), 3, {
|
||||
xScale: 2.0,
|
||||
yScale: 2.0,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getBlock(): Block3D | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
update() {}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Sprite } from "./engine/internal/sprite.ts";
|
||||
|
||||
import imgResourcePickup from "./art/pickups/resources.png";
|
||||
import imgStatPickup from "./art/pickups/stats.png";
|
||||
import imgCollectibles from "./art/pickups/collectibles.png";
|
||||
import imgCollectiblesSilhouettes from "./art/pickups/collectibles_silhouettes.png";
|
||||
import imgLadder from "./art/pickups/ladder.png";
|
||||
import imgLock from "./art/pickups/lock.png";
|
||||
import { Point, Size } from "./engine/datatypes.ts";
|
||||
@ -13,20 +13,20 @@ import imgThrallParty from "./art/thralls/thrall_party.png";
|
||||
import imgThrallStare from "./art/thralls/thrall_stare.png";
|
||||
import imgThrallStealth from "./art/thralls/thrall_stealth.png";
|
||||
|
||||
export let sprResourcePickup = new Sprite(
|
||||
imgResourcePickup,
|
||||
export let sprCollectibles = new Sprite(
|
||||
imgCollectibles,
|
||||
new Size(32, 32),
|
||||
new Point(16, 16),
|
||||
new Size(1, 1),
|
||||
1,
|
||||
new Size(5, 1),
|
||||
5,
|
||||
);
|
||||
|
||||
export let sprStatPickup = new Sprite(
|
||||
imgStatPickup,
|
||||
export let sprCollectiblesSilhouettes = new Sprite(
|
||||
imgCollectiblesSilhouettes,
|
||||
new Size(32, 32),
|
||||
new Point(16, 16),
|
||||
new Size(4, 1),
|
||||
4,
|
||||
new Size(5, 1),
|
||||
5,
|
||||
);
|
||||
|
||||
export let sprLadder = new Sprite(
|
||||
|
140
src/world3d.ts
Normal file
140
src/world3d.ts
Normal file
@ -0,0 +1,140 @@
|
||||
import { Color, Grid, Point, Rect, Size } from "./engine/datatypes.ts";
|
||||
import { DrawPile } from "./drawpile.ts";
|
||||
import { GridArt } from "./gridart.ts";
|
||||
import {
|
||||
BG_CEILING,
|
||||
BG_WALL_OR_UNREVEALED,
|
||||
FG_BOLD,
|
||||
FG_TEXT,
|
||||
} from "./colors.ts";
|
||||
|
||||
export class World3D {
|
||||
#grid: Grid<Element3D>;
|
||||
|
||||
constructor(size: Size) {
|
||||
this.#grid = new Grid<Element3D>(size, () => null);
|
||||
}
|
||||
|
||||
set(at: Point, value: Element3D) {
|
||||
this.#grid.set(at, value);
|
||||
}
|
||||
|
||||
drawCell(drawpile: DrawPile, gridArt: GridArt, xy: Point) {
|
||||
const OFFSET_AIR = 0;
|
||||
const OFFSET_TOP = 256;
|
||||
const OFFSET_TOP_OF_TOP = 512;
|
||||
let here = this.#grid.get(xy);
|
||||
|
||||
if (here == null) {
|
||||
drawpile.add(OFFSET_TOP, () => {
|
||||
gridArt.drawCeiling(BG_CEILING);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const getRevealedBlock = (dx: number, dy: number): Block3D | null => {
|
||||
let xy2 = xy.offset(new Point(dx, dy));
|
||||
if (!new Rect(new Point(0, 0), this.#grid.size).contains(xy2)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let other = this.#grid.get(xy.offset(new Point(dx, dy)));
|
||||
if (other instanceof Block3D) {
|
||||
return other;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
let center = getRevealedBlock(0, 0);
|
||||
if (center) {
|
||||
drawpile.add(OFFSET_TOP, () => {
|
||||
gridArt.drawCeiling(center.ceiling);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let west = getRevealedBlock(-1, 0);
|
||||
let east = getRevealedBlock(1, 0);
|
||||
let north = getRevealedBlock(0, -1);
|
||||
let south = getRevealedBlock(0, 1);
|
||||
|
||||
if (north && west) {
|
||||
drawpile.add(OFFSET_TOP_OF_TOP, () => {
|
||||
gridArt.drawMouldingTopLeft(north.moulding);
|
||||
});
|
||||
}
|
||||
if (north) {
|
||||
drawpile.add(OFFSET_AIR, () => {
|
||||
gridArt.drawWallTop(north.dark);
|
||||
});
|
||||
drawpile.add(OFFSET_TOP_OF_TOP, () => {
|
||||
gridArt.drawMouldingTop(north.moulding);
|
||||
});
|
||||
}
|
||||
if (north && east) {
|
||||
drawpile.add(OFFSET_TOP_OF_TOP, () => {
|
||||
gridArt.drawMouldingTopRight(north.moulding);
|
||||
});
|
||||
}
|
||||
if (west) {
|
||||
drawpile.add(OFFSET_AIR, () => {
|
||||
gridArt.drawWallLeft(west.dark);
|
||||
});
|
||||
drawpile.add(OFFSET_TOP_OF_TOP, () => {
|
||||
gridArt.drawMouldingLeft(west.moulding);
|
||||
});
|
||||
}
|
||||
if (south && west) {
|
||||
drawpile.add(OFFSET_TOP_OF_TOP, () => {
|
||||
gridArt.drawMouldingBottomLeft(south.moulding);
|
||||
});
|
||||
}
|
||||
if (south) {
|
||||
drawpile.add(OFFSET_AIR, () => {
|
||||
gridArt.drawWallBottom(south.bright);
|
||||
});
|
||||
drawpile.add(OFFSET_TOP_OF_TOP, () => {
|
||||
gridArt.drawMouldingBottom(south.moulding);
|
||||
});
|
||||
}
|
||||
if (south && east) {
|
||||
drawpile.add(OFFSET_TOP_OF_TOP, () => {
|
||||
gridArt.drawMouldingBottomRight(south.moulding);
|
||||
});
|
||||
}
|
||||
if (east) {
|
||||
drawpile.add(OFFSET_AIR, () => {
|
||||
gridArt.drawWallRight(east.bright);
|
||||
});
|
||||
drawpile.add(OFFSET_TOP_OF_TOP, () => {
|
||||
gridArt.drawMouldingRight(east.moulding);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type Element3D = Floor3D | Block3D | null;
|
||||
|
||||
export class Floor3D {
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
export class Block3D {
|
||||
readonly bright: Color;
|
||||
readonly dark: Color;
|
||||
readonly ceiling: Color;
|
||||
|
||||
get moulding(): Color {
|
||||
return this.dark;
|
||||
}
|
||||
|
||||
constructor(bright: Color, dark: Color, ceiling: Color) {
|
||||
this.bright = bright;
|
||||
this.dark = dark;
|
||||
this.ceiling = ceiling;
|
||||
}
|
||||
|
||||
static standardWall(): Block3D {
|
||||
return new Block3D(FG_BOLD, FG_TEXT, BG_WALL_OR_UNREVEALED);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user