150 lines
4.8 KiB
TypeScript
150 lines
4.8 KiB
TypeScript
import { clearScreen, fillRect, setPixelColor } from "./window.ts";
|
|
import { drawSprite, drawText } from "./builtins.ts";
|
|
import { COLOR } from "./colors.ts";
|
|
import { getSpriteSheet, setSheet } from "./sheet.ts";
|
|
import { mouseClick, mouseHeld, mousePos } from "./mouse.ts";
|
|
import { inRect, reGrid } from "./util.ts";
|
|
import { page } from "./viewsheets.ts";
|
|
import { useSpritesheet } from "./builtins.ts";
|
|
|
|
const state = {
|
|
selectedSprite: 0,
|
|
selectedColor: 0,
|
|
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;
|
|
},
|
|
get sprites() {
|
|
return getSpriteSheet(page.activeSheet);
|
|
},
|
|
set sprites(val) {
|
|
setSheet(page.activeSheet, "spritesheet", val);
|
|
}
|
|
}
|
|
|
|
const paletteX = 88;
|
|
const paletteY = 16;
|
|
const swatchW = 8;
|
|
const swatchH = 8;
|
|
const paletteW = 4;
|
|
const paletteH = 6;
|
|
|
|
const spriteX = 8;
|
|
const spriteY = 16;
|
|
const pixelW = 8;
|
|
const pixelH = 8;
|
|
|
|
const spriteW = 8;
|
|
const spriteH = 8;
|
|
|
|
const sheetX = 0;
|
|
const sheetY = 88;
|
|
const sheetW = 16;
|
|
const sheetH = 4;
|
|
|
|
const spriteSheetPageSwapX = 121;
|
|
const spriteSheetPageSwapY = 80;
|
|
const spriteSheetPageSwapW = 7;
|
|
const spriteSheetPageSwapH = 7;
|
|
|
|
const update = () => {
|
|
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);
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
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 drawTransparentRect = (x: number, y: number, w: number, h: number) => {
|
|
Array(w*h).fill(0).map((_z, j) => {
|
|
const jx = j%w;
|
|
const jy = Math.floor(j/w);
|
|
setPixelColor(x+jx, y+jy, (jx+jy)%2 ? COLOR.BLACK : COLOR.DARKGRAY);
|
|
})
|
|
}
|
|
|
|
const draw = () => {
|
|
const {sprites, selectedSprite, selectedColor} = state;
|
|
clearScreen();
|
|
useSpritesheet(page.activeSheet);
|
|
fillRect(0, 8, 128, 112, COLOR.DARKGRAY);
|
|
|
|
// Draw the palette
|
|
fillRect(paletteX-1, paletteY-1, (paletteW*swatchW)+2, (paletteH*swatchH)+2, COLOR.BLACK);
|
|
Object.keys(COLOR).forEach((name, i) => {
|
|
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]);
|
|
if (name == "TRANSPARENT") {
|
|
// transparent
|
|
drawTransparentRect(swatchX, swatchY, swatchW, swatchH);
|
|
}
|
|
if (i === selectedColor) {
|
|
outlineRect(swatchX, swatchY, swatchW, swatchH, name === "WHITE" ? COLOR.BLACK : COLOR.WHITE);
|
|
}
|
|
});
|
|
|
|
// Draw the current sprite
|
|
fillRect(spriteX-1, spriteY-1, (spriteW*pixelW)+2, (spriteH*pixelH)+2, COLOR.BLACK);
|
|
drawTransparentRect(spriteX, spriteY, (spriteW*pixelW), (spriteH*pixelH));
|
|
sprites[selectedSprite].forEach((pix, i) => {
|
|
fillRect(spriteX+pixelW*(i%spriteW), spriteY+pixelH*Math.floor(i/spriteW), pixelW, pixelH, pix);
|
|
});
|
|
|
|
// Draw the spritesheet page swap button
|
|
fillRect(spriteSheetPageSwapX, spriteSheetPageSwapY, spriteSheetPageSwapW, spriteSheetPageSwapH, COLOR.BLUE);
|
|
drawText(spriteSheetPageSwapX+2, spriteSheetPageSwapY+1, state.spriteSheetPage.toString());
|
|
|
|
// Draw the spritesheet
|
|
fillRect(sheetX, sheetY-1, (sheetW*spriteW), (sheetH*spriteH)+1, COLOR.BLACK);
|
|
Array(64).fill(0).forEach((_, i) => {
|
|
const sprI = i+64*state.spriteSheetPage;
|
|
const sprX = sheetX+spriteW*(i%sheetW);
|
|
const sprY = sheetY+spriteH*Math.floor(i/sheetW);
|
|
console.log(sprI, getSpriteSheet(page.activeSheet).length);
|
|
drawSprite(sprX, sprY, sprI);
|
|
if (i === state.spriteWithinPage) {
|
|
outlineRect(sprX, sprY, spriteW, spriteH, COLOR.WHITE);
|
|
}
|
|
});
|
|
}
|
|
|
|
export const spritetab = {
|
|
update,
|
|
draw,
|
|
} |