diff --git a/public/blocks/air.png b/public/blocks/air.png new file mode 100644 index 0000000..3c62bee Binary files /dev/null and b/public/blocks/air.png differ diff --git a/src/components/canvas/Blocks.tsx b/src/components/canvas/Blocks.tsx index 50ccad9..fff199f 100644 --- a/src/components/canvas/Blocks.tsx +++ b/src/components/canvas/Blocks.tsx @@ -85,6 +85,7 @@ function Blocks({ blocks, setBlocks, missingTexture, textures, solidTextures, im for (let i = 0; i < imageData.data.length; i += 4) { const block = findBlockFromRgb(blockData, imageData.data[i], imageData.data[i + 1], imageData.data[i + 2], imageData.data[i + 3]); + if (block == "air") continue; const x = Math.floor((i / 4) % imageData.width); const y = Math.floor(i / 4 / imageData.width); diff --git a/src/components/canvas/Canvas.tsx b/src/components/canvas/Canvas.tsx index 278ca74..0bd8331 100644 --- a/src/components/canvas/Canvas.tsx +++ b/src/components/canvas/Canvas.tsx @@ -109,8 +109,29 @@ function Canvas() { return radiusBlocks; }; + const eraseTool = () => { + // Fixes Infinity and NaN errors + if (blocks.length == 1) return; + + const halfSize = Math.floor(radius / 2); + const startX = mouseCoords.x - (radius % 2 === 0 ? 0 : halfSize); + const startY = mouseCoords.y - (radius % 2 === 0 ? 0 : halfSize); + + const updated = blocks.filter((block) => { + const withinSquare = block.x >= startX && block.x < startX + radius && block.y >= startY && block.y < startY + radius; + return !withinSquare; + }); + + setBlocks(updated); + }; + switch (tool) { case "pencil": { + if (selectedBlock == "air") { + eraseTool(); + break; + } + const newBlocks = getBlocksWithinRadius(mouseCoords.x, mouseCoords.y, radius, selectedBlock); const mergedBlocks = blocks.filter((block) => { return !newBlocks.some((newBlock) => block.x === newBlock.x && block.y === newBlock.y); @@ -120,19 +141,7 @@ function Canvas() { break; } case "eraser": { - // Fixes Infinity and NaN errors - if (blocks.length == 1) break; - - const halfSize = Math.floor(radius / 2); - const startX = mouseCoords.x - (radius % 2 === 0 ? 0 : halfSize); - const startY = mouseCoords.y - (radius % 2 === 0 ? 0 : halfSize); - - const updated = blocks.filter((block) => { - const withinSquare = block.x >= startX && block.x < startX + radius && block.y >= startY && block.y < startY + radius; - return !withinSquare; - }); - - setBlocks(updated); + eraseTool(); break; } } diff --git a/src/components/tool-settings/Replace.tsx b/src/components/tool-settings/Replace.tsx index 5a534cb..957c00b 100644 --- a/src/components/tool-settings/Replace.tsx +++ b/src/components/tool-settings/Replace.tsx @@ -25,7 +25,12 @@ function Replace() { }; const onClickReplace = () => { - setBlocks((prevBlocks) => prevBlocks.map((block) => (block.name === block1 ? { ...block, name: block2 } : block))); + // If block2 name is air, delete the block instead. + setBlocks((prevBlocks) => + prevBlocks + .map((block) => (block.name === block1 ? (block2 === "air" ? null : { ...block, name: block2 }) : block)) + .filter((block) => block !== null) + ); }; useEffect(() => { diff --git a/src/context/Textures.tsx b/src/context/Textures.tsx index 03a7846..fd17a17 100644 --- a/src/context/Textures.tsx +++ b/src/context/Textures.tsx @@ -28,19 +28,22 @@ export const TexturesProvider = ({ children }: Props) => { useEffect(() => { // Load missing texture - const baseTexture = new PIXI.BaseTexture( + const missingBaseTexture = new PIXI.BaseTexture( "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAGUlEQVR42mPABX4w/MCKaKJhVMPgcOuoBgDZRfgBVl5QdQAAAABJRU5ErkJggg==" ); - setMissingTexture(new PIXI.Texture(baseTexture)); + setMissingTexture(new PIXI.Texture(missingBaseTexture)); // Load textures const sheet = new PIXI.Spritesheet(PIXI.BaseTexture.from("/blocks/spritesheet.png"), spritesheet); sheet.parse().then((t) => { - setTextures(t); + // Add air texture + const airBaseTexture = new PIXI.BaseTexture("/blocks/air.png"); + + setTextures({ ...t, "air.png": new PIXI.Texture(airBaseTexture) }); }); // Load solid textures - const solidT: Record = {}; + const solidTexturesCollection: Record = {}; const canvas = document.createElement("canvas"); canvas.width = 16; @@ -58,10 +61,10 @@ export const TexturesProvider = ({ children }: Props) => { const baseTexture = new PIXI.BaseTexture(image); const texture = new PIXI.Texture(baseTexture); - solidT[blockName] = texture; + solidTexturesCollection[blockName] = texture; }); - setSolidTextures(solidT); + setSolidTextures(solidTexturesCollection); setLoading(false); }, []); diff --git a/src/data/blocks/data.json b/src/data/blocks/data.json index c427c0b..f9aa95e 100644 --- a/src/data/blocks/data.json +++ b/src/data/blocks/data.json @@ -1,4 +1,10 @@ { + "air": { + "name": "Air", + "version": 1000, + "id": ["air", 0], + "color": [0, 0, 0, 0] + }, "acacia_log": { "name": "Acacia Log", "version": 1072,