fantasy-console/editor/spritetab.ts

133 lines
4.3 KiB
TypeScript
Raw Permalink Normal View History

2023-05-18 19:45:49 -07:00
import { clearScreen, fillRect } from "../io/window.ts";
import { drawSprite, drawText, useSpritesheet } from "../runtime/builtins.ts";
import { COLOR } from "../data/colors.ts";
import { getSpriteSheet, setSheet } from "../io/sheet.ts";
import { mouseClick, mouseHeld, mousePos } from "../io/mouse.ts";
import { drawTransparentRect, inRect, outlineRect, reGrid } from "../util/util.ts";
2023-05-06 14:49:46 -07:00
import { page } from "./viewsheets.ts";
2023-05-05 14:59:52 -07:00
const state = {
2023-05-05 16:02:23 -07:00
selectedSprite: 0,
selectedColor: 0,
2023-05-09 20:29:25 -07:00
get spriteSheetPage() {
return Math.floor(this.selectedSprite/64);
},
set spriteSheetPage(val) {
this.selectedSprite = 64*val+this.spriteWithinPage;
},
get spriteWithinPage() {
return this.selectedSprite%64;
},
set spriteWithinPage(val) {
this.selectedSprite = 64*this.spriteSheetPage+val;
},
2023-05-05 14:59:52 -07:00
get sprites() {
2023-05-06 14:49:46 -07:00
return getSpriteSheet(page.activeSheet);
2023-05-05 14:59:52 -07:00
},
set sprites(val) {
2023-05-06 14:49:46 -07:00
setSheet(page.activeSheet, "spritesheet", val);
2023-05-05 14:59:52 -07:00
}
}
2023-05-05 16:02:23 -07:00
const paletteX = 88;
2023-05-07 13:58:55 -07:00
const paletteY = 16;
2023-05-05 16:02:23 -07:00
const swatchW = 8;
const swatchH = 8;
const paletteW = 4;
2023-05-07 13:58:55 -07:00
const paletteH = 6;
2023-05-05 16:02:23 -07:00
const spriteX = 8;
2023-05-07 13:58:55 -07:00
const spriteY = 16;
2023-05-05 16:02:23 -07:00
const pixelW = 8;
const pixelH = 8;
const spriteW = 8;
const spriteH = 8;
const sheetX = 0;
const sheetY = 88;
const sheetW = 16;
const sheetH = 4;
2023-05-09 20:29:25 -07:00
const spriteSheetPageSwapX = 121;
const spriteSheetPageSwapY = 80;
const spriteSheetPageSwapW = 7;
const spriteSheetPageSwapH = 7;
2023-05-05 14:59:52 -07:00
const update = () => {
2023-05-05 16:02:23 -07:00
if (mouseHeld()) {
const {x: mouseX, y: mouseY} = mousePos();
const inPalette = inRect(mouseX, mouseY, paletteX, paletteY, paletteW*swatchW, paletteH*swatchH);
const inSprite = inRect(mouseX, mouseY, spriteX, spriteY, spriteW*pixelW, spriteH*pixelH);
const inSheet = inRect(mouseX, mouseY, sheetX, sheetY, sheetW*spriteW, sheetH*spriteH);
if (inPalette) {
const {x, y} = reGrid(mouseX, mouseY, paletteX, paletteY, swatchW, swatchH);
state.selectedColor = paletteW*y+x;
}
if (inSprite) {
const {x, y} = reGrid(mouseX, mouseY, spriteX, spriteY, pixelW, pixelH);
const pixelNumber = spriteW*y+x;
state.sprites[state.selectedSprite][pixelNumber] = state.selectedColor;
}
if (inSheet) {
const {x, y} = reGrid(mouseX, mouseY, sheetX, sheetY, spriteW, spriteH);
2023-05-09 20:29:25 -07:00
state.spriteWithinPage = sheetW*y+x;
}
} else if (mouseClick()) {
const {x: mouseX, y: mouseY} = mousePos();
const inSpriteSheetPageSwap = inRect(mouseX, mouseY, spriteSheetPageSwapX, spriteSheetPageSwapY, spriteSheetPageSwapW, spriteSheetPageSwapH);
if (inSpriteSheetPageSwap) {
state.spriteSheetPage = (1+state.spriteSheetPage)%2;
2023-05-05 16:02:23 -07:00
}
}
2023-05-05 14:59:52 -07:00
}
const draw = () => {
2023-05-05 16:02:23 -07:00
const {sprites, selectedSprite, selectedColor} = state;
2023-05-05 14:59:52 -07:00
clearScreen();
2023-05-06 14:49:46 -07:00
useSpritesheet(page.activeSheet);
2023-05-07 13:58:55 -07:00
fillRect(0, 8, 128, 112, COLOR.DARKGRAY);
2023-05-05 16:02:23 -07:00
2023-05-05 14:59:52 -07:00
// Draw the palette
2023-05-05 16:02:23 -07:00
fillRect(paletteX-1, paletteY-1, (paletteW*swatchW)+2, (paletteH*swatchH)+2, COLOR.BLACK);
2023-05-05 14:59:52 -07:00
Object.keys(COLOR).forEach((name, i) => {
2023-05-05 16:02:23 -07:00
const swatchX = paletteX+swatchW*(i%paletteW);
const swatchY = paletteY+swatchH*Math.floor(i/paletteW);
fillRect(swatchX, swatchY, swatchW, swatchH, COLOR[name as keyof typeof COLOR]);
2023-05-07 13:58:55 -07:00
if (name == "TRANSPARENT") {
2023-05-05 14:59:52 -07:00
// transparent
2023-05-05 16:17:55 -07:00
drawTransparentRect(swatchX, swatchY, swatchW, swatchH);
2023-05-05 14:59:52 -07:00
}
2023-05-05 16:02:23 -07:00
if (i === selectedColor) {
2023-05-07 13:58:55 -07:00
outlineRect(swatchX, swatchY, swatchW, swatchH, name === "WHITE" ? COLOR.BLACK : COLOR.WHITE);
2023-05-05 16:02:23 -07:00
}
2023-05-05 14:59:52 -07:00
});
2023-05-05 16:02:23 -07:00
2023-05-05 14:59:52 -07:00
// Draw the current sprite
2023-05-05 16:02:23 -07:00
fillRect(spriteX-1, spriteY-1, (spriteW*pixelW)+2, (spriteH*pixelH)+2, COLOR.BLACK);
2023-05-05 16:17:55 -07:00
drawTransparentRect(spriteX, spriteY, (spriteW*pixelW), (spriteH*pixelH));
2023-05-05 16:02:23 -07:00
sprites[selectedSprite].forEach((pix, i) => {
fillRect(spriteX+pixelW*(i%spriteW), spriteY+pixelH*Math.floor(i/spriteW), pixelW, pixelH, pix);
2023-05-05 14:59:52 -07:00
});
2023-05-05 16:02:23 -07:00
2023-05-09 20:29:25 -07:00
// Draw the spritesheet page swap button
fillRect(spriteSheetPageSwapX, spriteSheetPageSwapY, spriteSheetPageSwapW, spriteSheetPageSwapH, COLOR.BLUE);
drawText(spriteSheetPageSwapX+2, spriteSheetPageSwapY+1, state.spriteSheetPage.toString());
2023-05-05 14:59:52 -07:00
// Draw the spritesheet
2023-05-05 16:02:23 -07:00
fillRect(sheetX, sheetY-1, (sheetW*spriteW), (sheetH*spriteH)+1, COLOR.BLACK);
2023-05-09 20:29:25 -07:00
Array(64).fill(0).forEach((_, i) => {
const sprI = i+64*state.spriteSheetPage;
2023-05-05 16:17:55 -07:00
const sprX = sheetX+spriteW*(i%sheetW);
const sprY = sheetY+spriteH*Math.floor(i/sheetW);
2023-05-09 20:29:25 -07:00
drawSprite(sprX, sprY, sprI);
if (i === state.spriteWithinPage) {
2023-05-05 16:17:55 -07:00
outlineRect(sprX, sprY, spriteW, spriteH, COLOR.WHITE);
}
2023-05-05 14:59:52 -07:00
});
}
export const spritetab = {
update,
draw,
}