fantasy-console/maptab.ts

161 lines
5.5 KiB
TypeScript
Raw Normal View History

2023-05-09 19:42:02 -07:00
import { clearScreen, fillRect } from "./window.ts";
import { drawSprite, drawText } from "./builtins.ts";
import { COLOR } from "./colors.ts";
import { getMapSheet, getSheet, getSpriteSheet, setSheet } from "./sheet.ts";
import { mouseHeld, mousePos } from "./mouse.ts";
import { inRect, reGrid } from "./util.ts";
import { page } from "./viewsheets.ts";
import { useSpritesheet } from "./builtins.ts";
const state = {
selectedSpriteSheet: 2,
selectedSprite: 0,
selectedPatch: 0,
get map() {
return getMapSheet(page.activeSheet);
},
set map(val) {
setSheet(page.activeSheet, "map", val);
},
setInPatch(i: number, sprsheet: number, sprite: number) {
const xx = this.selectedPatch%overviewW;
const yy = Math.floor(this.selectedPatch/overviewW);
const cell = (yy+patchH*Math.floor(i/patchW))*overviewW*patchW+xx*patchW+i%patchW;
this.map[cell] = [sprsheet, sprite];
},
get patch() {
const xx = this.selectedPatch%overviewW;
const yy = Math.floor(this.selectedPatch/overviewW);
return Array(overviewH).fill(0).flatMap((_, i) => {
const start = (yy+patchH*i)*overviewW*patchW+xx*patchW;
return this.map.slice(start, start+patchW);
})
}
}
const overviewX = 88;
const overviewY = 12;
const miniPatchW = 4;
const miniPatchH = 4;
const overviewW = 8;
const overviewH = 8;
const patchX = 8;
const patchY = 12;
const patchW = 8;
const patchH = 8;
const spriteW = 8;
const spriteH = 8;
const spriteSheetX = 0;
const spriteSheetY = 88;
const spriteSheetW = 16;
const spriteSheetH = 4;
const spriteSheetPickerX = 0;
const spriteSheetPickerY = 79;
const spriteSheetPickerW = 16;
const spriteSheetPickerH = 1;
const spriteSheetPickerTabW = 8;
const spriteSheetPickerTabH = 8;
const update = () => {
if (mouseHeld()) {
const {x: mouseX, y: mouseY} = mousePos();
const inOverview = inRect(mouseX, mouseY, overviewX, overviewY, overviewW*miniPatchW, overviewH*miniPatchH);
const inPatch = inRect(mouseX, mouseY, patchX, patchY, patchW*spriteW, patchH*spriteH);
const inSpriteSheetPicker = inRect(mouseX, mouseY, spriteSheetPickerX, spriteSheetPickerY, spriteSheetPickerW*spriteSheetPickerTabW, spriteSheetPickerH*spriteSheetPickerTabH);
const inSpriteSheet = inRect(mouseX, mouseY, spriteSheetX, spriteSheetY, spriteSheetW*spriteW, spriteSheetH*spriteH);
if (inOverview) {
const {x, y} = reGrid(mouseX, mouseY, overviewX, overviewY, miniPatchW, miniPatchH);
state.selectedPatch = overviewW*y+x;
}
if (inPatch) {
const {x, y} = reGrid(mouseX, mouseY, patchX, patchY, spriteW, spriteH);
const cellNumber = spriteW*y+x;
state.setInPatch(cellNumber, state.selectedSpriteSheet, state.selectedSprite);
}
if (inSpriteSheetPicker) {
const {x, y} = reGrid(mouseX, mouseY, spriteSheetPickerX, spriteSheetPickerY, spriteSheetPickerTabW, spriteSheetPickerTabH);
state.selectedSpriteSheet = spriteSheetPickerW*y+x;
}
if (inSpriteSheet) {
const {x, y} = reGrid(mouseX, mouseY, spriteSheetX, spriteSheetY, spriteW, spriteH);
state.selectedSprite = spriteSheetW*y+x;
}
}
}
const outlineRect = (x: number, y: number, w: number, h: number, color: number) => {
fillRect(x, y, w, 1, color);
fillRect(x, y, 1, h, color);
fillRect(x+w-1, y, 1, h, color);
fillRect(x, y+h-1, w, 1, color);
}
const draw = () => {
const {
selectedSpriteSheet,
selectedSprite,
selectedPatch
} = state;
clearScreen();
fillRect(0, 8, 128, 112, COLOR.DARKGRAY);
// Draw the overview
fillRect(overviewX-1, overviewY-1, (overviewW*miniPatchW)+2, (overviewH*miniPatchH)+2, COLOR.BLACK);
Array(overviewW*overviewH).fill(0).forEach((_, i) => {
const miniPatchX = overviewX+miniPatchW*(i%overviewW);
const miniPatchY = overviewY+miniPatchH*Math.floor(i/overviewW);
if (i === selectedPatch) {
outlineRect(miniPatchX, miniPatchY, miniPatchW, miniPatchH, COLOR.WHITE);
}
});
// Draw the current patch
fillRect(patchX-1, patchY-1, (patchW*spriteW)+2, (patchH*spriteH)+2, COLOR.BLACK);
state.patch.forEach(([sprsheet, sprite], i) => {
const spriteX = patchX+spriteW*(i%patchW);
const spriteY = patchY+spriteH*Math.floor(i/patchW);
if (getSheet(sprsheet).sheet_type === "spritesheet") {
useSpritesheet(sprsheet);
drawSprite(spriteX, spriteY, sprite);
}
});
// Draw the spritesheet picker
fillRect(spriteSheetPickerX, spriteSheetPickerY, spriteSheetPickerTabW*spriteSheetPickerW, spriteSheetPickerTabW, COLOR.BLACK);
Array(spriteSheetPickerW*spriteSheetPickerH).fill(0).forEach((_, i) => {
const tabX = spriteSheetPickerX+spriteSheetPickerTabW*(i%spriteSheetPickerW);
const tabY = spriteSheetPickerY+spriteSheetPickerTabH*Math.floor(i/spriteSheetPickerW);
let color = COLOR.DARKGREEN;
if (getSheet(i).sheet_type !== "spritesheet") {
color = COLOR.BROWN;
}
if (i === selectedSpriteSheet) {
color = color === COLOR.BROWN ? COLOR.TAN : COLOR.GREEN;
}
fillRect(tabX, tabY, spriteSheetPickerTabW, spriteSheetPickerTabH, color);
drawText(tabX+2, tabY+1, ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"][i]);
});
// Draw the spritesheet
fillRect(spriteSheetX, spriteSheetY-1, (spriteSheetW*spriteW), (spriteSheetH*spriteH)+1, COLOR.BLACK);
if (getSheet(selectedSpriteSheet).sheet_type === "spritesheet") {
useSpritesheet(selectedSpriteSheet);
getSpriteSheet(selectedSpriteSheet).forEach((_sprite, i) => {
const sprX = spriteSheetX+spriteW*(i%spriteSheetW);
const sprY = spriteSheetY+spriteH*Math.floor(i/spriteSheetW);
drawSprite(sprX, sprY, i);
if (i === selectedSprite) {
outlineRect(sprX, sprY, spriteW, spriteH, COLOR.WHITE);
}
});
}
}
export const maptab = {
update,
draw,
}