From 694eb006b9972bf8b298854084e3f10ce9e72cda Mon Sep 17 00:00:00 2001 From: dylan <> Date: Sat, 13 May 2023 12:15:59 -0700 Subject: [PATCH] Make map editor more like pico 8 --- maptab.ts | 93 +++++++++++++++++++++++++------------------------------ util.ts | 23 ++++++++++++-- 2 files changed, 63 insertions(+), 53 deletions(-) diff --git a/maptab.ts b/maptab.ts index 43ec71a..b423050 100644 --- a/maptab.ts +++ b/maptab.ts @@ -3,14 +3,17 @@ import { drawSprite, drawText } from "./builtins.ts"; import { COLOR } from "./colors.ts"; import { getMapSheet, getSheet, setSheet } from "./sheet.ts"; import { mouseClick, mouseHeld, mousePos } from "./mouse.ts"; -import { inRect, reGrid } from "./util.ts"; +import { drawTransparentRect, drawVoidRect, inRect, reGrid } from "./util.ts"; import { page } from "./viewsheets.ts"; import { useSpritesheet } from "./builtins.ts"; +import { keyPressed } from "./keyboard.ts"; +import { K } from "./keyboard.ts"; const state = { selectedSpriteSheet: 0, selectedSprite: 0, - selectedPatch: 0, + viewX: 0, + viewY: 0, get spriteSheetPage() { return Math.floor(this.selectedSprite/64); }, @@ -30,36 +33,21 @@ const state = { setSheet(page.activeSheet, "map", val); }, setInPatch(i: number, sprsheet: number, sprite: number) { - const xx = patchW*(this.selectedPatch%overviewW); - const yy = patchH*Math.floor(this.selectedPatch/overviewW); - const cellVal = this.map.subgrid(xx, yy, patchW, patchH).values[i]; - cellVal[0] = sprsheet - cellVal[1] = sprite; - // const cell = (yy*patchH+Math.floor(i/patchW))*overviewW*patchW+xx*patchW+i%patchW; - // this.map[cell] = [sprsheet, sprite]; + const cellVal = this.map.subgrid(this.viewX, this.viewY, patchW, patchH).values[i]; + if (cellVal) { + cellVal[0] = sprsheet + cellVal[1] = sprite; + } }, get patch() { - const xx = patchW*(this.selectedPatch%overviewW); - const yy = patchH*Math.floor(this.selectedPatch/overviewW); - return this.map.subgrid(xx, yy, patchW, patchH); - // return Array(overviewH).fill(0).flatMap((_, i) => { - // const start = (yy*patchH+i)*overviewW*patchW+xx*patchW; - // return this.map.slice(start, start+patchW); - // }) + return this.map.subgrid(this.viewX, this.viewY, patchW, patchH); } } -const overviewX = 88; -const overviewY = 12; -const miniPatchW = 4; -const miniPatchH = 4; -const overviewW = 8; -const overviewH = 8; - -const patchX = 4; -const patchY = 12; -const patchW = 8; -const patchH = 8; +const patchX = 0; +const patchY = 8; +const patchW = 16; +const patchH = 9; const spriteW = 8; const spriteH = 8; @@ -70,31 +58,26 @@ const spriteSheetW = 16; const spriteSheetH = 4; const spriteSheetPickerX = 0; -const spriteSheetPickerY = 80; +const spriteSheetPickerY = 81; const spriteSheetPickerW = 16; const spriteSheetPickerH = 1; const spriteSheetPickerTabW = 7; const spriteSheetPickerTabH = 7; const spriteSheetPageSwapX = 121; -const spriteSheetPageSwapY = 80; +const spriteSheetPageSwapY = 81; const spriteSheetPageSwapW = 7; const spriteSheetPageSwapH = 7; 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 inPatch = inRect(mouseX, mouseY, patchX, patchY, patchW*spriteW, patchH*spriteH - 2); 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; + const cellNumber = patchW*y+x; state.setInPatch(cellNumber, state.selectedSpriteSheet, state.selectedSprite); } if (inSpriteSheetPicker) { @@ -112,6 +95,18 @@ const update = () => { state.spriteSheetPage = (1+state.spriteSheetPage)%2; } } + if (keyPressed(K.ARROW_RIGHT)) { + state.viewX += 1; + } + if (keyPressed(K.ARROW_LEFT)) { + state.viewX -= 1; + } + if (keyPressed(K.ARROW_UP)) { + state.viewY -= 1; + } + if (keyPressed(K.ARROW_DOWN)) { + state.viewY += 1; + } } const outlineRect = (x: number, y: number, w: number, h: number, color: number) => { @@ -126,32 +121,30 @@ const draw = () => { selectedSpriteSheet, spriteWithinPage, spriteSheetPage, - 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.values.forEach(([sprsheet, sprite], i) => { + drawVoidRect(patchX-1, patchY-1, (patchW*spriteW)+2, (patchH*spriteH)+2); + state.patch.values.forEach((val, i) => { const spriteX = patchX+spriteW*(i%patchW); const spriteY = patchY+spriteH*Math.floor(i/patchW); + if (!val) { + return; + } + const [sprsheet, sprite] = val; + drawTransparentRect(spriteX, spriteY, 8, 8); if (getSheet(sprsheet).sheet_type === "spritesheet") { useSpritesheet(sprsheet); drawSprite(spriteX, spriteY, sprite); } }); + // Draw the bar + fillRect(spriteSheetPickerX, spriteSheetPickerY-1, 128, 1, COLOR.BLACK); + fillRect(spriteSheetPickerX, spriteSheetPickerY, 128, 7, COLOR.DARKGRAY); + // Draw the spritesheet picker fillRect(spriteSheetPickerX, spriteSheetPickerY, spriteSheetPickerTabW*spriteSheetPickerW, spriteSheetPickerTabW, COLOR.BLACK); Array(spriteSheetPickerW*spriteSheetPickerH).fill(0).forEach((_, i) => { @@ -180,7 +173,7 @@ const draw = () => { drawText(spriteSheetPageSwapX+2, spriteSheetPageSwapY+1, state.spriteSheetPage.toString()); // Draw the spritesheet - fillRect(spriteSheetX, spriteSheetY-1, (spriteSheetW*spriteW), (spriteSheetH*spriteH)+1, COLOR.BLACK); + fillRect(spriteSheetX, spriteSheetY, (spriteSheetW*spriteW), (spriteSheetH*spriteH), COLOR.BLACK); if (getSheet(selectedSpriteSheet).sheet_type === "spritesheet") { useSpritesheet(selectedSpriteSheet); Array(64).fill(0).forEach((_, i) => { diff --git a/util.ts b/util.ts index 929117b..1b5043a 100644 --- a/util.ts +++ b/util.ts @@ -46,10 +46,27 @@ export const drawTransparentRect = (x: number, y: number, w: number, h: number) }) } -export const subgrid = (array: Array, gridW: number, x: number, y: number, w: number, h: number): Array => { +export const drawVoidRect = (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.DARKERBLUE); + }) +} + +export const subgrid = (array: Array, gridW: number, x: number, y: number, w: number, h: number): Array => { return Array(h).fill(0).flatMap((_, i) => { - const start = (y+i)*gridW+x; - return array.slice(start, start+w); + if (y+i < 0 || y+i > array.length/gridW) { + return Array(w).fill(undefined); + } + const x0 = Math.max(0, x); + const x1 = Math.min(x+w, gridW); + const start = (y+i)*gridW+x0; + const end = (y+i)*gridW+x1; + const before = Array(x0 - x).fill(undefined); + const after = Array((x+w) - x1).fill(undefined); + const middle = array.slice(start, end); + return [...before, ...middle, ...after]; }) }