Make map editor more like pico 8
This commit is contained in:
		
							
								
								
									
										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]; | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 dylan
					dylan