Make map editor more like pico 8
This commit is contained in:
parent
f8c1cebedb
commit
694eb006b9
93
maptab.ts
93
maptab.ts
@ -3,14 +3,17 @@ import { drawSprite, drawText } from "./builtins.ts";
|
|||||||
import { COLOR } from "./colors.ts";
|
import { COLOR } from "./colors.ts";
|
||||||
import { getMapSheet, getSheet, setSheet } from "./sheet.ts";
|
import { getMapSheet, getSheet, setSheet } from "./sheet.ts";
|
||||||
import { mouseClick, mouseHeld, mousePos } from "./mouse.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 { page } from "./viewsheets.ts";
|
||||||
import { useSpritesheet } from "./builtins.ts";
|
import { useSpritesheet } from "./builtins.ts";
|
||||||
|
import { keyPressed } from "./keyboard.ts";
|
||||||
|
import { K } from "./keyboard.ts";
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
selectedSpriteSheet: 0,
|
selectedSpriteSheet: 0,
|
||||||
selectedSprite: 0,
|
selectedSprite: 0,
|
||||||
selectedPatch: 0,
|
viewX: 0,
|
||||||
|
viewY: 0,
|
||||||
get spriteSheetPage() {
|
get spriteSheetPage() {
|
||||||
return Math.floor(this.selectedSprite/64);
|
return Math.floor(this.selectedSprite/64);
|
||||||
},
|
},
|
||||||
@ -30,36 +33,21 @@ const state = {
|
|||||||
setSheet(page.activeSheet, "map", val);
|
setSheet(page.activeSheet, "map", val);
|
||||||
},
|
},
|
||||||
setInPatch(i: number, sprsheet: number, sprite: number) {
|
setInPatch(i: number, sprsheet: number, sprite: number) {
|
||||||
const xx = patchW*(this.selectedPatch%overviewW);
|
const cellVal = this.map.subgrid(this.viewX, this.viewY, patchW, patchH).values[i];
|
||||||
const yy = patchH*Math.floor(this.selectedPatch/overviewW);
|
if (cellVal) {
|
||||||
const cellVal = this.map.subgrid(xx, yy, patchW, patchH).values[i];
|
cellVal[0] = sprsheet
|
||||||
cellVal[0] = sprsheet
|
cellVal[1] = sprite;
|
||||||
cellVal[1] = sprite;
|
}
|
||||||
// const cell = (yy*patchH+Math.floor(i/patchW))*overviewW*patchW+xx*patchW+i%patchW;
|
|
||||||
// this.map[cell] = [sprsheet, sprite];
|
|
||||||
},
|
},
|
||||||
get patch() {
|
get patch() {
|
||||||
const xx = patchW*(this.selectedPatch%overviewW);
|
return this.map.subgrid(this.viewX, this.viewY, patchW, patchH);
|
||||||
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);
|
|
||||||
// })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const overviewX = 88;
|
const patchX = 0;
|
||||||
const overviewY = 12;
|
const patchY = 8;
|
||||||
const miniPatchW = 4;
|
const patchW = 16;
|
||||||
const miniPatchH = 4;
|
const patchH = 9;
|
||||||
const overviewW = 8;
|
|
||||||
const overviewH = 8;
|
|
||||||
|
|
||||||
const patchX = 4;
|
|
||||||
const patchY = 12;
|
|
||||||
const patchW = 8;
|
|
||||||
const patchH = 8;
|
|
||||||
|
|
||||||
const spriteW = 8;
|
const spriteW = 8;
|
||||||
const spriteH = 8;
|
const spriteH = 8;
|
||||||
@ -70,31 +58,26 @@ const spriteSheetW = 16;
|
|||||||
const spriteSheetH = 4;
|
const spriteSheetH = 4;
|
||||||
|
|
||||||
const spriteSheetPickerX = 0;
|
const spriteSheetPickerX = 0;
|
||||||
const spriteSheetPickerY = 80;
|
const spriteSheetPickerY = 81;
|
||||||
const spriteSheetPickerW = 16;
|
const spriteSheetPickerW = 16;
|
||||||
const spriteSheetPickerH = 1;
|
const spriteSheetPickerH = 1;
|
||||||
const spriteSheetPickerTabW = 7;
|
const spriteSheetPickerTabW = 7;
|
||||||
const spriteSheetPickerTabH = 7;
|
const spriteSheetPickerTabH = 7;
|
||||||
|
|
||||||
const spriteSheetPageSwapX = 121;
|
const spriteSheetPageSwapX = 121;
|
||||||
const spriteSheetPageSwapY = 80;
|
const spriteSheetPageSwapY = 81;
|
||||||
const spriteSheetPageSwapW = 7;
|
const spriteSheetPageSwapW = 7;
|
||||||
const spriteSheetPageSwapH = 7;
|
const spriteSheetPageSwapH = 7;
|
||||||
|
|
||||||
const update = () => {
|
const update = () => {
|
||||||
if (mouseHeld()) {
|
if (mouseHeld()) {
|
||||||
const {x: mouseX, y: mouseY} = mousePos();
|
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 - 2);
|
||||||
const inPatch = inRect(mouseX, mouseY, patchX, patchY, patchW*spriteW, patchH*spriteH);
|
|
||||||
const inSpriteSheetPicker = inRect(mouseX, mouseY, spriteSheetPickerX, spriteSheetPickerY, spriteSheetPickerW*spriteSheetPickerTabW, spriteSheetPickerH*spriteSheetPickerTabH);
|
const inSpriteSheetPicker = inRect(mouseX, mouseY, spriteSheetPickerX, spriteSheetPickerY, spriteSheetPickerW*spriteSheetPickerTabW, spriteSheetPickerH*spriteSheetPickerTabH);
|
||||||
const inSpriteSheet = inRect(mouseX, mouseY, spriteSheetX, spriteSheetY, spriteSheetW*spriteW, spriteSheetH*spriteH);
|
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) {
|
if (inPatch) {
|
||||||
const {x, y} = reGrid(mouseX, mouseY, patchX, patchY, spriteW, spriteH);
|
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);
|
state.setInPatch(cellNumber, state.selectedSpriteSheet, state.selectedSprite);
|
||||||
}
|
}
|
||||||
if (inSpriteSheetPicker) {
|
if (inSpriteSheetPicker) {
|
||||||
@ -112,6 +95,18 @@ const update = () => {
|
|||||||
state.spriteSheetPage = (1+state.spriteSheetPage)%2;
|
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) => {
|
const outlineRect = (x: number, y: number, w: number, h: number, color: number) => {
|
||||||
@ -126,32 +121,30 @@ const draw = () => {
|
|||||||
selectedSpriteSheet,
|
selectedSpriteSheet,
|
||||||
spriteWithinPage,
|
spriteWithinPage,
|
||||||
spriteSheetPage,
|
spriteSheetPage,
|
||||||
selectedPatch
|
|
||||||
} = state;
|
} = state;
|
||||||
clearScreen();
|
clearScreen();
|
||||||
fillRect(0, 8, 128, 112, COLOR.DARKGRAY);
|
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
|
// Draw the current patch
|
||||||
fillRect(patchX-1, patchY-1, (patchW*spriteW)+2, (patchH*spriteH)+2, COLOR.BLACK);
|
drawVoidRect(patchX-1, patchY-1, (patchW*spriteW)+2, (patchH*spriteH)+2);
|
||||||
state.patch.values.forEach(([sprsheet, sprite], i) => {
|
state.patch.values.forEach((val, i) => {
|
||||||
const spriteX = patchX+spriteW*(i%patchW);
|
const spriteX = patchX+spriteW*(i%patchW);
|
||||||
const spriteY = patchY+spriteH*Math.floor(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") {
|
if (getSheet(sprsheet).sheet_type === "spritesheet") {
|
||||||
useSpritesheet(sprsheet);
|
useSpritesheet(sprsheet);
|
||||||
drawSprite(spriteX, spriteY, sprite);
|
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
|
// Draw the spritesheet picker
|
||||||
fillRect(spriteSheetPickerX, spriteSheetPickerY, spriteSheetPickerTabW*spriteSheetPickerW, spriteSheetPickerTabW, COLOR.BLACK);
|
fillRect(spriteSheetPickerX, spriteSheetPickerY, spriteSheetPickerTabW*spriteSheetPickerW, spriteSheetPickerTabW, COLOR.BLACK);
|
||||||
Array(spriteSheetPickerW*spriteSheetPickerH).fill(0).forEach((_, i) => {
|
Array(spriteSheetPickerW*spriteSheetPickerH).fill(0).forEach((_, i) => {
|
||||||
@ -180,7 +173,7 @@ const draw = () => {
|
|||||||
drawText(spriteSheetPageSwapX+2, spriteSheetPageSwapY+1, state.spriteSheetPage.toString());
|
drawText(spriteSheetPageSwapX+2, spriteSheetPageSwapY+1, state.spriteSheetPage.toString());
|
||||||
|
|
||||||
// Draw the spritesheet
|
// 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") {
|
if (getSheet(selectedSpriteSheet).sheet_type === "spritesheet") {
|
||||||
useSpritesheet(selectedSpriteSheet);
|
useSpritesheet(selectedSpriteSheet);
|
||||||
Array(64).fill(0).forEach((_, i) => {
|
Array(64).fill(0).forEach((_, i) => {
|
||||||
|
23
util.ts
23
util.ts
@ -46,10 +46,27 @@ export const drawTransparentRect = (x: number, y: number, w: number, h: number)
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const subgrid = <T>(array: Array<T>, gridW: number, x: number, y: number, w: number, h: number): Array<T> => {
|
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 = <T>(array: Array<T>, gridW: number, x: number, y: number, w: number, h: number): Array<T|undefined> => {
|
||||||
return Array(h).fill(0).flatMap((_, i) => {
|
return Array(h).fill(0).flatMap((_, i) => {
|
||||||
const start = (y+i)*gridW+x;
|
if (y+i < 0 || y+i > array.length/gridW) {
|
||||||
return array.slice(start, start+w);
|
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];
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user